C / C++ 規則

回報問題 查看來源 Nightly · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

規則

cc_binary

查看規則來源
cc_binary(name, deps, srcs, data, additional_linker_inputs, args, compatible_with, conlyopts, copts, cxxopts, defines, deprecation, dynamic_deps, env, exec_compatible_with, exec_group_compatible_with, exec_properties, features, hdrs_check, includes, licenses, link_extra_lib, linkopts, linkshared, linkstatic, local_defines, malloc, module_interfaces, nocopts, output_licenses, package_metadata, 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) 放入 deps,並在 linkopts 中參照這些指令碼,但請考慮該用途的 additional_linker_inputs
srcs

標籤清單;預設值為 []

處理後建立程式庫目標的 C 和 C++ 檔案清單。 這些是 C/C++ 來源和標頭檔案,可以是未產生 (一般來源程式碼) 或已產生。

系統會編譯所有 .cc.c.cpp 檔案。這些可能是產生的檔案:如果具名檔案位於其他規則的 outs 中,則這個 cc_library 會自動依附於該其他規則。

純組語檔案 (.s、.asm) 不會經過前置處理,通常是使用組語建構。預先處理的組語檔案 (.S) 會經過預先處理,通常是使用 C/C++ 編譯器建構。

系統不會編譯 .h 檔案,但這類檔案可供這項規則中的來源納入。.cc.h 檔案可以直接包含這些 srcs 或這項規則的 hdrs 中列出的標頭,或 deps 引數中列出的任何規則。

所有 #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
  • 「Always link」程式庫:.lo.pic.lo
  • 共用程式庫 (有版本或無版本):.so, .so.version
  • 物件檔案:.o.pic.o

... 和產生這些檔案的任何規則 (例如 cc_embed_data)。 根據 gcc 慣例,不同的副檔名代表不同的程式設計語言。

data

標籤清單;預設值為 []

這個程式庫在執行階段所需的檔案清單。 請參閱data 有關大多數建構規則定義的典型屬性的一般註解。

如果 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++ 連結器指令使用的依附元件。

deps 在概念上是為編譯和連結依附元件而設計,但 additional_linker_inputs 專為後者設計,並表示僅連結所需的依附元件 (例如 linkopts 中參照的檔案)。

舉例來說,這裡可以提供已編譯的 Windows .res 檔案,以便嵌入二進位目標。

conlyopts

字串清單;預設值為 []

將這些選項新增至 C 編譯指令。 須遵守「製作變數」替代和 Bourne Shell 權杖化
copts

字串清單;預設值為 []

將這些選項新增至 C/C++ 編譯指令。 須遵守「Make variable」替代和 Bourne shell 權杖化

這個屬性中的每個字串都會依指定順序新增至 COPTS,然後編譯二進位目標。這些標記只會對編譯這個目標生效,不會對其依附元件生效,因此請小心其他位置包含的標頭檔。所有路徑都應以工作區為基準,而非以目前的套件為基準。 這個屬性不應在 third_party 以外使用。

如果套件宣告 feature no_copts_tokenization,Bourne Shell 權杖化只會套用至由單一「Make」變數組成的字串。

cxxopts

字串清單;預設值為 []

將這些選項新增至 C++ 編譯指令。須遵守「製作變數」替代和 Bourne Shell 權杖化
defines

字串清單;預設值為 []

要新增至這個目標和所有相依目標的編譯行的定義清單。 須遵守「Make」變數替換和 Bourne Shell 權杖化。每個字串都必須由單一 Bourne Shell 符記組成,並以 -D 為前置字元,然後新增至這個目標的編譯指令列,以及每個依附於這個目標的規則。請務必謹慎操作,因為這可能會造成深遠影響,定義會新增至依附於這個目標的每個目標。如有疑問,請改為在 local_defines 中新增定義值。
dynamic_deps

標籤清單;預設值為 []

這些是目前目標依附的其他 cc_shared_library 依附元件。

cc_shared_library 實作會使用 dynamic_deps 清單 (遞移性,也就是目前目標的 dynamic_deps) 決定遞移性 deps 中不應連結的 cc_libraries,因為這些 cc_libraries 已由其他 cc_shared_library 提供。 dynamic_deps

hdrs_check

字串;預設值為 ""

已淘汰,不執行任何作業。
includes

字串清單;預設值為 []

要新增至編譯行的 include 目錄清單。 須視「建立變數」替代項目而定。 每個字串都會加上套件路徑,並透過「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_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++ 執行階段程式庫,請參閱下文) 仍會動態連結,沒有靜態程式庫的程式庫也是如此。因此產生的可執行檔仍會動態連結,因此只有大部分是靜態。

連結可執行檔的方法其實有三種:

  • STATIC (使用 fully_static_link 功能),所有項目都會靜態連結;例如「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 即可啟用這個模式。

如果 linkstatic 屬性或 fully_static_link 用於 features 以外的 //third_party,請在規則附近加入註解,說明原因。

如果用於 cc_library() 規則,linkstatic 屬性的意義會有所不同。如果是 C++ 程式庫,linkstatic=True 表示只允許靜態連結,因此不會產生 .so。linkstatic=False 不會阻止建立靜態程式庫。這項屬性是用來控制動態程式庫的建立作業。

在正式環境中,以 linkstatic=False 建構的程式碼應該很少。如果是 linkstatic=False,建構工具會在 *.runfiles 區域中,為所依附的共用程式庫建立符號連結。

local_defines

字串清單;預設值為 []

要新增至編譯行的定義清單。 須遵守「Make」變數替換和 Bourne Shell 權杖化。每個字串都必須由單一 Bourne Shell 符記組成,並以 -D 為前置字元,然後加入這個目標的編譯指令列,但不會加入其依附元件。與 defines 不同的是,定義只會新增至這個目標的編譯命令列。
malloc

標籤;預設值為 "@bazel_tools//tools/cpp:malloc"

覆寫 malloc 的預設依附元件。

根據預設,C++ 二進位檔會連結至 //tools/cpp:malloc,這是空白程式庫,因此二進位檔最終會使用 libc malloc。這個標籤必須參照 cc_library。如果編譯的不是 C++ 規則,這個選項就不會生效。如果指定 linkshared=True,系統會忽略這項屬性的值。

module_interfaces

標籤清單;預設值為 []

檔案清單會視為 C++20 模組介面。

C++ 標準對模組介面副檔名沒有限制

  • Clang use cppm
  • GCC 可以使用任何來源檔案副檔名
  • MSVC 使用 ixx

使用時須遵守 --experimental_cpp_modules 旗標的規定。

nocopts

字串;預設值為 ""

從 C++ 編譯指令中移除相符的選項。 須代入「Make」變數。這項屬性的值會解讀為規則運算式。凡是符合這項規則運算式的任何現有 COPTS (包括規則 copts 屬性中明確指定的值),都會從 COPTS 中移除,以編譯這項規則。這個屬性不應在 third_party 以外使用,也不應有此需求。除了「Make」變數替換之外,這些值不會經過任何前置處理。
reexport_deps

標籤清單;預設值為 []

stamp

整數;預設值為 -1

是否要將建構資訊編碼為二進位檔。可能的值包括:
  • stamp = 1:一律將建構資訊蓋印到二進位檔中,即使是 --nostamp 建構版本也一樣。應避免使用這項設定,因為這可能會終止二進位檔的遠端快取,以及任何依附於二進位檔的下游動作。
  • stamp = 0:一律以常數值取代建構資訊。這樣做可有效快取建構結果。
  • stamp = -1:建構資訊的嵌入作業由 --[no]stamp 標記控管。

除非依附元件有所變更,否則系統不會重建蓋章的二進位檔。

win_def_file

標籤;預設值為 None

要傳遞至連結器的 Windows DEF 檔案。

只有在 Windows 是目標平台時,才應使用這項屬性。 連結共用程式庫時,可用於 匯出符號

cc_import

查看規則來源
cc_import(name, deps, data, hdrs, alwayslink, compatible_with, deprecation, exec_compatible_with, exec_group_compatible_with, exec_properties, features, includes, interface_library, linkopts, objects, package_metadata, pic_objects, pic_static_library, restricted_to, shared_library, static_library, strip_include_prefix, 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 = True,
)
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 = 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 = True,
)
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 = True, # default value
)

# second will link to libmylib.so (or libmylib.lib)
cc_binary(
  name = "second",
  srcs = ["second.cc"],
  deps = [":mylib"],
  linkstatic = False,
)

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 有關大多數建構規則定義的典型屬性的一般註解。
hdrs

標籤清單;預設值為 []

這個預先編譯的程式庫發布的標頭檔案清單,可由依附規則中的來源直接納入。

布林值;預設值為 False

如果是 1,任何 (直接或間接) 依附於這個 C++ 預先編譯程式庫的二進位檔,都會連結靜態程式庫中封存的所有物件檔案,即使部分檔案不含二進位檔參照的符號也一樣。如果二進位檔中的程式碼未明確呼叫您的程式碼,例如您的程式碼註冊接收某項服務提供的某些回呼,這就很有用。

如果 alwayslink 無法在 Windows 上的 VS 2017 運作,這是已知問題,請將 VS 2017 升級至最新版本。

includes

字串清單;預設值為 []

要新增至編譯行的 include 目錄清單。 須視「建立變數」替代項目而定。 每個字串都會加上套件路徑,並透過「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

strip_include_prefix

字串;預設值為 ""

要從這項規則的標頭路徑中移除的前置字串。

設定後,即可在路徑中存取這項規則 hdrs 屬性中的標頭,但須先移除前置字串。

如果是相對路徑,系統會將其視為套件相對路徑。如果是絕對路徑,系統會解讀為存放區相對路徑。

在移除這個前置字元後,系統會將 include_prefix 屬性的前置字元加入其中。

這項屬性僅在 third_party 下合法。

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, exec_compatible_with, exec_group_compatible_with, exec_properties, features, hdrs_check, implementation_deps, include_prefix, includes, licenses, linkopts, linkstamp, linkstatic, local_defines, module_interfaces, package_metadata, restricted_to, strip_include_prefix, tags, target_compatible_with, testonly, textual_hdrs, toolchains, visibility, win_def_file)

使用 cc_library() 處理以 C++ 編譯的程式庫。 視需求而定,結果可能是 .so.lo.a

如果您使用靜態連結建構依附於 cc_library 的項目,依附元件程式庫規則的輸出內容就是 .a 檔案。如果指定 alwayslink=True,您會取得 .lo 檔案。

共用程式庫的實際輸出檔案名稱為 libfoo.so,其中 foo 是規則的名稱。其他種類的程式庫則分別以 .lo.a 結尾。如果需要特定共用程式庫名稱 (例如定義 Python 模組),請使用 genrule 將程式庫複製到所需名稱。

檢查是否包含標頭

建構作業中使用的所有標頭檔案都必須在 hdrssrcscc_* 規則中宣告。 這項規定會強制執行。

如果是 cc_library 規則,hdrs 中的標頭會組成程式庫的公開介面,可直接從程式庫本身的 hdrssrcs 檔案,以及 cc_* 規則的 hdrssrcs 檔案中納入,這些規則會在 deps 中列出程式庫。srcs 中的標頭只能直接從程式庫本身的 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.hbaz-impl.h
baz-impl.hbaz.h
baz.ccbaz.h baz-impl.h

納入檢查規則僅適用於直接納入的項目。在上述範例中,foo.cc 可包含 bar.h,而 bar.h 可能包含 baz.hbaz.h 則可包含 baz-impl.h。從技術上來說,.cc 檔案的編譯作業可能會遞移地包含 hdrssrcs 中任何 cc_library 的標頭檔案,而這些檔案位於遞移 deps 封閉中。在這種情況下,編譯器可能會在編譯 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 = True,
)

以下範例來自 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大多數建構規則定義的典型屬性」。

這些應該是 C++ 程式庫規則的名稱。 建構連結這個規則程式庫的二進位檔時,您也會連結 deps 中的程式庫。

雖然名稱為「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 或這項規則的 hdrs 中列出的標頭,或 deps 引數中列出的任何規則。

所有 #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
  • 「Always link」程式庫:.lo.pic.lo
  • 共用程式庫 (有版本或無版本):.so, .so.version
  • 物件檔案:.o.pic.o

... 和產生這些檔案的任何規則 (例如 cc_embed_data)。 根據 gcc 慣例,不同的副檔名代表不同的程式設計語言。

data

標籤清單;預設值為 []

這個程式庫在執行階段所需的檔案清單。 請參閱data 有關大多數建構規則定義的典型屬性的一般註解。

如果 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

標籤清單;預設值為 []

您可能想傳遞至編譯器命令列的其他檔案,例如清除程式忽略清單。然後,您可以使用 $(location) 函式,在 copts 中使用這裡指定的檔案。
additional_linker_inputs

標籤清單;預設值為 []

僅供 C++ 連結器指令使用的依附元件。

deps 在概念上是為編譯和連結依附元件而設計,但 additional_linker_inputs 專為後者設計,並表示僅連結所需的依附元件 (例如 linkopts 中參照的檔案)。

舉例來說,這裡可以提供已編譯的 Windows .res 檔案,以便嵌入二進位目標。

布林值;預設值為 False

如果為 1,任何 (直接或間接) 依附於這個 C++ 程式庫的二進位檔,都會連結 srcs 中列出的所有檔案物件檔案,即使部分檔案不含二進位檔參照的符號也一樣。如果二進位檔中的程式碼未明確呼叫您的程式碼,例如您的程式碼註冊接收某項服務提供的某些回呼,這就很有用。

如果 alwayslink 無法在 Windows 上的 VS 2017 運作,這是已知問題,請將 VS 2017 升級至最新版本。

conlyopts

字串清單;預設值為 []

將這些選項新增至 C 編譯指令。 須遵守「製作變數」替代和 Bourne Shell 權杖化
copts

字串清單;預設值為 []

將這些選項新增至 C/C++ 編譯指令。 須遵守「Make variable」替代和 Bourne shell 權杖化

這個屬性中的每個字串都會依指定順序新增至 COPTS,然後編譯二進位目標。這些標記只會對編譯這個目標生效,不會對其依附元件生效,因此請小心其他位置包含的標頭檔。所有路徑都應以工作區為基準,而非以目前的套件為基準。 這個屬性不應在 third_party 以外使用。

如果套件宣告 feature no_copts_tokenization,Bourne Shell 權杖化只會套用至由單一「Make」變數組成的字串。

cxxopts

字串清單;預設值為 []

將這些選項新增至 C++ 編譯指令。須遵守「製作變數」替代和 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

字串清單;預設值為 []

要新增至編譯行的 include 目錄清單。 須視「建立變數」替代項目而定。 每個字串都會加上套件路徑,並透過「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 中指定的 Linkopts 優先於規則 Linkopts。

請注意,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++ 執行階段程式庫,請參閱下文) 仍會動態連結,沒有靜態程式庫的程式庫也是如此。因此產生的可執行檔仍會動態連結,因此只有大部分是靜態。

連結可執行檔的方法其實有三種:

  • STATIC (使用 fully_static_link 功能),所有項目都會靜態連結;例如「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 即可啟用這個模式。

如果 linkstatic 屬性或 fully_static_link 用於 features 以外的 //third_party,請在規則附近加入註解,說明原因。

如果用於 cc_library() 規則,linkstatic 屬性的意義會有所不同。如果是 C++ 程式庫,linkstatic=True 表示只允許靜態連結,因此不會產生 .so。linkstatic=False 不會阻止建立靜態程式庫。這項屬性是用來控制動態程式庫的建立作業。

在正式環境中,以 linkstatic=False 建構的程式碼應該很少。如果是 linkstatic=False,建構工具會在 *.runfiles 區域中,為所依附的共用程式庫建立符號連結。

local_defines

字串清單;預設值為 []

要新增至編譯行的定義清單。 須遵守「Make」變數替換和 Bourne Shell 權杖化。每個字串都必須由單一 Bourne Shell 符記組成,並以 -D 為前置字元,然後加入這個目標的編譯指令列,但不會加入其依附元件。與 defines 不同的是,定義只會新增至這個目標的編譯命令列。
module_interfaces

標籤清單;預設值為 []

檔案清單會視為 C++20 模組介面。

C++ 標準對模組介面副檔名沒有限制

  • Clang use 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, dynamic_deps, exec_compatible_with, exec_group_compatible_with, exec_properties, exports_filter, features, package_metadata, 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_shared 會靜態連結 foobaz,後者是遞移依附元件。系統不會連結 bar,因為 dynamic_dep bar_shared 已動態提供該連結。

foo_shared 會使用連結器指令碼 *.lds 檔案,控管要匯出的符號。cc_shared_library 規則邏輯不會控管要匯出哪些符號,只會使用假設要匯出的內容,在分析階段中,如果兩個共用程式庫匯出相同的目標,就會顯示錯誤。

系統會假設 cc_shared_library 的每個直接依附元件都已匯出。因此,Bazel 會在分析期間假設 foo_shared 正在匯出 foobaz 不會由 foo_shared 匯出。系統也會假設 exports_filter 比對到的每個目標都已匯出。

範例中的每個 cc_library 最多只能出現在一個 cc_shared_library 中。如果我們也想將 baz 連結到 bar_shared,就需要在 baz 中加入 tags = ["LINKABLE_MORE_THAN_ONCE"]

由於 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_deps) 決定遞移性 deps 中不應連結的 cc_libraries,因為這些 cc_libraries 已由其他 cc_shared_library 提供。 dynamic_deps

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, exec_compatible_with, exec_group_compatible_with, exec_properties, features, package_metadata, restricted_to, tags, target_compatible_with, testonly, toolchains, visibility)
從目標清單及其轉換式依附元件產生靜態程式庫。

產生的靜態程式庫包含 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, dynamic_deps, env, env_inherit, exec_compatible_with, exec_group_compatible_with, exec_properties, features, flaky, hdrs_check, includes, licenses, link_extra_lib, linkopts, linkshared, linkstatic, local, local_defines, malloc, module_interfaces, nocopts, package_metadata, 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) 放入 deps,並在 linkopts 中參照這些指令碼,但請考慮該用途的 additional_linker_inputs
srcs

標籤清單;預設值為 []

處理後建立程式庫目標的 C 和 C++ 檔案清單。 這些是 C/C++ 來源和標頭檔案,可以是未產生 (一般來源程式碼) 或已產生。

系統會編譯所有 .cc.c.cpp 檔案。這些可能是產生的檔案:如果具名檔案位於其他規則的 outs 中,則這個 cc_library 會自動依附於該其他規則。

純組語檔案 (.s、.asm) 不會經過前置處理,通常是使用組語建構。預先處理的組語檔案 (.S) 會經過預先處理,通常是使用 C/C++ 編譯器建構。

系統不會編譯 .h 檔案,但這類檔案可供這項規則中的來源納入。.cc.h 檔案可以直接包含這些 srcs 或這項規則的 hdrs 中列出的標頭,或 deps 引數中列出的任何規則。

所有 #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
  • 「Always link」程式庫:.lo.pic.lo
  • 共用程式庫 (有版本或無版本):.so, .so.version
  • 物件檔案:.o.pic.o

... 和產生這些檔案的任何規則 (例如 cc_embed_data)。 根據 gcc 慣例,不同的副檔名代表不同的程式設計語言。

data

標籤清單;預設值為 []

這個程式庫在執行階段所需的檔案清單。 請參閱data 有關大多數建構規則定義的典型屬性的一般註解。

如果 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++ 連結器指令使用的依附元件。

deps 在概念上是為編譯和連結依附元件而設計,但 additional_linker_inputs 專為後者設計,並表示僅連結所需的依附元件 (例如 linkopts 中參照的檔案)。

舉例來說,這裡可以提供已編譯的 Windows .res 檔案,以便嵌入二進位目標。

conlyopts

字串清單;預設值為 []

將這些選項新增至 C 編譯指令。 須遵守「製作變數」替代和 Bourne Shell 權杖化
copts

字串清單;預設值為 []

將這些選項新增至 C/C++ 編譯指令。 須遵守「Make variable」替代和 Bourne shell 權杖化

這個屬性中的每個字串都會依指定順序新增至 COPTS,然後編譯二進位目標。這些標記只會對編譯這個目標生效,不會對其依附元件生效,因此請小心其他位置包含的標頭檔。所有路徑都應以工作區為基準,而非以目前的套件為基準。 這個屬性不應在 third_party 以外使用。

如果套件宣告 feature no_copts_tokenization,Bourne Shell 權杖化只會套用至由單一「Make」變數組成的字串。

cxxopts

字串清單;預設值為 []

將這些選項新增至 C++ 編譯指令。須遵守「製作變數」替代和 Bourne Shell 權杖化
defines

字串清單;預設值為 []

要新增至這個目標和所有相依目標的編譯行的定義清單。 須遵守「Make」變數替換和 Bourne Shell 權杖化。每個字串都必須由單一 Bourne Shell 符記組成,並以 -D 為前置字元,然後新增至這個目標的編譯指令列,以及每個依附於這個目標的規則。請務必謹慎操作,因為這可能會造成深遠影響,定義會新增至依附於這個目標的每個目標。如有疑問,請改為在 local_defines 中新增定義值。
dynamic_deps

標籤清單;預設值為 []

這些是目前目標依附的其他 cc_shared_library 依附元件。

cc_shared_library 實作會使用 dynamic_deps 清單 (遞移性,也就是目前目標的 dynamic_deps) 決定遞移性 deps 中不應連結的 cc_libraries,因為這些 cc_libraries 已由其他 cc_shared_library 提供。 dynamic_deps

hdrs_check

字串;預設值為 ""

已淘汰,不執行任何作業。
includes

字串清單;預設值為 []

要新增至編譯行的 include 目錄清單。 須視「建立變數」替代項目而定。 每個字串都會加上套件路徑,並透過「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_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++ 執行階段程式庫,請參閱下文) 仍會動態連結,沒有靜態程式庫的程式庫也是如此。因此產生的可執行檔仍會動態連結,因此只有大部分是靜態。

連結可執行檔的方法其實有三種:

  • STATIC (使用 fully_static_link 功能),所有項目都會靜態連結;例如「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 即可啟用這個模式。

如果 linkstatic 屬性或 fully_static_link 用於 features 以外的 //third_party,請在規則附近加入註解,說明原因。

如果用於 cc_library() 規則,linkstatic 屬性的意義會有所不同。如果是 C++ 程式庫,linkstatic=True 表示只允許靜態連結,因此不會產生 .so。linkstatic=False 不會阻止建立靜態程式庫。這項屬性是用來控制動態程式庫的建立作業。

在正式環境中,以 linkstatic=False 建構的程式碼應該很少。如果是 linkstatic=False,建構工具會在 *.runfiles 區域中,為所依附的共用程式庫建立符號連結。

local_defines

字串清單;預設值為 []

要新增至編譯行的定義清單。 須遵守「Make」變數替換和 Bourne Shell 權杖化。每個字串都必須由單一 Bourne Shell 符記組成,並以 -D 為前置字元,然後加入這個目標的編譯指令列,但不會加入其依附元件。與 defines 不同的是,定義只會新增至這個目標的編譯命令列。
malloc

標籤;預設值為 "@bazel_tools//tools/cpp:malloc"

覆寫 malloc 的預設依附元件。

根據預設,C++ 二進位檔會連結至 //tools/cpp:malloc,這是空白程式庫,因此二進位檔最終會使用 libc malloc。這個標籤必須參照 cc_library。如果編譯的不是 C++ 規則,這個選項就不會生效。如果指定 linkshared=True,系統會忽略這項屬性的值。

module_interfaces

標籤清單;預設值為 []

檔案清單會視為 C++20 模組介面。

C++ 標準對模組介面副檔名沒有限制

  • Clang use cppm
  • GCC 可以使用任何來源檔案副檔名
  • MSVC 使用 ixx

使用時須遵守 --experimental_cpp_modules 旗標的規定。

nocopts

字串;預設值為 ""

從 C++ 編譯指令中移除相符的選項。 須代入「Make」變數。這項屬性的值會解讀為規則運算式。凡是符合這項規則運算式的任何現有 COPTS (包括規則 copts 屬性中明確指定的值),都會從 COPTS 中移除,以編譯這項規則。這個屬性不應在 third_party 以外使用,也不應有此需求。除了「Make」變數替換之外,這些值不會經過任何前置處理。
reexport_deps

標籤清單;預設值為 []

stamp

整數;預設值為 0

是否要將建構資訊編碼為二進位檔。可能的值包括:
  • stamp = 1:一律將建構資訊蓋印到二進位檔中,即使是 --nostamp 建構版本也一樣。應避免使用這項設定,因為這可能會終止二進位檔的遠端快取,以及任何依附於二進位檔的下游動作。
  • stamp = 0:一律以常數值取代建構資訊。這樣做可有效快取建構結果。
  • stamp = -1:建構資訊的嵌入作業由 --[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, dwp_files, dynamic_runtime_lib, exec_compatible_with, exec_group_compatible_with, exec_properties, exec_transition_for_inputs, features, libc_top, licenses, linker_files, module_map, objcopy_files, output_licenses, package_metadata, 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 結尾的其他屬性。這些屬性最常見於檔案群組,會將所有必要檔案 globbing。
  • 為 C++ 動作產生正確的命令列。這項操作是使用 CcToolchainConfigInfo 提供者 (詳情請見下文) 完成。

使用 toolchain_config 屬性設定 C++ 工具鍊。 如需詳細的 C++ 工具鍊設定和工具鍊選取說明文件,請參閱 這個頁面

使用 tags = ["manual"],避免在叫用 bazel build //... 時不必要地建構及設定工具鍊

引數

屬性
name

名稱:必填

這個目標的專屬名稱。

all_files

標籤 (必填)

所有 cc_toolchain 構件的集合。這些構件會新增為所有 rules_cc 相關動作的輸入內容 (但使用下列屬性中更精確構件集的動作除外)。Bazel 假設 all_files 是所有其他提供構件的屬性 (例如,linkstamp 編譯需要編譯和連結檔案,因此會採用 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

用於模組化建構作業的模組地圖構件。
objcopy_files

標籤 (必填)

收集 objcopy 動作所需的所有 cc_toolchain 構件。
output_licenses

字串清單;預設值為 []

static_runtime_lib

標籤;預設值為 None

C++ 執行階段程式庫的靜態程式庫構件 (例如 libstdc++.a)。

啟用「static_link_cpp_runtimes」功能並靜態連結依附元件時,系統會使用這個值。

strip_files

標籤 (必填)

所有 strip 動作所需的 cc_toolchain 構件集合。
supports_header_parsing

布林值;預設值為 False

如果 cc_toolchain 支援標頭剖析動作,請設為 True。
supports_param_files

布林值;預設值為 True

如果 cc_toolchain 支援使用參數檔案進行連結動作,請設為 True。
toolchain_config

標籤 (必填)

提供 cc_toolchain_config_info 的規則標籤。
toolchain_identifier

字串;預設值為 ""

這個 ID 用於將這個 cc_toolchain 與對應的 crosstool_config.toolchain 相符。

在問題 #5380 修正前,建議您使用這種方式將 cc_toolchainCROSSTOOL.toolchain 建立關聯。這項屬性將由 toolchain_config 屬性 (#5380) 取代。

cc_toolchain_suite

查看規則來源
cc_toolchain_suite(name, compatible_with, deprecation, features, licenses, package_metadata, restricted_to, tags, target_compatible_with, testonly, toolchains, visibility)

已淘汰:這項規則不會執行任何作業,日後將移除。

引數

屬性
name

名稱:必填

這個目標的專屬名稱。

fdo_prefetch_hints

查看規則來源
fdo_prefetch_hints(name, compatible_with, deprecation, exec_compatible_with, exec_group_compatible_with, exec_properties, features, package_metadata, 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, exec_compatible_with, exec_group_compatible_with, exec_properties, features, memprof_profile, package_metadata, 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 檔案可使用下列其中一個副檔名:未編列索引的 LLVM 設定檔為 .profraw、已編列索引的 LLVM 設定檔為 .profdata、包含 LLVM profraw 設定檔的 .zip、AutoFDO 設定檔為 .afdo、XBinary 設定檔為 .xfdo。標籤也可以指向 fdo_absolute_path_profile 規則。
proto_profile

標籤;預設值為 None

protobuf 設定檔的標籤。

memprof_profile

查看規則來源
memprof_profile(name, compatible_with, deprecation, exec_compatible_with, exec_group_compatible_with, exec_properties, features, package_metadata, 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, exec_compatible_with, exec_group_compatible_with, exec_properties, features, ld_profile, package_metadata, 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。