C / C++ 规则

报告问题 查看源代码

规则

cc_binary

查看规则来源
cc_binary(name, deps, srcs, data, additional_linker_inputs, args, compatible_with, copts, defines, deprecation, distribs, env, exec_compatible_with, exec_properties, features, includes, licenses, linkopts, linkshared, linkstatic, local_defines, malloc, nocopts, output_licenses, restricted_to, stamp, tags, target_compatible_with, testonly, toolchains, visibility, win_def_file)

隐式输出目标

  • name.stripped(只有在明确请求时才会构建):二进制文件的剥离版本。在二进制文件上运行 strip -g 以移除调试符号。您还可以在命令行中使用 --stripopt=-foo 提供其他剥离选项。只有在明确请求时才会构建此输出。
  • name.dwp(只有在明确请求时才会构建):如果启用了 Fission,则此调试信息软件包文件适用于调试远程部署的二进制文件。否则:为空文件。

参数

属性
name

Name; required

此目标的唯一名称。

deps

List of labels; optional

要链接到二进制目标的其他库的列表。

可以是 cc_libraryobjc_library

srcs

List of labels; optional

为创建目标而处理的 C 和 C++ 文件列表。这些是 C/C++ 源代码和头文件,可能是非生成的(常规源代码)文件,也可能是生成的文件。

所有 .cc.c.cpp 文件将被编译。这些可能是生成的文件:如果已命名文件位于某个其他规则的 outs 中,此规则将自动依赖于另一个规则。

.h 文件不会被编译,但可供此规则来源的源代码包含。.cc.h 文件都可以直接包含这些 srcsdeps 参数中列出的任何规则的 hdrs 中列出的标头。

所有 #included 文件都必须在此规则的 srcs 属性或引用的 cc_library()hdrs 属性中提及。推荐的样式是在库的 hdrs 属性中列出与库关联的标头,以及在 srcs 中列出与此规则的来源关联的所有其余标头。如需了解详情,请参阅“标头包含性检查”

如果规则的名称位于 srcs 中,则此规则会自动依赖于此规则。如果命名规则的 outs 是 C 或 C++ 源代码文件,则它们会被编译到此规则中;如果它们是库文件,则会链接到这些文件。

允许的 srcs 文件类型:

  • C 和 C++ 源文件:.c.cc.cpp.cxx.c++.C
  • C 和 C++ 头文件:.h.hh.hpp.hxx.inc.inl.H
  • 包含 C 预处理器的汇编器:.S
  • 归档文件:.a.pic.a
  • “Always link”库:.lo.pic.lo
  • 共享库(已进行版本控制或未进行版本控制):.so.so.version
  • 对象文件:.o.pic.o

...以及生成这些文件的所有规则。 根据 gcc 惯例,不同的扩展表示不同的编程语言。

additional_linker_inputs

List of labels; optional

将这些文件传递给 C++ 链接器命令。

例如,您可以在此处提供已编译的 Windows .res 文件,以嵌入到二进制目标中。

copts

List of strings; optional

将这些选项添加到 C++ 编译命令中。 受 "Make variable" 替换和 Bourne shell 令牌化约束。

此属性中的每个字符串都按指定顺序添加到 COPTS 中,然后再编译二进制目标。这些标志仅适用于编译此目标,而不编译其依赖项,因此请谨慎在其他地方添加头文件。所有路径都应相对于工作区,而不是当前软件包。

如果软件包声明功能 no_copts_tokenization,Bourne shell 词元化仅适用于单个“Make”变量的字符串。

defines

List of strings; optional

要添加到编译行中的定义列表。 符合“Make”变量替换和 Bourne shell 令牌化的条件。每个字符串(必须由单个 Bourne shell 令牌组成)前面都会附加 -D 并添加到编译命令行中与此目标以及与其相关的每个规则。请务必小心,因为这可能会造成深远的影响。如有疑问,请改为将定义值添加到 local_defines 中。
includes

List of strings; optional

要添加到编译行的包含目录目录列表。

符合使变量替代项。每个字符串会带有 -isystem 前缀并添加到 COPTS 中。与 COPTS 不同,此规则和依赖于此规则的每个规则都会添加这些标志。(注意:这里所说的规则不取决于它所依赖的规则!)请务必小心,因为这可能会造成深远的影响。如有疑问,请改为将“-I”标记添加到 COPTS 中。

必须将头文件添加到 src 或 hdr 中,否则在编译过程进行了沙盒化处理(默认设置)时,它们将不适用于依赖规则。

linkopts

List of strings; optional

将这些标记添加到 C++ 链接器命令中。 可使用“Make”变量替换、 Bourne shell 令牌化标签扩展。系统会将该属性中的每个字符串添加到 LINKOPTS,然后再关联二进制目标。

此列表中的每个不以 $- 开头的元素都被视为 deps 中的目标标签。该目标生成的文件列表会附加到链接器选项中。如果标签无效,或者 deps 中未声明标签,系统会报告错误。

linkshared

Boolean; optional; nonconfigurable; default is False

创建共享库。 如需启用此属性,请在规则中添加 linkshared=True。默认情况下,此选项处于关闭状态。

该标记的存在意味着通过 -shared 标记与 gcc 建立关联,而生成的共享库则适合加载到 Java 程序等示例中。不过,出于构建目的,我们绝不会将依赖项链接到依赖二进制文件,因为系统会假定使用 cc_binary 规则构建的共享库仅由其他程序手动加载,因此不应视为 cc_library 规则的替代方案。为了提高可伸缩性,我们建议完全避免此方法,而只是让 java_library 改为依赖 cc_library 规则。

如果您同时指定 linkopts=['-static']linkshared=True,则会获得一个完全独立的单元。如果您同时指定 linkstatic=Truelinkshared=True,会获得一个基本上独立的单元。

linkstatic

Boolean; optional; default is True

对于 cc_binarycc_test:在静态模式下关联二进制文件。对于 cc_library.linkstatic:请参阅下文。

默认情况下,此选项会为 cc_binary 开启,为其余应用关闭。

如果启用此选项,并且是二进制文件或测试,此选项会尽可能指示构建工具链接到用户库的 .a 而非 .so。 某些系统库可能仍会动态关联,就像没有静态库的库一样。因此,生成的可执行文件仍然是动态链接的,因此大部分是静态的。

您可以通过三种不同的方式链接可执行文件:

  • 具有 full_static_link 功能的 STATIC,其中所有内容都以静态方式链接;例如“gcc -static foo.o libbar.a libbaz.a -lm”。
    此模式通过在 features 属性中指定 fully_static_link 启用。
  • STATIC,其中所有用户库静态关联(如果有静态版本),但系统库(不包括 C/C++ 运行时库)以动态方式链接,例如“gcc foo.o libfoo.a libbaz.a -lm”。
    通过指定 linkstatic=True 启用此模式。
  • 动态,其中所有库都是动态链接的(如果有动态版本),例如“gcc foo.o libfoo.so libbaz.so -lm”。
    通过指定 linkstatic=False 可启用此模式。

如果对 cc_library() 规则使用 linkstatic 属性,则其含义有所不同。对于 C++ 库,linkstatic=True 表示只允许静态链接,因此不会生成任何 .so。linkstatic=False 不会阻止创建静态库。此属性用于控制动态库的创建。

如果为 linkstatic=False,构建工具会在 *.runfiles 区域中创建指向依赖共享库的符号链接。

local_defines

List of strings; optional

要添加到编译行中的定义列表。 符合“Make”变量替换和 Bourne shell 令牌化的条件。每个字符串都必须包含一个 Bourne shell 令牌,在前面加上 -D 并添加到此目标的编译命令行中,而不是添加到其依赖项中。
malloc

Label; optional; default is @bazel_tools//tools/cpp:malloc

替换 malloc 的默认依赖项。

默认情况下,C++ 二进制文件会关联到 //tools/cpp:malloc,这是一个空库,因此二进制文件最终会使用 libc malloc。 此标签必须引用 cc_library。如果编译针对的是非 C++ 规则,则此选项无效。如果指定了 linkshared=True,则此属性的值会被忽略。

nocopts

String; optional

从 C++ 编译命令中移除匹配选项。 符合“Make”变量替换条件。此属性的值会被解释为正则表达式。为了编译此规则,与正则表达式匹配的任何现有 COPTS(包括规则的 copts 属性中明确指定的值)都将从 COPTS 中移除。 您应该很少需要此属性。
stamp

Integer; optional; default is -1

是否将 build 信息编码到二进制文件中。可能的值包括:
  • stamp = 1:请务必将 build 信息印入二进制文件,即使在 --nostamp build 中也是如此。应避免此设置,因为它可能会终止二进制文件和任何依赖于它的下游操作的远程缓存。
  • stamp = 0:始终使用常量值替换 build 信息。这样可以很好地构建构建结果缓存。
  • stamp = -1:build 信息的嵌入由 --[no]stamp 标志控制。

已签名的二进制文件不会重新构建,除非其依赖项发生变化。

win_def_file

Label; optional

要传递给链接器的 Windows DEF 文件。

仅当 Windows 是目标平台时,才应使用此属性。该文件可用于在关联共享库期间 导出符号

cc_import

查看规则来源
cc_import(name, deps, data, hdrs, alwayslink, compatible_with, deprecation, distribs, features, interface_library, licenses, restricted_to, shared_library, static_library, system_provided, tags, target_compatible_with, testonly, visibility)

cc_import 规则允许用户导入预编译的 C/C++ 库。

下面是典型的用例:
1. 关联静态库

cc_import(
  name = "mylib",
  hdrs = ["mylib.h"],
  static_library = "libmylib.a",
  # If alwayslink is turned on,
  # libmylib.a will be forcely linked into any binary that depends on it.
  # alwayslink = 1,
)
2. 关联共享库 (Unix)
cc_import(
  name = "mylib",
  hdrs = ["mylib.h"],
  shared_library = "libmylib.so",
)
3. 将共享库与接口库 (Windows) 关联
cc_import(
  name = "mylib",
  hdrs = ["mylib.h"],
  # mylib.lib is an import library for mylib.dll which will be passed to linker
  interface_library = "mylib.lib",
  # mylib.dll will be available for runtime
  shared_library = "mylib.dll",
)
4. 将共享库与 system_provided=True (Windows) 关联
cc_import(
  name = "mylib",
  hdrs = ["mylib.h"],
  # mylib.lib is an import library for mylib.dll which will be passed to linker
  interface_library = "mylib.lib",
  # mylib.dll is provided by system environment, for example it can be found in PATH.
  # This indicates that Bazel is not responsible for making mylib.dll available.
  system_provided = 1,
)
5. 链接到静态或共享库
在 Unix 上:
cc_import(
  name = "mylib",
  hdrs = ["mylib.h"],
  static_library = "libmylib.a",
  shared_library = "libmylib.so",
)

# first will link to libmylib.a
cc_binary(
  name = "first",
  srcs = ["first.cc"],
  deps = [":mylib"],
  linkstatic = 1, # default value
)

# second will link to libmylib.so
cc_binary(
  name = "second",
  srcs = ["second.cc"],
  deps = [":mylib"],
  linkstatic = 0,
)
在 Windows 上:
cc_import(
  name = "mylib",
  hdrs = ["mylib.h"],
  static_library = "libmylib.lib", # A normal static library
  interface_library = "mylib.lib", # An import library for mylib.dll
  shared_library = "mylib.dll",
)

# first will link to libmylib.lib
cc_binary(
  name = "first",
  srcs = ["first.cc"],
  deps = [":mylib"],
  linkstatic = 1, # default value
)

# second will link to mylib.dll through mylib.lib
cc_binary(
  name = "second",
  srcs = ["second.cc"],
  deps = [":mylib"],
  linkstatic = 0,
)
cc_import 支持 include 属性。例如:
  cc_import(
  name = "curl_lib",
  hdrs = glob(["vendor/curl/include/curl/*.h"]),
  includes = [ "vendor/curl/include" ],
  shared_library = "vendor/curl/lib/.libs/libcurl.dylib",
)

参数

属性
name

Name; required

此目标的唯一名称。

deps

List of labels; optional

目标所依赖的其他库的列表。请参阅有关大多数 build 规则定义的典型特性的关于 deps 的一般注释。
hdrs

List of labels; optional

此预编译库发布的将由源文件直接添加到相关规则中的头文件列表。

Boolean; optional; default is False

如果为 1,则依赖(直接或间接)此 C++ 预编译库的所有二进制文件都将链接到静态库中归档的所有对象文件,即使其中部分文件不包含二进制文件引用的符号也是如此。如果您的代码未在二进制文件中明确调用(例如,您的代码注册接收某些服务提供的回调),这会非常有用。

如果 Windows 上始终无法使用 VS 2017,这是由于已知问题所致,请将 VS 2017 升级到最新版本。

interface_library

Label; optional

用于关联共享库的单个接口库。

允许的文件类型:.ifso.tbd.lib.so.dylib

shared_library

Label; optional

单个预编译的共享库。Bazel 会确保其在运行时可供依赖于它的二进制文件使用。

允许的文件类型:.so.dll.dylib

static_library

Label; optional

单个预编译的静态库。

允许的文件类型:.a.pic.a.lib

system_provided

Boolean; optional; default is False

如果为 1,则表示系统提供运行时所需的共享库。在这种情况下,应该指定 interface_library,并且 shared_library 应该为空。

cc_library

查看规则来源
cc_library(name, deps, srcs, data, hdrs, alwayslink, compatible_with, copts, defines, deprecation, distribs, exec_compatible_with, exec_properties, features, implementation_deps, include_prefix, includes, licenses, linkopts, linkstamp, linkstatic, local_defines, nocopts, restricted_to, strip_include_prefix, tags, target_compatible_with, testonly, textual_hdrs, toolchains, visibility, win_def_file)

标头是否包含检查

必须在 cc_* 规则的 hdrssrcs 中声明 build 中使用的所有头文件。这是强制要求。

对于 cc_library 规则,hdrs 中的标头包含库的公共接口,可以直接包含在库本身的 hdrssrcs 中的文件,以及 cc_* 中列出了相应库的 cc_*hdrssrcs 文件中的文件。 depssrcs 中的头文件必须仅直接从库本身的 hdrssrcs 文件中添加。在决定是否将头文件放入 hdrssrcs 时,应询问您希望此库的使用者是否能够直接纳入该头文件。此决定与编程语言中 publicprivate 可见性之间的大致相同。

cc_binarycc_test 规则没有导出的接口,因此也没有 hdrs 属性。直接属于二进制文件或测试的所有头文件都应列在 srcs 中。

为了说明这些规则,请查看以下示例。

cc_binary(
    name = "foo",
    srcs = [
        "foo.cc",
        "foo.h",
    ],
    deps = [":bar"],
)

cc_library(
    name = "bar",
    srcs = [
        "bar.cc",
        "bar-impl.h",
    ],
    hdrs = ["bar.h"],
    deps = [":baz"],
)

cc_library(
    name = "baz",
    srcs = [
        "baz.cc",
        "baz-impl.h",
    ],
    hdrs = ["baz.h"],
)

下表列出了此示例中可以直接包含的条目。例如,foo.cc 可以直接包含 foo.hbar.h,但不能包含 baz.h

包含的文件允许的包含项
foo.hbar.h
foo.ccfoo.h bar.h
bar.hbar-impl.h baz.h
bar-impl.hbar.h baz.h
bar.ccbar.h bar-impl.h baz.h
巴西baz-impl.h
baz-impl.h巴西
baz.ccbaz.h baz-impl.h

包含项检查规则仅适用于直接包含项。在上面的示例中,foo.cc 可以包含 bar.h,其中可能包括 baz.h,而后者可以包含 baz-impl.h。从技术上讲,对 .cc 文件的编译可以在传递 deps 闭包的任何 cc_library 中以传递方式包含 hdrssrcs 中的任何头文件。在这种情况下,编译器可能会在编译 foo.cc 时读取 baz.hbaz-impl.h,但 foo.cc 不得包含 #include "baz.h"。为此,必须将 baz 添加到 foodeps

Bazel 依靠工具链支持来实施包含项检查规则。工具链必须支持 layering_check 功能,并且需要显式请求,例如通过 --features=layering_check 命令行标志或 package 函数的 features 参数请求。Bazel 提供的工具链仅支持在 Unix 和 macOS 上使用 Clang 的此功能。

参数

属性
name

Name; required

此目标的唯一名称。

deps

List of labels; optional

要链接到二进制目标的其他库的列表。

可以是 cc_libraryobjc_library

srcs

List of labels; optional

为创建目标而处理的 C 和 C++ 文件列表。这些是 C/C++ 源代码和头文件,可能是非生成的(常规源代码)文件,也可能是生成的文件。

所有 .cc.c.cpp 文件将被编译。这些可能是生成的文件:如果已命名文件位于某个其他规则的 outs 中,此规则将自动依赖于另一个规则。

.h 文件不会被编译,但可供此规则来源的源代码包含。.cc.h 文件都可以直接包含这些 srcsdeps 参数中列出的任何规则的 hdrs 中列出的标头。

所有 #included 文件都必须在此规则的 srcs 属性或引用的 cc_library()hdrs 属性中提及。推荐的样式是在库的 hdrs 属性中列出与库关联的标头,以及在 srcs 中列出与此规则的来源关联的所有其余标头。如需了解详情,请参阅“标头包含性检查”

如果规则的名称位于 srcs 中,则此规则会自动依赖于此规则。如果命名规则的 outs 是 C 或 C++ 源代码文件,则它们会被编译到此规则中;如果它们是库文件,则会链接到这些文件。

允许的 srcs 文件类型:

  • C 和 C++ 源文件:.c.cc.cpp.cxx.c++.C
  • C 和 C++ 头文件:.h.hh.hpp.hxx.inc.inl.H
  • 包含 C 预处理器的汇编器:.S
  • 归档文件:.a.pic.a
  • “Always link”库:.lo.pic.lo
  • 共享库(已进行版本控制或未进行版本控制):.so.so.version
  • 对象文件:.o.pic.o

...以及生成这些文件的所有规则。 根据 gcc 惯例,不同的扩展表示不同的编程语言。

hdrs

List of labels; optional

此库发布的头文件列表,将由来源直接添加到相关规则中。

这是声明头文件来描述库接口的首选位置。这些标头将可供此规则的来源或依赖规则使用。 不应由该库的客户端包含的标头应列在 srcs 属性中,即使它们包含在已发布的头文件中也是如此。如需了解详情,请参阅“标头包含性检查”

Boolean; optional; default is False

如果为 1,则依赖(直接或间接)此 C++ 库的所有二进制文件都将链接在 srcs 中列出的文件的所有对象文件中,即使该文件中不包含任何由二进制文件引用的符号也是如此。如果您的代码未在二进制文件中明确调用(例如,您的代码注册接收某些服务提供的回调),这会非常有用。

如果 Windows 上始终无法使用 VS 2017,这是由于已知问题所致,请将 VS 2017 升级到最新版本。

copts

List of strings; optional

将这些选项添加到 C++ 编译命令中。 受 "Make variable" 替换和 Bourne shell 令牌化约束。

此属性中的每个字符串都按指定顺序添加到 COPTS 中,然后再编译二进制目标。这些标志仅适用于编译此目标,而不编译其依赖项,因此请谨慎在其他地方添加头文件。所有路径都应相对于工作区,而不是当前软件包。

如果软件包声明功能 no_copts_tokenization,Bourne shell 词元化仅适用于单个“Make”变量的字符串。

defines

List of strings; optional

要添加到编译行中的定义列表。 符合“Make”变量替换和 Bourne shell 令牌化的条件。每个字符串(必须由单个 Bourne shell 令牌组成)前面都会附加 -D 并添加到编译命令行中与此目标以及与其相关的每个规则。请务必小心,因为这可能会造成深远的影响。如有疑问,请改为将定义值添加到 local_defines 中。
implementation_deps

List of labels; optional

库目标所依赖的其他库的列表。与 deps 不同的是,这些库的头文件和包含路径(及其所有传递依赖项)仅用于库的编译,而不用于依赖于它的库。使用 implementation_deps 指定的库仍会在依赖于此库的二进制目标中关联。

目前仅限 cc_libraries 使用,并受 --experimental_cc_implementation_deps 标志保护。

include_prefix

String; optional

要添加到此规则的标头路径的前缀。

设置后,在此规则的 hdrs 属性中的头文件可供访问的是附加到其相对代码库路径的此属性的值。

在添加此前缀之前,strip_include_prefix 属性中的前缀会被移除。

includes

List of strings; optional

要添加到编译行的包含目录目录列表。

符合使变量替代项。每个字符串会带有 -isystem 前缀并添加到 COPTS 中。与 COPTS 不同,此规则和依赖于此规则的每个规则都会添加这些标志。(注意:这里所说的规则不取决于它所依赖的规则!)请务必小心,因为这可能会造成深远的影响。如有疑问,请改为将“-I”标记添加到 COPTS 中。

必须将头文件添加到 src 或 hdr 中,否则在编译过程进行了沙盒化处理(默认设置)时,它们将不适用于依赖规则。

linkopts

List of strings; optional

将这些标记添加到 C++ 链接器命令中。 可使用“Make”变量替换、 Bourne shell 令牌化标签扩展。系统会将该属性中的每个字符串添加到 LINKOPTS,然后再关联二进制目标。

此列表中的每个不以 $- 开头的元素都被视为 deps 中的目标标签。该目标生成的文件列表会附加到链接器选项中。如果标签无效,或者 deps 中未声明标签,系统会报告错误。

linkstamp

Label; optional

同时编译指定的 C++ 源文件并将其链接到最终二进制文件。使用此技巧需要将二进制文件信息引入二进制文件;如果我们以常规方式将源文件编译到对象文件中,时间戳将不正确。 链接测试编译不得包含任何一组特定的编译器标志,因此不应依赖于任何特定的头文件、编译器选项或其他 build 变量。此选项仅应在 base 软件包中使用。
linkstatic

Boolean; optional; default is False

对于 cc_binarycc_test:在静态模式下关联二进制文件。对于 cc_library.linkstatic:请参阅下文。

默认情况下,此选项会为 cc_binary 开启,为其余应用关闭。

如果启用此选项,并且是二进制文件或测试,此选项会尽可能指示构建工具链接到用户库的 .a 而非 .so。 某些系统库可能仍会动态关联,就像没有静态库的库一样。因此,生成的可执行文件仍然是动态链接的,因此大部分是静态的。

您可以通过三种不同的方式链接可执行文件:

  • 具有 full_static_link 功能的 STATIC,其中所有内容都以静态方式链接;例如“gcc -static foo.o libbar.a libbaz.a -lm”。
    此模式通过在 features 属性中指定 fully_static_link 启用。
  • STATIC,其中所有用户库静态关联(如果有静态版本),但系统库(不包括 C/C++ 运行时库)以动态方式链接,例如“gcc foo.o libfoo.a libbaz.a -lm”。
    通过指定 linkstatic=True 启用此模式。
  • 动态,其中所有库都是动态链接的(如果有动态版本),例如“gcc foo.o libfoo.so libbaz.so -lm”。
    通过指定 linkstatic=False 可启用此模式。

如果对 cc_library() 规则使用 linkstatic 属性,则其含义有所不同。对于 C++ 库,linkstatic=True 表示只允许静态链接,因此不会生成任何 .so。linkstatic=False 不会阻止创建静态库。此属性用于控制动态库的创建。

如果为 linkstatic=False,构建工具会在 *.runfiles 区域中创建指向依赖共享库的符号链接。

local_defines

List of strings; optional

要添加到编译行中的定义列表。 符合“Make”变量替换和 Bourne shell 令牌化的条件。每个字符串都必须包含一个 Bourne shell 令牌,在前面加上 -D 并添加到此目标的编译命令行中,而不是添加到其依赖项中。
nocopts

String; optional

从 C++ 编译命令中移除匹配选项。 符合“Make”变量替换条件。此属性的值会被解释为正则表达式。为了编译此规则,与正则表达式匹配的任何现有 COPTS(包括规则的 copts 属性中明确指定的值)都将从 COPTS 中移除。 您应该很少需要此属性。
strip_include_prefix

String; optional

用于从此规则的标头路径中移除的前缀。

设置后,此规则的 hdrs 特性中的头文件可在其路径中被截断,且此前缀被截断。

如果是相对路径,则会被视为与软件包相关的路径。如果它是绝对路径,则可以理解为相对代码库路径。

去掉此前缀后,系统会添加 include_prefix 属性中的前缀。

textual_hdrs

List of labels; optional

此库发布的头文件列表,供来源在依赖项规则中以文本方式包含。

此文件用于声明无法自行编译的头文件;也就是说,它们始终需要通过其他源文件以文本形式添加,才能构建有效的代码。

win_def_file

Label; optional

要传递给链接器的 Windows DEF 文件。

仅当 Windows 是目标平台时,才应使用此属性。该文件可用于在关联共享库期间 导出符号

cc_proto_library

查看规则来源
cc_proto_library(name, deps, data, compatible_with, deprecation, distribs, exec_compatible_with, exec_properties, features, licenses, restricted_to, tags, target_compatible_with, testonly, visibility)

cc_proto_library.proto 文件生成 C++ 代码。

deps 必须指向 proto_library 规则。

例如:

cc_library(
    name = "lib",
    deps = [":foo_cc_proto"],
)

cc_proto_library(
    name = "foo_cc_proto",
    deps = [":foo_proto"],
)

proto_library(
    name = "foo_proto",
)

参数

属性
name

Name; required

此目标的唯一名称。

deps

List of labels; optional

要为其生成 C++ 代码的 proto_library 规则列表。

cc_shared_library

查看规则来源
cc_shared_library(name, deps, additional_linker_inputs, dynamic_deps, exports_filter, shared_lib_name, tags, user_link_flags, win_def_file)

它会生成一个共享库。

示例

cc_shared_library(
    name = "foo_shared",
    deps = [
        ":foo",
    ],
    dynamic_deps = [
        ":bar_shared",
    ],
    additional_linker_inputs = [
        ":foo.lds",
    ],
    user_link_flags = [
        "-Wl,--version-script=$(location :foo.lds)",
    ],
)
cc_library(
    name = "foo",
    srcs = ["foo.cc"],
    hdrs = ["foo.h"],
    deps = [
        ":bar",
        ":baz",
    ],
)
cc_shared_library(
    name = "bar_shared",
    shared_lib_name = "bar.so",
    deps = [":bar"],
)
cc_library(
    name = "bar",
    srcs = ["bar.cc"],
    hdrs = ["bar.h"],
)
cc_library(
    name = "baz",
    srcs = ["baz.cc"],
    hdrs = ["baz.h"],
)

在示例中,foo_shared 静态关联了 foobaz,后者是传递依赖项。它不会关联 bar,因为它已由 dynamic_dep bar_shared 动态提供。

foo_shared 使用链接器脚本 *.lds 文件来控制应导出哪些符号。cc_shared_library 规则逻辑不能控制导出哪些符号,只有在两个共享库导出相同的目标的情况下,该分析器才会使用应导出的符号以在分析阶段抛出错误。

系统会假定,导出了 cc_shared_library 的每个直接依赖项。因此,Bazel 会在分析期间假设 foo_shared 将导出 foo。系统假定 foo_shared 不会导出 baz。系统也会假定,与 exports_filter 匹配的每个目标都会导出。

示例中的每个 cc_library 最多只能出现在一个 cc_shared_library 中。如果我们想将 baz 也关联到 bar_shared,则需要将 tags = ["LINKABLE_MORE_THAN_ONCE"] 添加到 baz

由于 shared_lib_name 属性的原因,bar_shared 生成的文件会采用 bar.so 名称,而不是在 Linux 上默认使用的名称 libbar.so

错误数

Two shared libraries in dependencies export the same symbols.

只要您创建具有两个导出相同目标的两个不同的 cc_shared_library 依赖项的目标,就会发生这种情况。如要解决此问题,您需要停止在其中一个 cc_shared_library 依赖项中导出库。

这将会在您创建具有两个静态 cc_shared_library 依赖项的新 cc_shared_library 依赖项(静态关联同一目标)时发生。与导出错误类似。

解决此问题的一种方法是停止将库关联到某个 cc_shared_library 依赖项。同时,仍在链接库的库需要导出库,以便没有链接该库的库可以继续查看这些符号。另一种方法是提取第三个库来导出目标。第三种方式是使用 LINKABLE_MORE_THAN_ONCE 标记罪犯的 cc_library,但这种修复情况应该很少见,您应该绝对确保 cc_library 确实可以多次链接。

'//foo:foo' is already linked statically in '//bar:bar' but not exported`

这意味着,无需传递某个 cc_shared_library 依赖项即可访问 deps 传递闭包中的库,但该库已链接至 dynamic_deps 中的其他 cc_shared_library,并且不会导出。

解决方案是从 cc_shared_library 依赖项中导出它,或者提取第三个用于导出它的 cc_shared_library

Do not place libraries which only contain a precompiled dynamic library in deps.

如果您有预编译的动态库,则无需执行此操作,也不能静态关联到您当前创建的当前 cc_shared_library 目标。因此,它不属于 cc_shared_librarydeps。如果此预编译动态库依赖于您的某个 cc_libraries,则 cc_library 需要直接依赖于它。

Trying to export a library already exported by a different shared library

如果当前规则声明要导出某个动态依赖项已导出的目标,您将看到此错误。

如需修复此问题,请从 deps 中移除目标,并从动态依赖项中获取该目标,或确保 exports_filter 不会捕获此目标。

参数

属性
name

Name; required

此目标的唯一名称。

deps

List of labels; optional

在全面归档后将无条件静态关联到共享库的顶级库。

这些直接依赖项的任何传递库依赖项都将关联到此共享库,前提是它们尚未由 dynamic_deps 中的 cc_shared_library 关联。

在分析过程中,规则实现会将 deps 中列出的任何目标视为共享库正在导出的目标,以便在多个 cc_shared_libraries 导出相同的目标时给出错误。规则实现负责不通知链接器有关共享对象应导出哪些符号。用户应通过链接器脚本或源代码中的可见性声明来解决此问题。

每当同一库静态关联到多个 cc_shared_library 时,实现也会触发错误。为避免出现此情况,您可以将 "LINKABLE_MORE_THAN_ONCE" 添加到 cc_library.tags,或将“cc_library”列为其中一个共享库的导出内容,以便一个可以互相变成 dynamic_dep

additional_linker_inputs

List of labels; optional

您可能需要向链接器传递的任何其他文件,例如链接器脚本。您必须单独传递链接器所需的所有信号,才能获知此文件。您可以通过 user_link_flags 属性完成此操作。
dynamic_deps

List of labels; optional

这些是当前目标所依赖的其他 cc_shared_library 依赖项。

cc_shared_library 实现将使用 dynamic_deps(传递,即当前目标 dynamic_depsdynamic_deps)列表来确定不应传递传递 deps 中的哪个 cc_libraries,因为它们已由不同的 cc_shared_library 提供。

exports_filter

List of strings; optional

此属性包含由当前共享库声明要导出的目标的列表。

共享库已理解为将导出的任何目标 deps。此属性应该用于列出共享库导出的但 deps 的传递依赖项。

请注意,此属性实际上并未向这些目标添加依赖项边缘。依赖项边缘应由 deps 创建。此属性中的条目只是字符串。请注意,将某个属性放入此属性时,系统会将其视为声明,即共享库会从该目标中导出符号。 cc_shared_library 逻辑实际上并不会处理告知链接器应导出哪些符号的操作。

允许使用以下语法:

//foo:__package__ 用于考虑 foo/BUILD 中的任何目标

//foo:__subpackages__,用于考虑 foo/BUILD 或 foo/ 下的任何其他软件包(如 foo/bar/BUILD)中的任何目标

shared_lib_name

String; optional

默认情况下,cc_shared_library 将根据共享库的名称和平台为共享库输出文件命名。这包括扩展名,有时还包括前缀。有时,您可能不希望使用默认名称,例如,在加载 Python 版 C++ 共享库时,通常不需要默认的 lib* 前缀,在这种情况下,您可以使用此属性选择自定义名称。

List of strings; optional

您可能需要传递给链接器的任何其他标志。例如,若要使链接器知道通过 additional_linker_inputs 传递的链接器脚本,您可以使用以下代码:
         cc_shared_library(
            name = "foo_shared",
            additional_linker_inputs = select({
              "//src/conditions:linux": [
                ":foo.lds",
                ":additional_script.txt",
              ],
              "//conditions:default": []}),
            user_link_flags = select({
              "//src/conditions:linux": [
                "-Wl,-rpath,kittens",
                "-Wl,--version-script=$(location :foo.lds)",
                "-Wl,--script=$(location :additional_script.txt)",
              ],
              "//conditions:default": []}),
              ...
         )
        
win_def_file

Label; optional

要传递给链接器的 Windows DEF 文件。

仅当 Windows 是目标平台时,才应使用此属性。该文件可用于在关联共享库期间 导出符号

fdo_prefetch_hints

查看规则来源
fdo_prefetch_hints(name, compatible_with, deprecation, distribs, features, licenses, profile, restricted_to, tags, target_compatible_with, testonly, visibility)

表示位于工作区或指定绝对路径中的 FDO 预提取提示配置文件。示例:

fdo_prefetch_hints(
    name = "hints",
    profile = "//path/to/hints:profile.afdo",
)

fdo_profile(
  name = "hints_abs",
  absolute_path_profile = "/absolute/path/profile.afdo",
)

参数

属性
name

Name; required

此目标的唯一名称。

profile

Label; optional

提示配置文件的标签。hints 文件的扩展名为 .afdo。标签也可以指向 fdo_absolute_path_profile 规则。

fdo_profile

查看规则来源
fdo_profile(name, absolute_path_profile, compatible_with, deprecation, distribs, features, licenses, profile, proto_profile, restricted_to, tags, target_compatible_with, testonly, visibility)

表示工作区或指定绝对路径中的 FDO 配置文件。示例:

fdo_profile(
    name = "fdo",
    profile = "//path/to/fdo:profile.zip",
)

fdo_profile(
  name = "fdo_abs",
  absolute_path_profile = "/absolute/path/profile.zip",
)

参数

属性
name

Name; required

此目标的唯一名称。

absolute_path_profile

String; optional

FDO 配置文件的绝对路径。FDO 文件只能有 .afdo 扩展名。
profile

Label; optional

FDO 配置文件的标签或生成该配置文件的规则。FDO 文件可以具有以下扩展名之一:.proraw(用于未编入索引的 LLVM 配置文件)、.profdata(用于已编入索引的 LLVM 配置文件)、.zip(包含 LLVM Proraw 配置文件)、.afdo(用于 AutoFDO 配置文件)、.xfdo(用于 XBinary 配置文件)。该标签还可以指向 fdo_absolute_path_profile 规则。
proto_profile

Label; optional

protobuf 配置文件的标签。

propeller_optimize

查看规则来源
propeller_optimize(name, compatible_with, deprecation, distribs, features, ld_profile, licenses, restricted_to, tags, target_compatible_with, testonly, visibility)

表示工作区中的推进器优化配置文件。 例如:

propeller_optimize(
    name = "layout",
    cc_profile = "//path:cc_profile.txt",
    ld_profile = "//path:ld_profile.txt"
)

propeller_optimize(
    name = "layout_absolute",
    absolute_cc_profile = "/absolute/cc_profile.txt",
    absolute_ld_profile = "/absolute/ld_profile.txt"
)

参数

属性
name

Name; required

此目标的唯一名称。

ld_profile

Label; optional

传递给关联操作的个人资料的标签。此文件的扩展名为 .txt。

抄送测试

查看规则来源
cc_test(name, deps, srcs, data, additional_linker_inputs, args, compatible_with, copts, defines, deprecation, distribs, env, env_inherit, exec_compatible_with, exec_properties, features, flaky, includes, licenses, linkopts, linkstatic, local, local_defines, malloc, nocopts, restricted_to, shard_count, size, stamp, tags, target_compatible_with, testonly, timeout, toolchains, visibility, win_def_file)

参数

属性
name

Name; required

此目标的唯一名称。

deps

List of labels; optional

要链接到二进制目标的其他库的列表。

可以是 cc_libraryobjc_library

srcs

List of labels; optional

为创建目标而处理的 C 和 C++ 文件列表。这些是 C/C++ 源代码和头文件,可能是非生成的(常规源代码)文件,也可能是生成的文件。

所有 .cc.c.cpp 文件将被编译。这些可能是生成的文件:如果已命名文件位于某个其他规则的 outs 中,此规则将自动依赖于另一个规则。

.h 文件不会被编译,但可供此规则来源的源代码包含。.cc.h 文件都可以直接包含这些 srcsdeps 参数中列出的任何规则的 hdrs 中列出的标头。

所有 #included 文件都必须在此规则的 srcs 属性或引用的 cc_library()hdrs 属性中提及。推荐的样式是在库的 hdrs 属性中列出与库关联的标头,以及在 srcs 中列出与此规则的来源关联的所有其余标头。如需了解详情,请参阅“标头包含性检查”

如果规则的名称位于 srcs 中,则此规则会自动依赖于此规则。如果命名规则的 outs 是 C 或 C++ 源代码文件,则它们会被编译到此规则中;如果它们是库文件,则会链接到这些文件。

允许的 srcs 文件类型:

  • C 和 C++ 源文件:.c.cc.cpp.cxx.c++.C
  • C 和 C++ 头文件:.h.hh.hpp.hxx.inc.inl.H
  • 包含 C 预处理器的汇编器:.S
  • 归档文件:.a.pic.a
  • “Always link”库:.lo.pic.lo
  • 共享库(已进行版本控制或未进行版本控制):.so.so.version
  • 对象文件:.o.pic.o

...以及生成这些文件的所有规则。 根据 gcc 惯例,不同的扩展表示不同的编程语言。

additional_linker_inputs

List of labels; optional

将这些文件传递给 C++ 链接器命令。

例如,您可以在此处提供已编译的 Windows .res 文件,以嵌入到二进制目标中。

copts

List of strings; optional

将这些选项添加到 C++ 编译命令中。 受 "Make variable" 替换和 Bourne shell 令牌化约束。

此属性中的每个字符串都按指定顺序添加到 COPTS 中,然后再编译二进制目标。这些标志仅适用于编译此目标,而不编译其依赖项,因此请谨慎在其他地方添加头文件。所有路径都应相对于工作区,而不是当前软件包。

如果软件包声明功能 no_copts_tokenization,Bourne shell 词元化仅适用于单个“Make”变量的字符串。

defines

List of strings; optional

要添加到编译行中的定义列表。 符合“Make”变量替换和 Bourne shell 令牌化的条件。每个字符串(必须由单个 Bourne shell 令牌组成)前面都会附加 -D 并添加到编译命令行中与此目标以及与其相关的每个规则。请务必小心,因为这可能会造成深远的影响。如有疑问,请改为将定义值添加到 local_defines 中。
includes

List of strings; optional

要添加到编译行的包含目录目录列表。

符合使变量替代项。每个字符串会带有 -isystem 前缀并添加到 COPTS 中。与 COPTS 不同,此规则和依赖于此规则的每个规则都会添加这些标志。(注意:这里所说的规则不取决于它所依赖的规则!)请务必小心,因为这可能会造成深远的影响。如有疑问,请改为将“-I”标记添加到 COPTS 中。

必须将头文件添加到 src 或 hdr 中,否则在编译过程进行了沙盒化处理(默认设置)时,它们将不适用于依赖规则。

linkopts

List of strings; optional

将这些标记添加到 C++ 链接器命令中。 可使用“Make”变量替换、 Bourne shell 令牌化标签扩展。系统会将该属性中的每个字符串添加到 LINKOPTS,然后再关联二进制目标。

此列表中的每个不以 $- 开头的元素都被视为 deps 中的目标标签。该目标生成的文件列表会附加到链接器选项中。如果标签无效,或者 deps 中未声明标签,系统会报告错误。

linkstatic

Boolean; optional; default is False

对于 cc_binarycc_test:在静态模式下关联二进制文件。对于 cc_library.linkstatic:请参阅下文。

默认情况下,此选项会为 cc_binary 开启,为其余应用关闭。

如果启用此选项,并且是二进制文件或测试,此选项会尽可能指示构建工具链接到用户库的 .a 而非 .so。 某些系统库可能仍会动态关联,就像没有静态库的库一样。因此,生成的可执行文件仍然是动态链接的,因此大部分是静态的。

您可以通过三种不同的方式链接可执行文件:

  • 具有 full_static_link 功能的 STATIC,其中所有内容都以静态方式链接;例如“gcc -static foo.o libbar.a libbaz.a -lm”。
    此模式通过在 features 属性中指定 fully_static_link 启用。
  • STATIC,其中所有用户库静态关联(如果有静态版本),但系统库(不包括 C/C++ 运行时库)以动态方式链接,例如“gcc foo.o libfoo.a libbaz.a -lm”。
    通过指定 linkstatic=True 启用此模式。
  • 动态,其中所有库都是动态链接的(如果有动态版本),例如“gcc foo.o libfoo.so libbaz.so -lm”。
    通过指定 linkstatic=False 可启用此模式。

如果对 cc_library() 规则使用 linkstatic 属性,则其含义有所不同。对于 C++ 库,linkstatic=True 表示只允许静态链接,因此不会生成任何 .so。linkstatic=False 不会阻止创建静态库。此属性用于控制动态库的创建。

如果为 linkstatic=False,构建工具会在 *.runfiles 区域中创建指向依赖共享库的符号链接。

local_defines

List of strings; optional

要添加到编译行中的定义列表。 符合“Make”变量替换和 Bourne shell 令牌化的条件。每个字符串都必须包含一个 Bourne shell 令牌,在前面加上 -D 并添加到此目标的编译命令行中,而不是添加到其依赖项中。
malloc

Label; optional; default is @bazel_tools//tools/cpp:malloc

替换 malloc 的默认依赖项。

默认情况下,C++ 二进制文件会关联到 //tools/cpp:malloc,这是一个空库,因此二进制文件最终会使用 libc malloc。 此标签必须引用 cc_library。如果编译针对的是非 C++ 规则,则此选项无效。如果指定了 linkshared=True,则此属性的值会被忽略。

nocopts

String; optional

从 C++ 编译命令中移除匹配选项。 符合“Make”变量替换条件。此属性的值会被解释为正则表达式。为了编译此规则,与正则表达式匹配的任何现有 COPTS(包括规则的 copts 属性中明确指定的值)都将从 COPTS 中移除。 您应该很少需要此属性。
stamp

Integer; optional; default is 0

是否将 build 信息编码到二进制文件中。可能的值包括:
  • stamp = 1:请务必将 build 信息印入二进制文件,即使在 --nostamp build 中也是如此。应避免此设置,因为它可能会终止二进制文件和任何依赖于它的下游操作的远程缓存。
  • stamp = 0:始终使用常量值替换 build 信息。这样可以很好地构建构建结果缓存。
  • stamp = -1:build 信息的嵌入由 --[no]stamp 标志控制。

已签名的二进制文件不会重新构建,除非其依赖项发生变化。

win_def_file

Label; optional

要传递给链接器的 Windows DEF 文件。

仅当 Windows 是目标平台时,才应使用此属性。该文件可用于在关联共享库期间 导出符号

cc_toolchain

查看规则来源
cc_toolchain(name, all_files, ar_files, as_files, compatible_with, compiler, compiler_files, compiler_files_without_includes, coverage_files, cpu, deprecation, distribs, dwp_files, dynamic_runtime_lib, exec_transition_for_inputs, features, libc_top, licenses, linker_files, module_map, objcopy_files, restricted_to, static_runtime_lib, strip_files, supports_header_parsing, supports_param_files, tags, target_compatible_with, testonly, toolchain_config, toolchain_identifier, visibility)

表示 C++ 工具链。

此规则负责:

  • 收集运行 C++ 操作所需的所有工件。由 all_filescompiler_fileslinker_files 等属性或以 _files 结尾的属性组成。这些是最常见的文件组,会遍历所有必需的文件。
  • 为 C++ 操作生成正确的命令行。这是使用 CcToolchainConfigInfo 提供程序(详见下文)实现的。

使用 toolchain_config 属性配置 C++ 工具链。另请参阅此 页面 ,以查看详细的 C++ 工具链配置和工具链选择文档。

使用 tags = ["manual"] 可防止在调用 bazel build //... 时不必要地构建和配置工具链

参数

属性
name

Name; required

此目标的唯一名称。

all_files

Label; required

所有 cc_toolchain 工件的集合。这些工件将作为输入添加到所有 rules_cc 相关操作(使用以下特性中更精确工件的一组操作除外)。Bazel 假定 all_files 是所有其他提供工件的属性的超集(例如,linktamp 编译需要编译和链接文件,因此它需要 all_files)。

这是 cc_toolchain.files 包含的内容,所有使用 C++ 工具链的 Starlark 规则都会使用此属性。

ar_files

Label; optional

归档操作所需的所有 cc_toolchain 工件的集合。

as_files

Label; optional

汇编操作所需的所有 cc_toolchain 工件的集合。

compiler

String; optional; nonconfigurable

已弃用。改用 toolchain_identifier 属性。在 将 CROSSTOOL 迁移到 Starlark 之后,这将是空函数,并将被 #7075 移除。

设置后,它将用于执行 crosstool_config.toolchain 选择。它优先于 --cpu Bazel 选项。

compiler_files

Label; required

编译操作所需的所有 cc_toolchain 工件的集合。
compiler_files_without_includes

Label; optional

在支持输入发现的情况下,编译操作所需的所有 cc_toolchain 工件(目前仅限 Google)的集合。
coverage_files

Label; optional

覆盖率操作所需的所有 cc_toolchain 工件的集合。如果未指定,系统会使用 all_files。
cpu

String; optional; nonconfigurable

已弃用。请改用 toolchain_identifier 属性。在将 CROSSTOOL 迁移到 Starlark 之后,这将是一个空操作,并且将被 #7075 移除。

设置后,它将用于执行 crosstool_config.toolchain 选择。它优先于 --cpu Bazel 选项。

dwp_files

Label; required

DWP 操作所需的所有 CC_toolchain 工件的集合。
dynamic_runtime_lib

Label; optional

适用于 C++ 运行时库(例如 libstdc++.so)的动态库工件。

启用“static_link_cpp_runtimes”功能后,系统会动态关联依赖项。

exec_transition_for_inputs

Boolean; optional; default is True

设置为 True 时,可将执行平台的所有文件输入构建到 cc_toolchain,而不是转换(即默认目标平台)。
libc_top

Label; optional

libc 的工件集合,作为编译/关联操作的输入传递。
linker_files

Label; required

关联操作所需的所有 cc_toolchain 工件的集合。
module_map

Label; optional

将用于模块化 build 的模块映射工件。
objcopy_files

Label; required

OBJCopy 操作所需的所有 CC_toolchain 工件的集合。
static_runtime_lib

Label; optional

适用于 C++ 运行时库的静态库工件(例如 libstdc++.a)。

如果您启用了“static_link_cpp_runtimes”功能,系统就会采用静态方式关联依赖项。

strip_files

Label; required

删除操作所需的全部 cc_toolchain 工件的集合。
supports_header_parsing

Boolean; optional; default is False

如果 cc_toolchain 支持标头解析操作,则设置为 True。
supports_param_files

Boolean; optional; default is True

如果 cc_toolchain 支持使用参数文件链接操作,请设为 True。
toolchain_config

Label; required

提供 cc_toolchain_config_info 的规则的标签。
toolchain_identifier

String; optional; nonconfigurable

用于将此 cc_toolchain 与相应的 crosstool_config.toolchain 匹配的标识符。

在问题 #5380 修复之前,这是将 cc_toolchainCROSSTOOL.toolchain 相关联的推荐方法。它将替换为 toolchain_config 属性 (#5380)。

cc_toolchain_suite

查看规则来源
cc_toolchain_suite(name, compatible_with, deprecation, distribs, features, licenses, restricted_to, tags, target_compatible_with, testonly, toolchains, visibility)

表示 C++ 工具链的集合。

此规则负责:

  • 收集所有相关的 C++ 工具链。
  • 根据传递给 Bazel 的 --cpu--compiler 选项选择一个工具链。

另请参阅此 页面 ,以查看详细的 C++ 工具链配置和工具链选择文档。

参数

属性
name

Name; required

此目标的唯一名称。

toolchains

Dictionary mapping strings to labels; required; nonconfigurable

从“<cpu>”或“<cpu>|<compiler>”字符串到 cc_toolchain 标签的映射。只有 --cpu 传递给 Bazel 时,会使用“<cpu>”;当 --cpu--compiler 都传递给 Bazel 时,会使用“<cpu>|<compiler>”。示例:

          cc_toolchain_suite(
            name = "toolchain",
            toolchains = {
              "piii|gcc": ":my_cc_toolchain_for_piii_using_gcc",
              "piii": ":my_cc_toolchain_for_piii_using_default_compiler",
            },
          )