Bazel 使用总结

#Rules

1. cc_binary

  • name : Required ,A unique name for this target.

  • deps : List of labels; optional; The list of other libraries to be linked in to the binary target.

  • srcs : List of labels; optional

    1. 用于生成target的C/C++文件,包括头文件和源文件,可以是非生成的或者生成的

    2. 所有.cc,.c和.cpp文件都将被编译。 这些可能是生成的文件:如果一个命名文件在”其他规则”的outs中,则该规则将自动依赖于该“其他规则”。

    3. .h文件不会被编译,但是可以被该规则中的sources(源文件)包含。 .cc和.h文件都可以直接包含srcs中列出的头文件,或deps参数中列出的任何规则的hdrs中列出的头文件。

    4. 所有#include的文件必需在该规则的srcs,或者引用的cc_library的hdrs参数中提及

    5. 推荐的风格是,所有与库关联的头文件在库的hdrs中列出,所有剩下的与该规则的sources(源文件)关联的头文件在srcs中列出。

    6. 如果一个规则名称在srcs中,则本规则自动依赖于srcs中的规则。 如果命名规则的输出是C或C ++源文件,则将它们编译到该规则中去; 如果它们是库文件,则将它们链接在一起。

    7. 允许的文件类型

      1. C and C++ source files: .c, .cc, .cpp, .cxx, .c++, .C
      2. C and C++ header files: .h, .hh, .hpp, .hxx, .inc, .inl, .H
      3. Assembler with C preprocessor: .S
      4. Archive: .a, .pic.a
      5. “Always link” library: .lo, .pic.lo
      6. Shared library, versioned or unversioned: .so, .so.*version*
      7. Object file: .o, .pic.o

      以及产生这些文件的所有规则。 根据gcc约定,不同的扩展名表示不同的编程语言。

  • additional_linker_inputs: List of labels; optional;Pass these files to the C++ linker command.

  • copts : List of strings; optional

    将这些选项添加到C ++编译命令。在编译二进制目标之前,将此属性中的每个字符串都以给定的顺序添加到COPTS中。 这些标志仅对编译目标有效,而对它的依赖项无效,因此请注意其他位置包含的头文件。 所有路径都应相对于工作空间,而不是相对于当前包。

  • defines : List of strings; optional

    要添加到编译命令行的定义列表。 每个字符串,必须由单个Bourne shell token组成,都以-D开头,并添加到该目标以及依赖于此目标的所有规则的编译命令行中。 请非常小心,因为这可能会产生深远的影响。 如有疑问,请将定义值添加到local_defines中。

  • includes : List of strings; optional

    要添加到编译命令行的包含目录列表。每个字符串都以-isystem开头,并添加到COPTS中。 与COPTS不同,这些标志是为此规则以及依赖于此规则的每个规则添加的。 (注意:不是它所依赖的规则!)请非常小心,因为这可能会产生深远的影响。 如有疑问,请在COPTS上添加“ -I”标志。

    必须将头文件添加到srcs或hdrs中,否则在使用沙箱(默认设置)进行编译时,依赖的规则将无法使用该头文件

  • linkopts : List of strings; optional

    将这些标志添加到C ++链接器命令。 链接二进制目标之前,将此属性中的每个字符串都添加到LINKOPTS中。 列表中每个不以$或-开头的元素均假定为deps中target的label。 这些target生成的文件列表将附加到链接器选项。 如果label无效或未在deps中声明,则会报告错误。

  • linkshared : Boolean; optional; nonconfigurable; default is False

    ​ 创建一个共享库。要启用此属性,请在规则中包含linkshared = True。默认情况下,此选项处于关闭状态。如果启用它,则必须为某些有意义的foo值命名二进制libfoo.so(或目标平台上库的命名约定)。 ​ 此标志的存在意味着与-shared标志被加到gcc,并且所生成的共享库适合装入例如Java程序中。但是,出于构建目的,它永远不会链接到依赖它的二进制文件中,因为假定使用cc_binary规则构建的共享库仅由其他程序手动加载,因此不应视其为cc_library规则的替代。为了实现可伸缩性,我们建议完全避免使用这种方法,而只是让java_library依赖cc_library规则。

    ​ 如果同时指定linkopts = [‘-static’]和linkshared = True,则会得到一个完全自包含的单元。如果同时指定linkstatic = 1和linkshared = True,则将得到一个单一的,几乎是自包含的单元。

  • linkstatic: Boolean; optional; default is True

    ​ 对于cc_binary和cc_test:以静态模式链接二进制文件。 对于cc_library.linkstatic:请参见下文。 默认情况下,此选项对cc_binary启用,对其他禁用。

    ​ 如果启用并且是binary或test,则此选项告诉构建工具在可能的情况下以.a(而不是.so)链接到用户库。 某些系统库仍可能是动态链接的,没有静态库的库也是如此。 因此,生成的可执行文件仍将动态链接,大部分是静态链接。

    链接可执行文件的方法实际上有三种:

    1. STATIC,带有fully_static_link特性,其中所有内容都是静态链接的;例如“ gcc -static foo.o libbar.a libbaz.a -lm”。通过在features属性中指定fully_static_link启用此模式。

    2. STATIC,其中所有用户库都是静态链接的(如果有可用的静态版本),而系统库(不包括C / C ++运行时库)是动态链接的,例如“ gcc foo.o libfoo.a libbaz.a -lm”。通过指定linkstatic = True启用此模式。

    3. DYNAMIC,其中所有库都动态链接(如果有可用的动态版本),例如“ 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

    要添加到编译命令行的定义列表。 每个字符串,必须由单个Bourne shell token组成,都以-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 ++编译命令中删除匹配的选项。 此属性的值解释为正则表达式。 与该正则表达式匹配的所有现有COPTS(包括在规则的copts属性中显式指定的值)都将从COPTS中删除,以编译此规则。 很少需要此属性。

  • stamp : Integer; optional; default is -1

    启用链接标记。 是否将构建信息编码为二进制文件。 可能的值: stamp = 1:将构建信息标记到二进制文件中。 带标记的二进制文件仅在其依赖项更改时才重建。 如果有依赖于构建信息的测试,请使用此选项。 stamp = 0:始终用恒定值替换构建信息。 这样可以很好地缓存构建结果。 stamp = -1:构建信息的嵌入由”–[no]stamp”标志控制。

  • win_def_file : Label; optional

    Windows DEF文件将传递给链接器。 仅当Windows是目标平台时,才应使用此属性。 在链接共享库期间,可用于导出符号。

2. cc_import

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

以下是典型的用例:

  1. Linking a static library
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,
)
  1. Linking a shared library (Unix)
cc_import(
  name = "mylib",
  hdrs = ["mylib.h"],
  shared_library = "libmylib.so",
)
  1. Linking a shared library with interface library (Windows)
cc_import(
  name = "mylib",
  hdrs = ["mylib.h"],
  # mylib.lib is a 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",
)
  1. Linking a shared library with “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,
)
  1. Linking to static or shared library

On 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,
)

On 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,
)

Arguments

  • name : Name, Required, A unique name for this target.

  • hdrs : List of labels; optional

    此预编译的库发布的头文件列表,将直接由相关规则中的源包含在内。

  • alwayslink : Boolean; optional; default is False

    如果为1,则任何(直接或间接)依赖于此C ++预编译库的二进制文件将链接静态库中存档的所有目标文件,即使某些文件不包含该二进制文件引用的符号。 如果您的代码未被二进制中的代码显式调用,例如当您的代码注册为接收某些服务提供的回调时,这将非常有用。 如果Alwayslink在Windows上的VS 2017上不起作用,那是由于已知问题,请将VS 2017升级到最新版本。

  • interface_library : label, optional 用于链接共享库的单个接口库。Permitted file types: .ifso, .tbd, .lib, .so or .dylib

  • shared_library: label, optional单个预编译的共享库,Bazel确保在运行时依赖于它的二进制文件可以使用它。

    Permitted file types: .so, .dll or .dylib

  • static_library: label, optional,A single precompiled static library.Permitted file types: .a, .pic.a or .lib

  • system_provided:Boolean; optional; default is False;

    If 1, it indicates the shared library required at runtime is provided by the system. In this case, interface_library should be specified andshared_library should be empty.

cc_library

头文件包含检测

必须在cc_ *规则的hdrs或srcs中声明构建中使用的所有头文件。 这是强制性的。

对于cc_library规则,hdrs中的头文件构成了库的公共接口,可以直接包含在库本身的hdrs和srcs中的文件中,如果cc_ *规则在其deps中列出了该库,也可以直接包含在cc_ *规则的hdrs和srcs中的文件中。 srcs中的头文件只能直接包含在库本身的hdrs和srcs中的文件中。 在决定将头文件放入hdrs还是srcs时,应询问您是否希望该库的使用者能够直接包含它。 这与在编程语言中的公共可见性和私有可见性之间大致相同。

cc_binary和cc_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.h和bar.h,但不能包含baz.h。

Including file Allowed inclusions
foo.h bar.h
foo.cc foo.h bar.h
bar.h bar-impl.h baz.h
bar-impl.h bar.h baz.h
bar.cc bar.h bar-impl.h baz.h
baz.h baz-impl.h
baz-impl.h baz.h
baz.cc baz.h baz-impl.h

包含检查规则仅适用于直接包含。在上面的示例中,允许foo.cc包含bar.h,其中可能包含baz.h,而后者又包含baz-impl.h。从技术上讲,.cc文件的编译可能传递包含deps依赖链中任何cc_library中的hdrs或srcs中的任何头文件。在这种情况下,编译器在编译foo.cc时可以读取baz.h和baz-impl.h,但是foo.cc不得包含#include“ baz.h”。为此,必须将baz添加到foo的dep中。

不幸的是,Bazel当前无法区分直接包含和传递包含,因此无法检测错误情况,即文件非法直接包含那些仅允许传递包含的头文件。例如,如果在上面的示例中foo.cc直接包含baz.h,Bazel不会抱怨。这将是非法的,因为foo不直接依赖baz。当前,在这种情况下不会产生任何错误,但是将来可能会添加这种错误检查。

Arguments

  • name : Name,required, a unique name for this target

  • deps : list of labels, optional

    要链接到二进制目标的其他库的列表。这些可以是cc_library或objc_library目标。

  • srcs : list of labels, optional; 与cc_binary的srcs定义相同,参考上文

  • hdrs:list of labels, optional

    此库发布的头文件列表,这些文件将直接由依赖它的规则中的sources包含在内。 这是用于声明描述库接口的头文件的首选位置。 这些头文件可被包含在本规则或依赖规则中;不应由该库的客户端包含的头文件应改为在srcs属性中列出,即使它们被发布的接口头文件包含。

  • alwayslink : Boolean; optional; default is False

    如果为1,则任何(直接或间接)依赖于此C ++库的二进制文件将会链接srcs中列出的文件对应的obj文件,即使某些文件不包含该二进制文件引用的符号。 如果您的代码未被二进制中的代码显式调用,例如当您的代码注册为接收某些服务提供的回调时,这将非常有用。

  • copts : list of strings ; optional; 参考cc_binary的该选项

  • defines : list of strings ; optional;参考cc_binary的该选项

  • include_prefix: string, optional;

    添加到此规则的头文件路径的前缀。设置后,此规则的hdrs属性中的头文件可通过以下方式访问:该属性的值位于其相对于存储库的相对路径之前。在添加该前缀之前,将删除strip_include_prefix属性中的前缀。

  • includes : list of strings, optional; 参考cc_binary的该选项

  • linkopts : list of string optional ; 参考cc_binary的该选项

  • link_static: 参考cc_binary

  • local_defines: 参考cc_binary

  • nocopts: 参考cc_binary

  • strip_include_prefix: String; optional

    要从此规则的头文件路径中剥离的前缀。设置后,此规则的hdrs属性中的头文件可通过文件路径去除该前缀的方式访问。如果是相对路径,则将其视为相对于软件包的路径。 如果它是绝对路径,则将其理解为相对于存储库的路径。删除该前缀后,将添加include_prefix属性中的前缀。

  • textual_hdrs : list of labels, optional

    此库发布的头文件列表,这些文件将以文本形式包含在依赖本规则的规则的sources中。 这是用于声明无法自行编译的头文件的位置; 也就是说,始终需要在文本上将它们包含在其他源文件中以构建有效的代码。

  • win_def_file : label ;optional 参考cc_binary

3. cc_proto_library

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

deps必须指向proto_library规则。

Example:

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, unique name of this target
  • deps : List of labels; optional; 为其生成C ++代码的proto_library规则列表。

4. cc_test

以下属性全部参考cc_binary

  • name
  • deps
  • srcs
  • additional_linker_inputs
  • copts
  • defines
  • includes
  • linkopts
  • linkstatic
  • local_defines
  • malloc
  • nocopts
  • stamp
  • win_def_file

5. cc_toolchain

表示一个C ++工具链。

该规则负责:

  • 收集运行C ++动作所需的所有工件。 这是通过诸如all_files,compiler_files,linker_files或其他以_files结尾的属性来完成的。 这些是最常见的文件组,遍历所有必需的文件。
  • 为C ++操作生成正确的命令行。 这是使用CcToolchainConfigInfo 提供者完成的(下面有详细信息)。

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

argument

  • name : Name, required, a unique name of this target

  • all_files: label, required

    所有cc_toolchain工件的集合。 这些工件将作为所有rule_cc相关动作的输入添加(使用下面的属性来描述更精确的工件集的动作除外)。 Bazel假设all_files是所有其他”提供工件的属性”的超集(例如,linkstamp编译需要编译和链接文件,因此需要all_files)。 这就是cc_toolchain.files所包含的内容,并且所有使用C ++工具链的Starlark规则都使用它。

  • ar_files: label, optional; 归档操作所需的所有cc_toolchain工件的集合。

  • as_files: label, optional ; assembly 操作所需的所有cc_toolchain工件的集合。

  • compiler: String; optional; nonconfigurable

    不推荐使用。 请改用toolchain_identifier属性。 在CROSSTOOL迁移到Starlark之后,它将不再使用,并将由#7075删除。 设置后,它将用于执行crosstool_config.toolchain选择。 它优先于–cpu Bazel选项。

  • compiler_files : label, required

    编译操作所需的所有cc_toolchain工件的集合。 当前,仅由lto_backend操作使用,常规编译操作使用all_files(#6927)。

  • compiler_files_without_includes : label, optional

    如果支持输入发现(当前仅Google),则为编译操作所需的所有cc_toolchain工件的集合。

  • coverage_files : label, optional

    coverage操作所需的所有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”功能时将使用此功能,并且动态链接依赖项。

  • libc_top: label, optional

    libc的工件集合,作为编译/链接操作的输入传递。

  • linker_files : label , required,

    链接动作所需的所有cc_toolchain工件的集合。

  • module_map: Label; optional

    用于模块化构建的模块映射工件。

  • objcopy_files: Label; required

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

  • static_runtime_lib: Label; optional

    C ++运行时库的静态库工件(例如libstdc ++.a)。 启用“ static_link_cpp_runtimes”功能时,将使用此功能,并且我们将静态链接依赖项。

  • strip_files: Label; required

    strip操作所需的所有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_toolchain与CROSSTOOL.toolchain关联的推荐方法。 它将由toolchain_config属性(#5380)代替。

6. cc_toolchain_suite

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

该规则负责:

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

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

Arguments

  • name
  • toolchains: Dictionary mapping strings to labels; required; nonconfigurable

A map from “" or "|" strings to a cc_toolchain label. "" will be used when only --cpu is passed to Bazel, and "|" will be used when both —cpu and --compiler

are passed to Bazel. Example:

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