C / C++ 规则

报告问题 查看源代码 每夜 build · 8.0 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

规则

cc_binary

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

它会生成可执行二进制文件。


目标的 name 应与应用的主要入口点(不含扩展名)的源文件的名称相同。例如,如果您的入口点位于 main.cc 中,则您的名称应为 main

隐式输出目标

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

参数

属性
name

名称;必需

此目标的唯一名称。

deps

标签列表;默认值为 []

要关联到二进制目标的其他库的列表。

这些可以是 cc_libraryobjc_library 目标。

还可以将链接器脚本 (.lds) 放入依赖项中,并在 linkopts 中引用它们。
srcs

标签列表;默认值为 []

用于创建库目标而经过处理的 C 和 C++ 文件的列表。这些是 C/C++ 源文件和头文件,可以是非生成的(普通源代码),也可以是生成的。

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

纯汇编文件(.s、.asm)不会预处理,通常使用汇编器构建。预处理汇编文件 (.S) 会进行预处理,通常使用 C/C++ 编译器进行构建。

系统不会编译 .h 文件,但会将其提供给此规则中的来源使用。.cc.h 文件都可以直接包含这些 srcs 中列出的标头,也可以包含此规则或 deps 参数中列出的任何规则的 hdrs 中列出的标头。

所有 #included 文件都必须在本规则或引用的 cc_library 规则的 hdrs 属性中提及,或者如果这些文件是此库的私有文件,则应在 srcs 中列出。如需了解详情,请参阅“头文件包含检查”

.so.lo.a 文件是预编译文件。如果您的库使用了我们没有源代码的第三方代码,则可能会将这些代码标记为 srcs

如果 srcs 属性包含其他规则的标签,cc_library 将使用该规则的输出文件作为源文件进行编译。这对于一次性生成源代码非常有用(如果要经常使用,最好实现 Starlark 规则类并使用 cc_common API)

允许的 srcs 文件类型:

  • C 和 C++ 源文件:.c.cc.cpp.cxx.c++.C
  • C 和 C++ 头文件:.h.hh.hpp.hxx.inc.inl.H
  • 带有 C 预处理器的汇编器:.S
  • 归档:.a.pic.a
  • “始终关联”库:.lo.pic.lo
  • 有版本或无版本的共享库:.so.so.version
  • 对象文件:.o.pic.o

... 以及生成这些文件的任何规则(例如 cc_embed_data)。不同的扩展名表示不同的编程语言,具体取决于 gcc 惯例。

data

标签列表;默认值为 []

此库在运行时所需的文件列表。 如需了解 data 的一般说明,请参阅大多数 build 规则定义的典型属性

如果 data 是生成的文件的名称,则此 cc_library 规则会自动依赖于生成规则。

如果 data 是规则名称,则此 cc_library 规则会自动依赖于该规则,并且该规则的 outs 会自动添加到此 cc_library 的数据文件中。

您的 C++ 代码可以按如下方式访问这些数据文件:


  const std::string path = devtools_build::GetDataDependencyFilepath(
      "my/test/data/file");
additional_linker_inputs

标签列表;默认值为 []

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

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

conlyopts

字符串列表;默认值为 []

将这些选项添加到 C 编译命令。 会受到 “Make 变量”替换和 Bourne shell 令牌化的影响。
copts

字符串列表;默认值为 []

将这些选项添加到 C/C++ 编译命令中。会受到 “Make 变量”替换和 Bourne shell 令牌化的影响。

在编译二进制目标之前,此属性中的每个字符串都会按给定顺序添加到 COPTS。这些标志仅对此目标的编译有效,而不会影响其依赖项,因此请注意其他位置包含的头文件。 所有路径都应相对于工作区,而不是相对于当前软件包。 在 third_party 之外,应该不需要此属性。

如果软件包声明了功能 no_copts_tokenization,Bourne shell 令牌化仅适用于由单个“Make”变量组成的字符串。

cxxopts

字符串列表;默认值为 []

将这些选项添加到 C++ 编译命令。 会受到 “Make 变量”替换和 Bourne shell 令牌化的影响。
defines

字符串列表;默认值为 []

要添加到编译行中的定义列表。会受到 “Make”变量替换和 Bourne shell 令牌化的影响。每个字符串(必须由单个 Bourne shell 令牌组成)都将附加 -D,并添加到此目标的编译命令行以及依赖于它的每个规则中。请务必谨慎,因为这可能会产生深远影响。如果不确定,请改为向 local_defines 添加定义值。
dynamic_deps

标签列表;默认值为 []

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

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

hdrs_check

字符串;默认值为 ""

已废弃,无操作。
includes

字符串列表;默认值为 []

要添加到编译行中的包含目录列表。需遵循“Make 变量”替换规则。每个字符串都会附加软件包路径,并通过“include_paths”CROSSTOOL 功能传递给 C++ 工具链以进行展开。在具有典型功能定义的 POSIX 系统上运行的工具链将生成 -isystem path_to_package/include_entry。此方法仅适用于不符合 Google 编写 #include 语句样式的第三方库。与 COPTS 不同,这些标志会为此规则以及依赖于它的每个规则添加。(注意:不是它依赖的规则!)请务必谨慎,因为这可能会产生深远影响。如果不确定,请改为向 COPTS 添加“-I”标志。

添加的 include 路径将包含生成的文件以及源代码树中的文件。

标签;默认值为 "@bazel_tools//tools/cpp:link_extra_lib"

控制额外库的链接。

默认情况下,C++ 二进制文件会与 //tools/cpp:link_extra_lib 链接,而 //tools/cpp:link_extra_lib 默认依赖于标签标志 //tools/cpp:link_extra_libs。 如果未设置此标志,此库默认为空。设置标签标志后,您可以关联可选依赖项,例如弱符号的替换项、共享库函数的拦截器或特殊运行时库(对于 malloc 替换项,最好使用 malloc--custom_malloc)。将此属性设置为 None 会停用此行为。

linkopts

字符串列表;默认值为 []

将这些标志添加到 C++ 链接器命令。 会受到 “Make”变量替换、 Bourne shell 令牌化标签展开的影响。在此属性中的每个字符串都会在链接二进制目标之前添加到 LINKOPTS

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

linkshared

布尔值;默认值为 False

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

此标志的存在表示 -shared 标志会与 gcc 进行关联,并且生成的共享库适合加载到 Java 程序等中。不过,出于构建目的,它绝不会关联到依赖的二进制文件,因为假定使用 cc_binary 规则构建的共享库仅由其他程序手动加载,因此不应将其视为 cc_library 规则的替代项。为了实现可伸缩性,我们建议您完全避免这种方法,而改为让 java_library 依赖于 cc_library 规则。

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

linkstatic

布尔值;默认值为 True

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

默认情况下,此选项对 cc_binary 处于开启状态,对其余内容处于关闭状态。

如果启用此选项且这是二进制文件或测试,则此选项会告知构建工具尽可能为用户库链接 .a 而不是 .so。 libc 等系统库(但不是 C/C++ 运行时库,请参阅下文)仍会动态链接,没有静态库的库也是如此。因此,生成的可执行文件仍将是动态链接的,因此只是主要为静态。

实际上,有三种不同的方式可以关联可执行文件:

  • 具有 fully_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 即可启用此模式。
  • DYNAMIC,其中所有库都将动态链接(如果有动态版本),例如“gcc foo.o libfoo.so libbaz.so -lm”。
    通过指定 linkstatic=False 即可启用此模式。

如果 features 中的 linkstatic 属性或 fully_static_link//third_party 之外使用,请在规则旁边添加注释来说明原因。

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

生产环境中使用 linkstatic=False 构建的代码应该很少。如果为 linkstatic=False,则构建工具将在 *.runfiles 区域中创建指向依赖的共享库的符号链接。

local_defines

字符串列表;默认值为 []

要添加到编译行中的定义列表。会受到 “Make”变量替换和 Bourne shell 令牌化的影响。每个字符串(必须由单个 Bourne shell 令牌组成)都将附加 -D,并添加到此目标的编译命令行,但不会添加到其依赖项。
malloc

标签;默认值为 "@bazel_tools//tools/cpp:malloc"

替换对 malloc 的默认依赖项。

默认情况下,C++ 二进制文件会与 //tools/cpp:malloc 关联,后者是一个空库,因此二进制文件最终会使用 libc malloc。此标签必须引用 cc_library。如果编译的是非 C++ 规则,此选项不会产生任何影响。如果指定了 linkshared=True,系统会忽略此属性的值。

module_interfaces

标签列表;默认值为 []

文件列表被视为 C++20 模块接口。

C++ 标准对模块接口文件扩展名没有限制

  • Clang 使用 cppm
  • GCC 可以使用任何源文件扩展名
  • MSVC 使用 ixx

使用受标志 --experimental_cpp_modules 保护。

nocopts

字符串;默认值为 ""

从 C++ 编译命令中移除匹配的选项。 受 “Make”变量替换的约束。此属性的值会被解读为正则表达式。为了编译此规则,系统会从 COPTS 中移除与此正则表达式匹配的所有现有 COPTS(包括在规则的 copts 属性中明确指定的值)。在 third_party 之外,不需要使用此属性,也不能使用此属性。除了“Make”变量替换之外,系统不会以任何其他方式预处理这些值。
reexport_deps

标签列表;默认值为 []

stamp

整数;默认为 -1

是否将 build 信息编码到二进制文件中。可能的值:
  • stamp = 1:始终将 build 信息戳入二进制文件,即使在 --nostamp build 中也是如此。应避免使用此设置,因为它可能会终止二进制文件以及依赖于它的所有下游操作的远程缓存。
  • stamp = 0:始终将 build 信息替换为常量值。这样可以实现良好的 build 结果缓存。
  • stamp = -1:build 信息的嵌入由 --[no]stamp 标志控制。

除非其依赖项发生变化,否则不会重新构建带有标记的二进制文件。

win_def_file

标签;默认值为 None

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

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

cc_import

查看规则源代码
cc_import(name, deps, data, hdrs, alwayslink, compatible_with, deprecation, distribs, exec_compatible_with, exec_properties, features, includes, interface_library, linkopts, objects, pic_objects, pic_static_library, restricted_to, shared_library, static_library, system_provided, tags, target_compatible_with, testonly, toolchains, 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. 将共享库与接口库相关联

在 Unix 上:


cc_import(
  name = "mylib",
  hdrs = ["mylib.h"],
  # libmylib.ifso is an interface library for libmylib.so which will be passed to linker
  interface_library = "libmylib.ifso",
  # libmylib.so will be available for runtime
  shared_library = "libmylib.so",
)

在 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 相关联

在 Unix 上:


cc_import(
  name = "mylib",
  hdrs = ["mylib.h"],
  interface_library = "libmylib.ifso", # Or we can also use libmylib.so as its own interface library
  # libmylib.so is provided by system environment, for example it can be found in LD_LIBRARY_PATH.
  # This indicates that Bazel is not responsible for making libmylib.so available.
  system_provided = 1,
)

在 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",
)

在 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",
)

其余部分在 Unix 和 Windows 上相同:


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

# second will link to libmylib.so (or libmylib.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

名称;必需

此目标的唯一名称。

deps

标签列表;默认值为 []

目标依赖的其他库的列表。 如需了解 deps 的一般说明,请参阅大多数 build 规则定义的典型属性
hdrs

标签列表;默认值为 []

此预编译库发布的头文件列表,以供依赖项规则中的源文件直接包含。

布尔值;默认值为 False

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

如果 alwayslink 不适用于 Windows 上的 VS 2017,这是由于存在已知问题,请将 VS 2017 升级到最新版本。

includes

字符串列表;默认值为 []

要添加到编译行中的包含目录列表。需遵循“Make 变量”替换规则。每个字符串都会附加软件包路径,并通过“include_paths”CROSSTOOL 功能传递给 C++ 工具链以进行展开。在具有典型功能定义的 POSIX 系统上运行的工具链将生成 -isystem path_to_package/include_entry。此方法仅适用于不符合 Google 编写 #include 语句样式的第三方库。与 COPTS 不同,这些标志会为此规则以及依赖于它的每个规则添加。(注意:不是它依赖的规则!)请务必谨慎,因为这可能会产生深远影响。如果不确定,请改为向 COPTS 添加“-I”标志。

默认的 include 路径不包含生成的文件。如果您需要 #include 生成的头文件,请在 srcs 中列出该文件。

interface_library

标签;默认值为 None

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

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

linkopts

字符串列表;默认值为 []

将这些标志添加到 C++ 链接器命令。 会受到 “Make”变量替换、 Bourne shell 令牌化标签展开的影响。在此属性中的每个字符串都会在链接二进制目标之前添加到 LINKOPTS

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

objects

标签列表;默认值为 []

pic_objects

标签列表;默认值为 []

pic_static_library

标签;默认值为 None

shared_library

标签;默认值为 None

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

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

static_library

标签;默认值为 None

单个预编译的静态库。

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

system_provided

布尔值;默认值为 False

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

cc_library

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

对于 C++ 编译的库,请使用 cc_library()。 结果为 .so.lo.a,具体取决于需要的内容。

如果您使用静态链接构建依赖于 cc_library 的项目,则依赖的库规则的输出为 .a 文件。如果您指定 alwayslink=True,则会获得 .lo 文件。

共享库的实际输出文件名为 libfoo.so,其中 foo 是规则的名称。其他类型的库分别以 .lo.a 结尾。如果您需要特定的共享库名称(例如,定义 Python 模块),请使用 genrule 将库复制到所需的名称。

标头包含性检查

构建过程中使用的所有头文件都必须在 cc_* 规则的 hdrssrcs 中声明。系统会强制执行此规则。

对于 cc_library 规则,hdrs 中的头文件构成了库的公共接口,可以直接从库本身的 hdrssrcs 中的文件中包含,也可以从在 deps 中列出库的 cc_* 规则的 hdrssrcs 中的文件中包含。srcs 中的头文件只能直接从库本身的 hdrssrcs 中的文件中包含。在决定将头文件放入 hdrs 还是 srcs 时,您应考虑是否希望此库的使用方能够直接包含该头文件。这与在编程语言中选择 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.hbaz-impl.h
baz-impl.hbaz.h
baz.ccbaz.h baz-impl.h

收录检查规则仅适用于直接收录。在上面的示例中,foo.cc 可以包含 bar.hbar.h 可以包含 baz.hbaz.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 使用此功能。

示例


cc_library(
    name = "ast_inspector_lib",
    srcs = ["ast_inspector_lib.cc"],
    hdrs = ["ast_inspector_lib.h"],
    visibility = ["//visibility:public"],
    deps = ["//third_party/llvm/llvm/tools/clang:frontend"],
    # alwayslink as we want to be able to call things in this library at
    # debug time, even if they aren't used anywhere in the code.
    alwayslink = 1,
)

以下示例来自 third_party/python2_4_3/BUILD。部分代码使用 dl 库(用于加载另一个动态库),因此此规则指定了 -ldl 链接选项以链接 dl 库。


cc_library(
    name = "python2_4_3",
    linkopts = [
        "-ldl",
        "-lutil",
    ],
    deps = ["//third_party/expat"],
)

以下示例来自 third_party/kde/BUILD。 我们会在仓库中保留预构建的 .so 文件。 头文件位于名为 include 的子目录中。


cc_library(
    name = "kde",
    srcs = [
        "lib/libDCOP.so",
        "lib/libkdesu.so",
        "lib/libkhtml.so",
        "lib/libkparts.so",
        ...more .so files...,
    ],
    includes = ["include"],
    deps = ["//third_party/X11"],
)

以下示例来自 third_party/gles/BUILD。 第三方代码通常需要一些 defineslinkopts


cc_library(
    name = "gles",
    srcs = [
        "GLES/egl.h",
        "GLES/gl.h",
        "ddx.c",
        "egl.c",
    ],
    defines = [
        "USE_FLOAT",
        "__GL_FLOAT",
        "__GL_COMMON",
    ],
    linkopts = ["-ldl"],  # uses dlopen(), dl library
    deps = [
        "es",
        "//third_party/X11",
    ],
)

参数

属性
name

名称;必需

此目标的唯一名称。

deps

标签列表;默认值为 []

库目标依赖的其他库的列表。

这些可以是 cc_libraryobjc_library 目标。

如需有关 deps 的一般说明,请参阅大多数 build 规则定义的典型属性

这些应为 C++ 库规则的名称。 构建用于关联此规则库的二进制文件时,您还将关联 deps 中的库。

尽管名称为“依赖项”,但此库的并非所有客户端都属于此类别。运行时数据依赖项属于 data。 由其他规则生成的源文件属于 srcs

如需关联预编译的第三方库,请改为将其名称添加到 srcs

如需依赖某项内容但不将其链接到此库,请改为将其名称添加到 data

srcs

标签列表;默认值为 []

用于创建库目标而经过处理的 C 和 C++ 文件的列表。这些是 C/C++ 源文件和头文件,可以是非生成的(普通源代码),也可以是生成的。

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

纯汇编文件(.s、.asm)不会预处理,通常使用汇编器构建。预处理汇编文件 (.S) 会进行预处理,通常使用 C/C++ 编译器进行构建。

系统不会编译 .h 文件,但会将其提供给此规则中的来源使用。.cc.h 文件都可以直接包含这些 srcs 中列出的标头,也可以包含此规则或 deps 参数中列出的任何规则的 hdrs 中列出的标头。

所有 #included 文件都必须在本规则或引用的 cc_library 规则的 hdrs 属性中提及,或者如果这些文件是此库的私有文件,则应在 srcs 中列出。如需了解详情,请参阅“头文件包含检查”

.so.lo.a 文件是预编译文件。如果您的库使用了我们没有源代码的第三方代码,则可能会将这些代码标记为 srcs

如果 srcs 属性包含其他规则的标签,cc_library 将使用该规则的输出文件作为源文件进行编译。这对于一次性生成源代码非常有用(如果要经常使用,最好实现 Starlark 规则类并使用 cc_common API)

允许的 srcs 文件类型:

  • C 和 C++ 源文件:.c.cc.cpp.cxx.c++.C
  • C 和 C++ 头文件:.h.hh.hpp.hxx.inc.inl.H
  • 带有 C 预处理器的汇编器:.S
  • 归档:.a.pic.a
  • “始终关联”库:.lo.pic.lo
  • 有版本或无版本的共享库:.so.so.version
  • 对象文件:.o.pic.o

... 以及生成这些文件的任何规则(例如 cc_embed_data)。不同的扩展名表示不同的编程语言,具体取决于 gcc 惯例。

data

标签列表;默认值为 []

此库在运行时所需的文件列表。 如需了解 data 的一般说明,请参阅大多数 build 规则定义的典型属性

如果 data 是生成的文件的名称,则此 cc_library 规则会自动依赖于生成规则。

如果 data 是规则名称,则此 cc_library 规则会自动依赖于该规则,并且该规则的 outs 会自动添加到此 cc_library 的数据文件中。

您的 C++ 代码可以按如下方式访问这些数据文件:


  const std::string path = devtools_build::GetDataDependencyFilepath(
      "my/test/data/file");
hdrs

标签列表;默认值为 []

此库发布的头文件列表,以供依赖项规则中的源文件直接包含。

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

允许的 headers 文件类型:.h.hh.hpp.hxx

additional_compiler_inputs

标签列表;默认值为 []

您可能希望传递给编译器命令行的任何其他文件,例如沙盒过滤列表。然后,您可以在 copts 中使用 $(location) 函数来使用此处指定的文件。
additional_linker_inputs

标签列表;默认值为 []

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

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

布尔值;默认值为 False

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

如果 alwayslink 不适用于 Windows 上的 VS 2017,这是由于存在已知问题,请将 VS 2017 升级到最新版本。

conlyopts

字符串列表;默认值为 []

将这些选项添加到 C 编译命令。 会受到 “Make 变量”替换和 Bourne shell 令牌化的影响。
copts

字符串列表;默认值为 []

将这些选项添加到 C/C++ 编译命令中。会受到 “Make 变量”替换和 Bourne shell 令牌化的影响。

在编译二进制目标之前,此属性中的每个字符串都会按给定顺序添加到 COPTS。这些标志仅对此目标的编译有效,而不会影响其依赖项,因此请注意其他位置包含的头文件。 所有路径都应相对于工作区,而不是相对于当前软件包。 在 third_party 之外,应该不需要此属性。

如果软件包声明了功能 no_copts_tokenization,Bourne shell 令牌化仅适用于由单个“Make”变量组成的字符串。

cxxopts

字符串列表;默认值为 []

将这些选项添加到 C++ 编译命令。 会受到 “Make 变量”替换和 Bourne shell 令牌化的影响。
defines

字符串列表;默认值为 []

要添加到编译行中的定义列表。会受到 “Make”变量替换和 Bourne shell 令牌化的影响。每个字符串(必须由单个 Bourne shell 令牌组成)都将附加 -D,并添加到此目标的编译命令行以及依赖于它的每个规则中。请务必谨慎,因为这可能会产生深远影响。如果不确定,请改为向 local_defines 添加定义值。
hdrs_check

字符串;默认值为 ""

已废弃,无操作。
implementation_deps

标签列表;默认值为 []

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

字符串;默认值为 ""

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

设置后,此规则的 hdrs 属性中的头文件可通过将此属性的值附加到其相对于代码库的路径来访问。

系统会先移除 strip_include_prefix 属性中的前缀,然后再添加此前缀。

此属性仅在 third_party 下有效。

includes

字符串列表;默认值为 []

要添加到编译行中的包含目录列表。需遵循“Make 变量”替换规则。每个字符串都会附加软件包路径,并通过“include_paths”CROSSTOOL 功能传递给 C++ 工具链以进行展开。在具有典型功能定义的 POSIX 系统上运行的工具链将生成 -isystem path_to_package/include_entry。此方法仅适用于不符合 Google 编写 #include 语句样式的第三方库。与 COPTS 不同,这些标志会为此规则以及依赖于它的每个规则添加。(注意:不是它依赖的规则!)请务必谨慎,因为这可能会产生深远影响。如果不确定,请改为向 COPTS 添加“-I”标志。

添加的 include 路径将包含生成的文件以及源代码树中的文件。

linkopts

字符串列表;默认值为 []

请参阅 cc_binary.linkoptslinkopts 属性还会应用于通过 deps 属性(或通过处理方式类似的其他属性:cc_binarymalloc 属性)直接或间接依赖于此库的任何目标。依赖项 linkopts 的优先级高于依赖项 linkopts(即依赖项 linkopts 会在命令行中显示在后面)。--linkopt 中指定的 linkopt 优先于规则 linkopt。

请注意,linkopts 属性仅适用于创建 .so 文件或可执行文件时,而不适用于创建 .a.lo 文件时。因此,如果设置了 linkstatic=True 属性,linkopts 属性对此库的创建没有影响,只会影响依赖于此库的其他目标。

此外,请务必注意,系统不支持“-Wl,-soname”或“-Xlinker -soname”选项,并且绝不应在此属性中指定这些选项。

cc_library 规则生成的 .so 文件未与其依赖的库相关联。如果您尝试创建要在主代码库之外使用的共享库(例如,用于手动使用 dlopen()LD_PRELOAD),最好使用带有 linkshared=True 属性的 cc_binary 规则。请参阅 cc_binary.linkshared

linkstamp

标签;默认值为 None

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

布尔值;默认值为 False

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

默认情况下,此选项对 cc_binary 处于开启状态,对其余内容处于关闭状态。

如果启用此选项且这是二进制文件或测试,则此选项会告知构建工具尽可能为用户库链接 .a 而不是 .so。 libc 等系统库(但不是 C/C++ 运行时库,请参阅下文)仍会动态链接,没有静态库的库也是如此。因此,生成的可执行文件仍将是动态链接的,因此只是主要为静态。

实际上,有三种不同的方式可以关联可执行文件:

  • 具有 fully_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 即可启用此模式。
  • DYNAMIC,其中所有库都将动态链接(如果有动态版本),例如“gcc foo.o libfoo.so libbaz.so -lm”。
    通过指定 linkstatic=False 即可启用此模式。

如果 features 中的 linkstatic 属性或 fully_static_link//third_party 之外使用,请在规则旁边添加注释来说明原因。

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

生产环境中使用 linkstatic=False 构建的代码应该很少。如果为 linkstatic=False,则构建工具将在 *.runfiles 区域中创建指向依赖的共享库的符号链接。

local_defines

字符串列表;默认值为 []

要添加到编译行中的定义列表。会受到 “Make”变量替换和 Bourne shell 令牌化的影响。每个字符串(必须由单个 Bourne shell 令牌组成)都将附加 -D,并添加到此目标的编译命令行,但不会添加到其依赖项。
module_interfaces

标签列表;默认值为 []

文件列表被视为 C++20 模块接口。

C++ 标准对模块接口文件扩展名没有限制

  • Clang 使用 cppm
  • GCC 可以使用任何源文件扩展名
  • MSVC 使用 ixx

使用受标志 --experimental_cpp_modules 保护。

strip_include_prefix

字符串;默认值为 ""

要从此规则标头的路径中剥离的前缀。

设置后,此规则的 hdrs 属性中的标头可通过其路径(去掉此前缀)访问。

如果是相对路径,则视为相对于软件包的路径。如果是绝对路径,则会被视为相对于代码库的路径。

include_prefix 属性中的前缀会在移除此前缀后添加。

此属性仅在 third_party 下有效。

textual_hdrs

标签列表;默认值为 []

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

此位置用于声明无法单独编译的头文件;也就是说,这些头文件始终需要由其他源文件以文本形式包含,才能构建有效的代码。

win_def_file

标签;默认值为 None

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

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

cc_shared_library

查看规则源代码
cc_shared_library(name, deps, additional_linker_inputs, compatible_with, deprecation, distribs, dynamic_deps, exec_compatible_with, exec_properties, experimental_disable_topo_sort_do_not_use_remove_before_7_0, exports_filter, features, restricted_to, roots, shared_lib_name, static_deps, tags, target_compatible_with, testonly, toolchains, user_link_flags, visibility, 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_sharedfoobaz 静态链接起来,后者是传递依赖项。它不会关联 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`

这意味着,deps 的传递闭包中的某个库可在不通过任何 cc_shared_library 依赖项的情况下访问,但已关联到 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

名称;必需

此目标的唯一名称。

deps

标签列表;默认值为 []

顶级库,在完整归档后将无条件地静态链接到共享库中。

只要这些直接依赖项的任何传递库依赖项尚未由 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

标签列表;默认值为 []

您可能需要传递给链接器的任何其他文件,例如链接器脚本。您必须单独传递链接器需要的所有链接器标志,以便链接器知道此文件。您可以通过 user_link_flags 属性执行此操作。
dynamic_deps

标签列表;默认值为 []

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

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

experimental_disable_topo_sort_do_not_use_remove_before_7_0

布尔值;默认值为 False

exports_filter

字符串列表;默认值为 []

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

任何目标 deps 都已被视为由共享库导出。此属性应用于列出由共享库导出的但属于 deps 的传递依赖项的任何目标。

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

允许使用以下语法:

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

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

roots

标签列表;默认值为 []

shared_lib_name

字符串;默认值为 ""

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

字符串列表;默认值为 []

字符串列表;默认值为 []

您可能想要传递给链接器的任何其他标志。例如,如需让链接器知道通过 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

标签;默认值为 None

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

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

cc_static_library

查看规则源代码
cc_static_library(name, deps, compatible_with, deprecation, distribs, exec_compatible_with, exec_properties, features, restricted_to, tags, target_compatible_with, testonly, toolchains, visibility)
此规则目前处于实验阶段,只能与 --experimental_cc_static_library 标志一起使用。 根据目标列表及其传递依赖项生成静态库。

生成的静态库包含 deps 中列出的目标的对象文件以及它们的传递依赖项,其中优先考虑 PIC 对象。

输出组

linkdeps

一个文本文件,其中包含 deps 中列出的目标的传递依赖项的标签。这些传递依赖项未向静态库贡献任何对象文件,但确实提供了至少一个静态、动态或接口库。生成的静态库可能需要这些库在链接时可用。

linkopts

一个文本文件,其中包含 deps 中列出的目标的所有传递依赖项的用户提供的 linkopts

符号重复

默认情况下,cc_static_library 规则会检查生成的静态库是否不包含任何重复的符号。如果存在重复符号,构建会失败,并会显示错误消息,其中列出了重复符号以及包含这些符号的对象文件。

您可以通过设置 features = ["-symbol_check"] 来按目标或软件包停用此检查,也可以通过 --features=-symbol_check 来全局停用此检查。

symbol_check 的工具链支持

随 Bazel 一起提供的自动配置 C++ 工具链在所有平台上都支持 symbol_check 功能。自定义工具链可以通过以下两种方式之一添加对它的支持:

  • 实现 ACTION_NAMES.validate_static_library 操作并使用 symbol_check 功能启用该操作。系统会使用两个参数调用操作中设置的工具,一个是用于检查是否存在重复符号的静态库,另一个是检查通过后必须创建的文件的路径。
  • symbol_check 功能添加归档器标志,导致创建静态库的操作在出现重复符号时失败。

参数

属性
name

名称;必需

此目标的唯一名称。

deps

标签列表;默认值为 []

要合并到静态库中的目标的列表,包括它们的所有传递依赖项。

不提供任何对象文件的依赖项不会包含在静态库中,但其标签会收集在 linkdeps 输出组提供的文件中。

cc_test

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

cc_test() 规则会编译测试。在这里,测试是指某些测试代码的二进制封装容器。

默认情况下,C++ 测试是动态链接的。
如需将单元测试静态关联,请指定 linkstatic=True。 最好说明您的测试为何需要 linkstatic;这可能并不明显。

隐式输出目标

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

请参阅 cc_binary() 参数,但对于测试,stamp 参数默认设置为 0,并且 cc_test 具有与所有测试规则 (*_test) 通用的额外属性

参数

属性
name

名称;必需

此目标的唯一名称。

deps

标签列表;默认值为 []

要关联到二进制目标的其他库的列表。

这些可以是 cc_libraryobjc_library 目标。

还可以将链接器脚本 (.lds) 放入依赖项中,并在 linkopts 中引用它们。
srcs

标签列表;默认值为 []

用于创建库目标而经过处理的 C 和 C++ 文件的列表。这些是 C/C++ 源文件和头文件,可以是非生成的(普通源代码),也可以是生成的。

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

纯汇编文件(.s、.asm)不会预处理,通常使用汇编器构建。预处理汇编文件 (.S) 会进行预处理,通常使用 C/C++ 编译器进行构建。

系统不会编译 .h 文件,但会将其提供给此规则中的来源使用。.cc.h 文件都可以直接包含这些 srcs 中列出的标头,也可以包含此规则或 deps 参数中列出的任何规则的 hdrs 中列出的标头。

所有 #included 文件都必须在本规则或引用的 cc_library 规则的 hdrs 属性中提及,或者如果这些文件是此库的私有文件,则应在 srcs 中列出。如需了解详情,请参阅“头文件包含检查”

.so.lo.a 文件是预编译文件。如果您的库使用了我们没有源代码的第三方代码,则可能会将这些代码标记为 srcs

如果 srcs 属性包含其他规则的标签,cc_library 将使用该规则的输出文件作为源文件进行编译。这对于一次性生成源代码非常有用(如果要经常使用,最好实现 Starlark 规则类并使用 cc_common API)

允许的 srcs 文件类型:

  • C 和 C++ 源文件:.c.cc.cpp.cxx.c++.C
  • C 和 C++ 头文件:.h.hh.hpp.hxx.inc.inl.H
  • 带有 C 预处理器的汇编器:.S
  • 归档:.a.pic.a
  • “始终关联”库:.lo.pic.lo
  • 有版本或无版本的共享库:.so.so.version
  • 对象文件:.o.pic.o

... 以及生成这些文件的任何规则(例如 cc_embed_data)。不同的扩展名表示不同的编程语言,具体取决于 gcc 惯例。

data

标签列表;默认值为 []

此库在运行时所需的文件列表。 如需了解 data 的一般说明,请参阅大多数 build 规则定义的典型属性

如果 data 是生成的文件的名称,则此 cc_library 规则会自动依赖于生成规则。

如果 data 是规则名称,则此 cc_library 规则会自动依赖于该规则,并且该规则的 outs 会自动添加到此 cc_library 的数据文件中。

您的 C++ 代码可以按如下方式访问这些数据文件:


  const std::string path = devtools_build::GetDataDependencyFilepath(
      "my/test/data/file");
additional_linker_inputs

标签列表;默认值为 []

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

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

conlyopts

字符串列表;默认值为 []

将这些选项添加到 C 编译命令。 会受到 “Make 变量”替换和 Bourne shell 令牌化的影响。
copts

字符串列表;默认值为 []

将这些选项添加到 C/C++ 编译命令中。会受到 “Make 变量”替换和 Bourne shell 令牌化的影响。

在编译二进制目标之前,此属性中的每个字符串都会按给定顺序添加到 COPTS。这些标志仅对此目标的编译有效,而不会影响其依赖项,因此请注意其他位置包含的头文件。 所有路径都应相对于工作区,而不是相对于当前软件包。 在 third_party 之外,应该不需要此属性。

如果软件包声明了功能 no_copts_tokenization,Bourne shell 令牌化仅适用于由单个“Make”变量组成的字符串。

cxxopts

字符串列表;默认值为 []

将这些选项添加到 C++ 编译命令。 会受到 “Make 变量”替换和 Bourne shell 令牌化的影响。
defines

字符串列表;默认值为 []

要添加到编译行中的定义列表。会受到 “Make”变量替换和 Bourne shell 令牌化的影响。每个字符串(必须由单个 Bourne shell 令牌组成)都将附加 -D,并添加到此目标的编译命令行以及依赖于它的每个规则中。请务必谨慎,因为这可能会产生深远影响。如果不确定,请改为向 local_defines 添加定义值。
dynamic_deps

标签列表;默认值为 []

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

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

hdrs_check

字符串;默认值为 ""

已废弃,无操作。
includes

字符串列表;默认值为 []

要添加到编译行中的包含目录列表。需遵循“Make 变量”替换规则。每个字符串都会附加软件包路径,并通过“include_paths”CROSSTOOL 功能传递给 C++ 工具链以进行展开。在具有典型功能定义的 POSIX 系统上运行的工具链将生成 -isystem path_to_package/include_entry。此方法仅适用于不符合 Google 编写 #include 语句样式的第三方库。与 COPTS 不同,这些标志会为此规则以及依赖于它的每个规则添加。(注意:不是它依赖的规则!)请务必谨慎,因为这可能会产生深远影响。如果不确定,请改为向 COPTS 添加“-I”标志。

添加的 include 路径将包含生成的文件以及源代码树中的文件。

标签;默认值为 "@bazel_tools//tools/cpp:link_extra_lib"

控制额外库的链接。

默认情况下,C++ 二进制文件会与 //tools/cpp:link_extra_lib 链接,而 //tools/cpp:link_extra_lib 默认依赖于标签标志 //tools/cpp:link_extra_libs。 如果未设置此标志,此库默认为空。设置标签标志后,您可以关联可选依赖项,例如弱符号的替换项、共享库函数的拦截器或特殊运行时库(对于 malloc 替换项,最好使用 malloc--custom_malloc)。将此属性设置为 None 会停用此行为。

linkopts

字符串列表;默认值为 []

将这些标志添加到 C++ 链接器命令。 会受到 “Make”变量替换、 Bourne shell 令牌化标签展开的影响。在此属性中的每个字符串都会在链接二进制目标之前添加到 LINKOPTS

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

linkshared

布尔值;默认值为 False

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

此标志的存在表示 -shared 标志会与 gcc 进行关联,并且生成的共享库适合加载到 Java 程序等中。不过,出于构建目的,它绝不会关联到依赖的二进制文件,因为假定使用 cc_binary 规则构建的共享库仅由其他程序手动加载,因此不应将其视为 cc_library 规则的替代项。为了实现可伸缩性,我们建议您完全避免这种方法,而改为让 java_library 依赖于 cc_library 规则。

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

linkstatic

布尔值;默认值为 False

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

默认情况下,此选项对 cc_binary 处于开启状态,对其余内容处于关闭状态。

如果启用此选项且这是二进制文件或测试,则此选项会告知构建工具尽可能为用户库链接 .a 而不是 .so。 libc 等系统库(但不是 C/C++ 运行时库,请参阅下文)仍会动态链接,没有静态库的库也是如此。因此,生成的可执行文件仍将是动态链接的,因此只是主要为静态。

实际上,有三种不同的方式可以关联可执行文件:

  • 具有 fully_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 即可启用此模式。
  • DYNAMIC,其中所有库都将动态链接(如果有动态版本),例如“gcc foo.o libfoo.so libbaz.so -lm”。
    通过指定 linkstatic=False 即可启用此模式。

如果 features 中的 linkstatic 属性或 fully_static_link//third_party 之外使用,请在规则旁边添加注释来说明原因。

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

生产环境中使用 linkstatic=False 构建的代码应该很少。如果为 linkstatic=False,则构建工具将在 *.runfiles 区域中创建指向依赖的共享库的符号链接。

local_defines

字符串列表;默认值为 []

要添加到编译行中的定义列表。会受到 “Make”变量替换和 Bourne shell 令牌化的影响。每个字符串(必须由单个 Bourne shell 令牌组成)都将附加 -D,并添加到此目标的编译命令行,但不会添加到其依赖项。
malloc

标签;默认值为 "@bazel_tools//tools/cpp:malloc"

替换对 malloc 的默认依赖项。

默认情况下,C++ 二进制文件会与 //tools/cpp:malloc 关联,后者是一个空库,因此二进制文件最终会使用 libc malloc。此标签必须引用 cc_library。如果编译的是非 C++ 规则,此选项不会产生任何影响。如果指定了 linkshared=True,系统会忽略此属性的值。

module_interfaces

标签列表;默认值为 []

文件列表被视为 C++20 模块接口。

C++ 标准对模块接口文件扩展名没有限制

  • Clang 使用 cppm
  • GCC 可以使用任何源文件扩展名
  • MSVC 使用 ixx

使用受标志 --experimental_cpp_modules 保护。

nocopts

字符串;默认值为 ""

从 C++ 编译命令中移除匹配的选项。 受 “Make”变量替换的约束。此属性的值会被解读为正则表达式。为了编译此规则,系统会从 COPTS 中移除与此正则表达式匹配的所有现有 COPTS(包括在规则的 copts 属性中明确指定的值)。在 third_party 之外,不需要使用此属性,也不能使用此属性。除了“Make”变量替换之外,系统不会以任何其他方式预处理这些值。
reexport_deps

标签列表;默认值为 []

stamp

整数;默认为 0

是否将 build 信息编码到二进制文件中。可能的值:
  • stamp = 1:始终将 build 信息戳入二进制文件,即使在 --nostamp build 中也是如此。应避免使用此设置,因为它可能会终止二进制文件以及依赖于它的所有下游操作的远程缓存。
  • stamp = 0:始终将 build 信息替换为常量值。这样可以实现良好的 build 结果缓存。
  • stamp = -1:build 信息的嵌入由 --[no]stamp 标志控制。

除非其依赖项发生变化,否则不会重新构建带有标记的二进制文件。

win_def_file

标签;默认值为 None

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

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

cc_toolchain

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

表示 C++ 工具链。

此规则负责:

  • 收集运行 C++ 操作所需的所有工件。这可以通过 all_filescompiler_fileslinker_files 或以 _files 结尾的其他属性来实现。这些通常是用于将所有必需文件括入文件群组的正则表达式。
  • 为 C++ 操作生成正确的命令行。这通过使用 CcToolchainConfigInfo 提供方来完成(详见下文)。

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

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

参数

属性
name

名称;必需

此目标的唯一名称。

all_files

标签;必填

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

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

ar_files

标签;默认值为 None

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

标签;默认值为 None

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

标签;必填

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

标签;默认值为 None

收集编译操作所需的所有 cc_toolchain 工件,以防支持输入发现(目前仅限 Google)。
coverage_files

标签;默认值为 None

涵盖覆盖率操作所需的所有 cc_toolchain 工件。如果未指定,则使用 all_files。
dwp_files

标签;必填

包含 dwp 操作所需的所有 cc_toolchain 工件集合。
dynamic_runtime_lib

标签;默认值为 None

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

在启用“static_link_cpp_runtimes”功能并动态关联依赖项时,系统会使用此参数。

exec_transition_for_inputs

布尔值;默认值为 False

已弃用。无操作。
libc_top

标签;默认值为 None

一系列 libc 工件,作为编译/链接操作的输入传递。
linker_files

标签;必填

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

标签;默认值为 None

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

标签;必填

包含 objcopy 操作所需的所有 cc_toolchain 工件集合。
output_licenses

字符串列表;默认值为 []

static_runtime_lib

标签;默认值为 None

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

在启用“static_link_cpp_runtimes”功能并静态关联依赖项时,系统会使用此参数。

strip_files

标签;必填

剥离操作所需的所有 cc_toolchain 工件集合。
supports_header_parsing

布尔值;默认值为 False

当 cc_toolchain 支持头文件解析操作时,设置为 True。
supports_param_files

布尔值;默认值为 True

当 cc_toolchain 支持使用 param 文件进行关联操作时,将其设置为 True。
toolchain_config

标签;必填

提供 cc_toolchain_config_info 的规则的标签。
toolchain_identifier

字符串;默认值为 ""

用于将此 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)

已废弃:该规则无效,并将被移除。

参数

属性
name

名称;必需

此目标的唯一名称。

fdo_prefetch_hints

查看规则源代码
fdo_prefetch_hints(name, compatible_with, deprecation, distribs, exec_compatible_with, exec_properties, features, profile, restricted_to, tags, target_compatible_with, testonly, toolchains, visibility)

表示工作区中的 FDO 预提取提示配置文件。示例:


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

参数

属性
name

名称;必需

此目标的唯一名称。

profile

标签;必填

提示个人资料的标签。提示文件的扩展名为 .afdo。该标签还可以指向 fdo_absolute_path_profile 规则。

fdo_profile

查看规则源代码
fdo_profile(name, compatible_with, deprecation, distribs, exec_compatible_with, exec_properties, features, memprof_profile, profile, proto_profile, restricted_to, tags, target_compatible_with, testonly, toolchains, visibility)

表示工作区中的 FDO 配置文件。 示例:


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

参数

属性
name

名称;必需

此目标的唯一名称。

memprof_profile

标签;默认值为 None

MemProf 配置文件的标签。配置文件应具有 .profdata 扩展名(对于编入索引/符号化的 memprof 配置文件),或者 .zip 扩展名(对于包含 memprof.profdata 文件的 ZIP 文件)。
profile

标签;必填

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

标签;默认值为 None

protobuf 配置文件的标签。

memprof_profile

查看规则源代码
memprof_profile(name, compatible_with, deprecation, distribs, exec_compatible_with, exec_properties, features, profile, restricted_to, tags, target_compatible_with, testonly, toolchains, visibility)

表示工作区中的 MEMPROF 配置文件。 示例:


memprof_profile(
    name = "memprof",
    profile = "//path/to/memprof:profile.afdo",
)

参数

属性
name

名称;必需

此目标的唯一名称。

profile

标签;必填

MEMPROF 配置文件的标签。配置文件应具有 .profdata 扩展名(对于编入索引/符号化的 memprof 配置文件),或者 .zip 扩展名(对于包含 memprof.profdata 文件的 ZIP 文件)。该标签还可以指向 fdo_absolute_path_profile 规则。

propeller_optimize

查看规则源代码
propeller_optimize(name, cc_profile, compatible_with, deprecation, distribs, exec_compatible_with, exec_properties, features, ld_profile, restricted_to, tags, target_compatible_with, testonly, toolchains, visibility)

表示工作区中的 Propeller 优化配置文件。 示例:


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

参数

属性
name

名称;必需

此目标的唯一名称。

cc_profile

标签;必填

传递给各种编译操作的配置文件的标签。此文件的扩展名为 .txt。
ld_profile

标签;必填

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