c++ - 是否可以在带有自定义规则的 bazel 中使用 C++20 模块?

标签 c++ bazel c++20 c++-modules

Bazel 不直接支持模块(参见 Issue #4005)。
但是,可以为 bazel 提供自定义 CROSSTOOL。
来自 https://docs.bazel.build/versions/0.22.0/crosstool-reference.html :

By default, Bazel automatically configures CROSSTOOL for your build, but you have the option to configure it manually.


并且可以使用自定义规则扩展 bazel。
来自 https://docs.bazel.build/versions/master/skylark/rules.html :

A few rules are built into Bazel itself. These native rules, such as cc_library and java_binary, provide some core support for certain languages. By defining your own rules, you can add similar support for languages and tools that Bazel does not support natively.


还有这个comment关于 Bazel 的模块问题,建议即使没有 native 支持,您也可以使用自定义 CROSSTOOL 来支持模块:

everything regarding modules (only for clang) is open sourced already. The only missing piece is a CROSSTOOL that makes use of them and provides all necessary features.


谁能展示如何为 clang 编写自定义 CROSSTOOL 以及如何使用它为模块编写自定义 C++ 规则(例如 cc_module ),以便您可以执行以下操作:
编写一个基本模块
// helloworld.cc
module;
#include <stdio.h>

export module helloworld;
export void hello();

module :private;
void hello() { puts("Hello world!"); }
使用模块
// main.cc
import helloworld;
int main() { hello(); }
将部件集成到构建系统中
cc_module(
   name = "helloworld",
   srcs = ["helloworld.cc"],
) # Compiles to a precomiled module file (PCM)

cc_binary(
  name = "main",
  srcs = [
    "main.cc",
  ],
  deps = [
     ":helloworld",
   ],
) # Compiles against the helloworld PCM

最佳答案

是的。以下是如何做到这一点的概述。
添加用于跟踪模块信息的自定义提供程序:

ModuleCompileInfo = provider(doc = "", fields = [
    "module_name", 
    "module_file",
    "module_dependencies",
])
添加自定义规则 cc_module用于生成 C++20 模块。然后你可以写类似
cc_module(
   name = "A",
   src = "a.cc", # a.cc exports the module A
   impl_srcs = [
     "a_impl1.cc", # optionally you can provide additional implementation sources for A
     "a_impl2.cc",
   ],
   deps = [
     ":B", # dependencies can be either other modules or other cc_libraries
     ":C",
   ],
)
自定义规则将
  • 为 A
  • 的模块依赖关系创建模块映射
  • 为 A 的模块生成一个静态库包装 A 的对象和一个 cmi 文件
  • 返回两个 CcInfo A 的提供程序和 ModuleCompileInfo 提供程序来跟踪模块信息。

  • 由于其他标准 bazel 规则(例如 cc_binary、cc_library)不了解 c++20 模块,因此您还需要提供自定义 cc_module_binary 和 cc_module_library 规则,以便您可以将模块与其他 C++ 结构一起使用。例如,
    cc_module_binary(
       name = "exe",
       srcs = ["main.cc"],  # main.cc can import A
       deps = [":A"],       # we can depend on modules
    )
    
    https://github.com/rnburn/rules_cc_module对于提供 c++20 模块规则的项目。见here有关如何使用它的示例。

    关于c++ - 是否可以在带有自定义规则的 bazel 中使用 C++20 模块?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64406726/

    相关文章:

    pytest - 如何将 pytest 迁移到 bazel py_test?

    c++ - decltype(fun()) 用于 consteval 方法

    c++ - 基于空终止字符串的for循环范围

    c++ - 相同大小的小对象的非常快速的对象分配器

    bazel - 如何使用 Stardoc 生成多个文件的文档?

    c++ - 是否可以在 Visual Studio 中使用 Bazel 构建代码?

    c++ - 无法在带有 Clang 的模块中使用对齐的 `operator new`

    c++ - 如何将概念应用于成员变量

    c++ - 导致程序返回奇怪符号的未知错误

    c++ - 重新哈希时锁定 HashMap