使用絕對路徑
包含的路徑是相對于工作區(qū)的根路徑。假設(shè)有以下的目錄結(jié)構(gòu):
[workspace]/
WORKSPACE
a/
BUILD
a.h
a.cc
b/
BUILD
b.h
b.cc
main.cc
如果b/main.cc
需要包含b.h
頭文件择份,我們需要?jiǎng)?chuàng)建以下的b/BUILD
文件:
cc_library(
name = "b",
srcs = ["b.cc"],
hdrs = ["b.h"],
)
cc_binary(
name = "main",
srcs = ["main.cc"],
deps = [":b"],
)
b/main.cc
可以這樣包含b.h
:
#include "b/b.h"
上面的頭文件包含路徑是相對于工作區(qū)根目錄的相對路徑菠赚。如果b/main.cc
還要依賴a/a.h
頭文件的話等太,我們還需要添加a/BUILD
文件:
cc_library(
name = "a",
srcs = ["a.cc"],
hdrs = ["a.h"],
visibility = ["http://b:__pkg__"],
)
然后我們在b/BUILD
添加依賴關(guān)系:
cc_binary(
name = "main",
srcs = ["main.cc"],
deps = [
":b",
"http://a",
],
)
b/main.cc
代碼中也包含了a/a.h
頭文件:
#include "a/a.h"
b/main.cc
就可以正常使用a/a.h
或b/b.h
中導(dǎo)出的符號了右核。
依賴傳遞
如果包含了一個(gè)頭文件半哟,那么需要將頭文件對應(yīng)的庫添加到依賴中溉苛。不過镜廉,只需有添加直接依賴的庫。假設(shè)三明治對應(yīng)的sandwich.h
文件包含了面包對應(yīng)的bread.h
文件愚战,同時(shí)bread.h
又包含了面粉對應(yīng)的flour.h
文件娇唯。但是,三明治sandwich.h
文件并沒有直接包含面粉flour.h
文件(三明治用戶當(dāng)然不關(guān)心面粉的事情)寂玲,因此BUILD文件可以這樣:
cc_library(
name = "sandwich",
srcs = ["sandwich.cc"],
hdrs = ["sandwich.h"],
deps = [":bread"],
)
cc_library(
name = "bread",
srcs = ["bread.cc"],
hdrs = ["bread.h"],
deps = [":flour"],
)
cc_library(
name = "flour",
srcs = ["flour.cc"],
hdrs = ["flour.h"],
)
上面表示了sandwich
三明治庫依賴bread
面包庫塔插,bread
又依賴flour
對應(yīng)的面粉庫。
添加頭文件包含路徑
很多時(shí)候你可能并不希望基于工作區(qū)根路徑的相對路徑來包含每個(gè)頭文件拓哟。因?yàn)楹芏嘁呀?jīng)存在的第三方庫的頭文件包含方式并不是基于工作區(qū)的根路徑想许。假設(shè)有以下目錄結(jié)構(gòu):
[workspace]/
WORKSPACE
third_party/
some_lib/
include/
some_lib.h
BUILD
some_lib.cc
Bazel希望用third_party/some_lib/include/some_lib.h
方式包含some_lib.h
,但是some_lib.cc
可能跟希望用"include/some_lib.h"
方式包含彰檬。為了使得包含路徑有效伸刃,需要在third_party/some_lib/BUILD
文件中將some_lib/
目錄添加到頭文件包含路徑的搜索列表中:
cc_library(
name = "some_lib",
srcs = ["some_lib.cc"],
hdrs = ["some_lib.h"],
copts = ["-Ithird_party/some_lib"],
)
這對于依賴的外部第三方庫特別有效,因?yàn)榭梢员苊庠陬^文件路徑中出現(xiàn)無關(guān)的external/[repository-name]/
前綴逢倍。
包含外部庫:一個(gè)例子
假設(shè)使用了 Google Test捧颅。可以在WORKSPACE
文件中使用new_
開頭的倉庫相關(guān)的函數(shù)较雕,下載依賴的GTest代碼到當(dāng)前倉庫中:
new_http_archive(
name = "gtest",
url = "https://googletest.googlecode.com/files/gtest-1.7.0.zip",
sha256 = "247ca18dd83f53deb1328be17e4b1be31514cedfc1e3424f672bf11fd7e0d60d",
build_file = "gtest.BUILD",
)
創(chuàng)建gtest.BUILD
文件碉哑,對應(yīng)Google Test的構(gòu)建配置文件挚币。配置文件中有幾個(gè)需要特別注意的地方:
-
gtest-1.7.0/src/gtest-all.cc
文件已經(jīng)采用#include
語法包含了gtest-1.7.0/src/
目錄中其它*.cc
文件,因此需要將它排除在外(也可以只包含它一個(gè)文件扣典,但是需要正確配置包含路徑)妆毕。 - 它的頭文件在
gtest-1.7.0/include/
目錄,需要將它添加到頭文件包含路徑列表中 - GTest依賴
pthread
多線程庫贮尖,通過linkopt
選項(xiàng)指定笛粘。
最終的規(guī)則大概是這樣:
cc_library(
name = "main",
srcs = glob(
["gtest-1.7.0/src/*.cc"],
exclude = ["gtest-1.7.0/src/gtest-all.cc"]
),
hdrs = glob([
"gtest-1.7.0/include/**/*.h",
"gtest-1.7.0/src/*.h"
]),
copts = [
"-Iexternal/gtest/gtest-1.7.0/include"
],
linkopts = ["-pthread"],
visibility = ["http://visibility:public"],
)
這是有點(diǎn)混亂:所有以gtest-1.7.0
為前綴的其實(shí)都是生成的臨時(shí)文件。我們可以通過new_http_archive
函數(shù)中的strip_prefix
屬性來忽略它:
new_http_archive(
name = "gtest",
url = "https://googletest.googlecode.com/files/gtest-1.7.0.zip",
sha256 = "247ca18dd83f53deb1328be17e4b1be31514cedfc1e3424f672bf11fd7e0d60d",
build_file = "gtest.BUILD",
strip_prefix = "gtest-1.7.0",
)
現(xiàn)在gtest.BUILD
簡潔多了:
cc_library(
name = "main",
srcs = glob(
["src/*.cc"],
exclude = ["src/gtest-all.cc"]
),
hdrs = glob([
"include/**/*.h",
"src/*.h"
]),
copts = ["-Iexternal/gtest/include"],
linkopts = ["-pthread"],
visibility = ["http://visibility:public"],
)
現(xiàn)在cc_
相關(guān)的規(guī)則可以通過//external:gtest/main
引用GTest了湿硝。
例如:我們可以創(chuàng)建以下測試:
#include "gtest/gtest.h"
TEST(FactorialTest, Negative) {
EXPECT_EQ(1, 1);
}
創(chuàng)建對應(yīng)的BUILD文件:
cc_test(
name = "my_test",
srcs = ["my_test.cc"],
copts = ["-Iexternal/gtest/include"],
deps = ["@gtest//:main"],
)
使用bazel test
命令運(yùn)行測試薪前。
依賴預(yù)編譯的庫
如果要依賴一個(gè)已經(jīng)編譯好的庫(可能只有頭文件和對應(yīng)的*.so
庫文件),可以使用cc_library
規(guī)則包裝一個(gè)庫對象:
cc_library(
name = "mylib",
srcs = ["mylib.so"],
hdrs = ["mylib.h"],
)
其它的目標(biāo)就可以依賴這個(gè)包裝的庫對象了关斜。