從零學(xué)習(xí)構(gòu)造系統(tǒng)之bazel示例詳解
什么是bazel
Bazel 是一款與 Make、Maven 和 Gradle 類似的開源構(gòu)建和測(cè)試工具。 它使用人類可讀懂的高級(jí) build 語(yǔ)言。Bazel 支持使用多種語(yǔ)言的項(xiàng)目,并針對(duì)多個(gè)平臺(tái)構(gòu)建輸出。Bazel 支持跨多個(gè)代碼庫(kù)和大量用戶的大量代碼庫(kù)。
Bazel的基本概念
WORKSPACE file
在構(gòu)建項(xiàng)目之前,我們需要先設(shè)置工作區(qū),工作區(qū)的作用是存儲(chǔ)項(xiàng)目的源文件和Bazel的構(gòu)建輸出的目錄,其中WORKSPACE file就是將目錄及其內(nèi)容標(biāo)識(shí)為Bazel工作區(qū)的文件,需要位于項(xiàng)目目錄結(jié)構(gòu)的根目錄下,該文件可以為空,但是通常包含從網(wǎng)絡(luò)或者本地文件系統(tǒng)中提取其他依賴項(xiàng)的外部代碼庫(kù)聲明。
BUILD file
一個(gè)項(xiàng)目中包含一個(gè)或多個(gè)BUILD file,BUILD主要用于告知Bazel如何構(gòu)建項(xiàng)目,工作區(qū)包含一個(gè)BUILD文件的目錄就是一個(gè)軟件包。在之前的文章提到過(guò),Bazel是基于工件的構(gòu)建系統(tǒng),而工件就可以理解為Bazel根據(jù)Build文件中的編譯規(guī)則編譯該目錄下的文件形成的,軟件包可以包含子軟件包或包含BUILD文件的子目錄,從而形成軟件包的層次。
BUILD文件中包含了一些適用于Bazel的不同類型的指令,每個(gè)BUILD文件都需要包含至少一條規(guī)則(如cc_library)作為一組指令,以指示Bazel如何構(gòu)建所需要的輸出,例如可執(zhí)行文件或庫(kù)。BUILD文件中的每一個(gè)build規(guī)則實(shí)例都稱為目標(biāo),并指向一組特定的源文件和依賴項(xiàng),一個(gè)目標(biāo)也可以指向其他目標(biāo)。以下就是一個(gè)簡(jiǎn)單的BUILD文件的例子。
cc_binary( name = "hello-world", srcs = ["hello-world.cc"], )
在本示例中,hello-world 目標(biāo)會(huì)實(shí)例化 Bazel 的內(nèi)置 cc_binary rule。該規(guī)則會(huì)告知 Bazel 從 hello-world.cc 源文件構(gòu)建不含依賴項(xiàng)的獨(dú)立可執(zhí)行文件。
Bazel的C++事例
該例子是Bazel官方提供的,github地址為git clone github.com/bazelbuild/…
單個(gè)目標(biāo),單個(gè)軟件包
我們從最簡(jiǎn)單的例子開始,例子只包含一個(gè)源文件,需要將改源文件構(gòu)建成一個(gè)可執(zhí)行文件,其文件目錄如下。
examples └── cpp-tutorial └──stage1 ├── main │ ├── BUILD │ └── hello-world.cc └── WORKSPACE
BUILD文件內(nèi)容如下
load("@rules_cc//cc:defs.bzl", "cc_binary") cc_binary( name = "hello-world", srcs = ["hello-world.cc"], )
然后進(jìn)入該目錄cpp-tutorial/stage1,運(yùn)行以下命令構(gòu)建
bazel build //main:hello-world
會(huì)打印以下信息表示編譯成功
Starting local Bazel server and connecting to it... INFO: Analyzed target //main:hello-world (37 packages loaded, 255 targets configured). INFO: Found 1 target... Target //main:hello-world up-to-date: bazel-bin/main/hello-world INFO: Elapsed time: 28.089s, Critical Path: 2.78s INFO: 6 processes: 4 internal, 2 darwin-sandbox. INFO: Build completed successfully, 6 total actions
然后可以使用以下命令測(cè)試,會(huì)打印Hello world
bazel-bin/main/hello-world
其依賴關(guān)系如下
單個(gè)軟件包,多個(gè)目標(biāo)
雖然單個(gè)目標(biāo)足以滿足小型項(xiàng)目的需求,在實(shí)際的開發(fā)過(guò)程中可能需要將較大的項(xiàng)目拆分為多個(gè)目標(biāo)和軟件包。這樣可以實(shí)現(xiàn)快速增量構(gòu)建(即 Bazel 僅重建更改的內(nèi)容,并通過(guò)一次性構(gòu)建項(xiàng)目的多個(gè)部分來(lái)加快構(gòu)建速度。在教程的這一階段,您將添加目標(biāo),然后添加軟件包。
下面的BUILD文件會(huì)告訴Bazel先構(gòu)建hello-greet庫(kù)(使用Bazel內(nèi)置的cc_library)然后構(gòu)建hello-world二進(jìn)制文件,其中的deps屬性告訴Bazel構(gòu)建hello-world需要hello-greet庫(kù)。
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library") cc_library( name = "hello-greet", srcs = ["hello-greet.cc"], hdrs = ["hello-greet.h"], ) cc_binary( name = "hello-world", srcs = ["hello-world.cc"], deps = [ ":hello-greet", ], )
編譯情況如下
INFO: Analyzed target //main:hello-world (36 packages loaded, 258 targets configured). INFO: Found 1 target... Target //main:hello-world up-to-date: bazel-bin/main/hello-world INFO: Elapsed time: 15.548s, Critical Path: 2.39s INFO: 8 processes: 4 internal, 4 darwin-sandbox. INFO: Build completed successfully, 8 total actions
如果現(xiàn)在修改 hello-greet.cc 并重新構(gòu)建項(xiàng)目,Bazel 只會(huì)重新編譯該文件,編譯結(jié)果如下(通過(guò)-s選項(xiàng)可以打印具體編譯過(guò)程)
INFO: Analyzed target //main:hello-world (0 packages loaded, 0 targets configured). INFO: Found 1 target... SUBCOMMAND: # //main:hello-greet [action 'Compiling main/hello-greet.cc', configuration: a42135a42aad3da7e3af209ce54745fb0d0306dc29e1f3dc84d7d58372421fc9, execution platform: @local_config_platform//:host] (cd /private/var/tmp/_bazel_qiming/e4d33fbb5ee1f924b3cb079f19abf4eb/execroot/__main__ && \ exec env - \ APPLE_SDK_PLATFORM=MacOSX \ APPLE_SDK_VERSION_OVERRIDE=13.1 \ PATH=/Users/qiming/Library/Caches/bazelisk/downloads/bazelbuild/bazel-6.0.0-darwin-x86_64/bin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin \ XCODE_VERSION_OVERRIDE=14.2.0.14C18 \ ZERO_AR_DATE=1 \ external/local_config_cc/wrapped_clang_pp '-D_FORTIFY_SOURCE=1' -fstack-protector -fcolor-diagnostics -Wall -Wthread-safety -Wself-assign -fno-omit-frame-pointer -O0 -DDEBUG '-std=c++11' 'DEBUG_PREFIX_MAP_PWD=.' -iquote . -iquote bazel-out/darwin-fastbuild/bin -MD -MF bazel-out/darwin-fastbuild/bin/main/_objs/hello-greet/hello-greet.d '-DBAZEL_CURRENT_REPOSITORY=""' '-frandom-seed=bazel-out/darwin-fastbuild/bin/main/_objs/hello-greet/hello-greet.o' -isysroot __BAZEL_XCODE_SDKROOT__ -F__BAZEL_XCODE_SDKROOT__/System/Library/Frameworks -F__BAZEL_XCODE_DEVELOPER_DIR__/Platforms/MacOSX.platform/Developer/Library/Frameworks -no-canonical-prefixes -pthread -no-canonical-prefixes -Wno-builtin-macro-redefined '-D__DATE__="redacted"' '-D__TIMESTAMP__="redacted"' '-D__TIME__="redacted"' -target x86_64-apple-macosx13.1 -c main/hello-greet.cc -o bazel-out/darwin-fastbuild/bin/main/_objs/hello-greet/hello-greet.o) # Configuration: a42135a42aad3da7e3af209ce54745fb0d0306dc29e1f3dc84d7d58372421fc9 # Execution platform: @local_config_platform//:host Target //main:hello-world up-to-date: bazel-bin/main/hello-world INFO: Elapsed time: 0.750s, Critical Path: 0.58s INFO: 2 processes: 1 internal, 1 darwin-sandbox. INFO: Build completed successfully, 2 total actions
其中依賴如下圖
多個(gè)軟件包,多個(gè)目標(biāo)
在包含多個(gè)軟件包的情況下又該如何編譯呢?其結(jié)構(gòu)如下:
└──stage3 ├── main │ ├── BUILD │ ├── hello-world.cc │ ├── hello-greet.cc │ └── hello-greet.h ├── lib │ ├── BUILD │ ├── hello-time.cc │ └── hello-time.h └── WORKSPACE
lib目錄下的BUILD文件如下
load("@rules_cc//cc:defs.bzl", "cc_library") cc_library( name = "hello-time", srcs = ["hello-time.cc"], hdrs = ["hello-time.h"], visibility = ["http://main:__pkg__"], )
main目錄下的BUILD文件如下
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library") cc_library( name = "hello-greet", srcs = ["hello-greet.cc"], hdrs = ["hello-greet.h"], ) cc_binary( name = "hello-world", srcs = ["hello-world.cc"], deps = [ ":hello-greet", "http://lib:hello-time", ], )
主軟件包中的 hello-world 目標(biāo)依賴于 lib 軟件包中的 hello-time 目標(biāo)(因此是目標(biāo)標(biāo)簽 //lib:hello-time)- Bazel 通過(guò) deps 屬性知道這一點(diǎn)。依賴項(xiàng)圖中反映了這一點(diǎn):
為了順利構(gòu)建,請(qǐng)使用可見性屬性使 lib/BUILD 中的 //lib:hello-time 目標(biāo)明確對(duì) main/BUILD 中的目標(biāo)可見。這是因?yàn)槟J(rèn)情況下,目標(biāo)僅對(duì)同一 BUILD 文件中的其他目標(biāo)可見。Bazel 使用目標(biāo)可見性來(lái)防止出現(xiàn)包含實(shí)現(xiàn)細(xì)節(jié)的庫(kù)泄露到公共 API 等問(wèn)題。
最后
這篇文章主要介紹了構(gòu)造系統(tǒng)bazel的簡(jiǎn)單使用,更多關(guān)于bazel構(gòu)造系統(tǒng)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Opencv基于CamShift算法實(shí)現(xiàn)目標(biāo)跟蹤
這篇文章主要為大家詳細(xì)介紹了Opencv基于CamShift算法實(shí)現(xiàn)目標(biāo)跟蹤,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01C++超詳細(xì)講解模擬實(shí)現(xiàn)vector
這篇文章主要介紹了C++ 容器 Vector 的使用方法,Vector 是一個(gè)能夠存放任意類型的動(dòng)態(tài)數(shù)組,有點(diǎn)類似數(shù)組,是一個(gè)連續(xù)地址空間,下文更多詳細(xì)內(nèi)容的介紹,需要的小伙伴可以參考一下2022-07-07基于C++實(shí)現(xiàn)簡(jiǎn)單的日期計(jì)算機(jī)
這篇文章主要為大家詳細(xì)介紹了如何基于C++實(shí)現(xiàn)簡(jiǎn)單的日期計(jì)算機(jī),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-04-04C語(yǔ)言實(shí)現(xiàn)推箱子游戲的地圖編輯器
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)推箱子游戲的地圖編輯器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-02-02一起來(lái)學(xué)習(xí)C++中remove與erase的理解
這篇文章主要為大家詳細(xì)介紹了C++的remove與erase,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2022-03-03C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單航班管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單航班管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-12-12C++項(xiàng)目基于HuffmanTree實(shí)現(xiàn)文件的壓縮與解壓縮功能
這篇文章主要介紹了C++項(xiàng)目基于HuffmanTree實(shí)現(xiàn)文件的壓縮與解壓縮功能,本文給大家提到文件壓縮的概念介紹及壓縮方法,通過(guò)示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2021-08-08