我在使用cl的Windows构建中使用cl来编译C ++。
third_party/icu/source/common/unicode/schriter.h
third_party/icu/source/common/unicode/utypes.h
third_party/icu/source/common/unicode/stringpiece.h
third_party/icu/source/common/stringpiece.cpp
third_party/icu/BUILD
a/a.cc
a/a.h
a/BUILD
b/cpp/src/strings/stringpiece.h
b/cpp/src/util/uri_utils.h
b/BUILD
schriter.h
有#include "unicode/utypes.h"
。
uri_utils.h
和b/cpp/src/strings/stringpiece.h
都有class StringPiece
。 third_party/icu/source/common/unicode/stringpiece.h
有class U_COMMON_API StringPiece : public UMemory
a.cc
是指StringPiece
,其中包括:
#include "b/cpp/util/uri_utils.h"
#include "strings/stringpiece.h"
#include "third_party/icu/source/common/unicode/schriter.h"
a/BUILD
cc_library(
name = "a",
srcs = ["a.cc"],
hdrs = ["a.h"],
deps = [
"//third_party/icu:common",
"//b:sdk_strings",
],
)
b/BUILD
cc_library(
name = "sdk_strings",
srcs = [
"cpp/util/uri_utils.cc",
"cpp/src/strings/stringpiece.cc"
],
hdrs = [
"cpp/util/uri_utils.h",
"cpp/src/strings/stringpiece.h",
],
includes = ["cpp/src"],
)
third_party/icu/BUILD
cc_library(
name = "common",
srcs = [
"source/common/stringpiece.cpp",
"source/stubdata/stubdata.c",
],
hdrs = glob(["**/*.h"]),
)
按原样,构建third_party/icu:common
失败:
third_party/icu/source/stubdata/stubdata.c(20): fatal error C1083: Cannot open include file: 'unicode/utypes.h': No such file or directory
如果我将copts = ["/Ithird_party/icu/source/common",],
添加到third_party/icu/BUILD
,那么icu:common
构建但目标a
会失败:
third_party/icu/source/common/unicode/schriter.h(21): fatal error C1083: Cannot open include file: 'unicode/utypes.h': No such file or directory
如果我添加includes = ["source/common",],
,那么icu:common
版本,但目标a
会失败:
a/a.cc(168): error C2872: 'StringPiece': ambiguous symbol
b/cpp/util/uri_utils.h(24): note: could be 'StringPiece'
third_party\icu\source\common\unicode/stringpiece.h(52): note: or 'icu_54::StringPiece'
使用cmake编译源代码很好,所以我不需要更改源代码。如何更改BUILD文件以使此构建正确?如何让icu
中的所有内容访问unicode
中的标题,但不将[{1}}公开给依赖unicode/stringpiece.h
的目标?
答案 0 :(得分:1)
您应该能够添加命名空间(icu::StringPiece
,我猜?)来解决C2872错误。
要限制知名度,请查看the documentation:
对于cc_library规则,hdrs中的标头包含库的公共接口,可以直接包含在hdrs中的文件和库本身的srcs中,也可以直接包含在hdrs中的文件和包含列出的cc_ *规则的srcs中的文件中。图书馆在他们的deps。 srcs中的标题只能直接包含在库本身的hdrs和srcs中的文件中。
这意味着hdrs
定义了可传递的标题,srcs
代表“私有”标题。
然而,正如文档进一步指出的那样,这并不总是能够完美地实施:
不幸的是,Bazel目前无法区分直接和传递包含,因此它无法检测到文件非法包含直接标题的错误情况,只允许传递包含。例如,如果在上面的例子中fzel.cc直接包含baz.h,Bazel就不会抱怨。这将是非法的,因为foo并不直接依赖于baz。
因此,它应该阻止除了最有决心的用户之外的所有用户将其放入具有srcs
选项的私有目标的copts = ['-Ithird_party/icu/source/common']
。