1

背景

我在使用 cl 编译 C++ 的 Bazel 构建 Windows。

文件子集:

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 StringPiecethird_party/icu/source/common/unicode/stringpiece.hclass U_COMMON_API StringPiece : public UMemory

a.ccStringPiece并具有这些包括:

#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,但不暴露unicode/stringpiece.h给依赖的目标icu

4

1 回答 1

1

您应该能够添加命名空间(icu::StringPiece我猜?)来解决 C2872 错误。

要限制可见性,请查看文档

对于 cc_library 规则,hdrs 中的头文件构成了库的公共接口,并且可以直接包含在 hdrs 和库本身的 srcs 中的文件中,也可以从在其列表中列出库的 cc_* 规则的 hdrs 和 srcs 中的文件中包含部门。srcs 中的标头只能直接从库本身的 hdrs 和 srcs 中的文件中包含。

这意味着hdrs定义可传递可见的标头并srcs用于“私有”标头。

但是,正如文档进一步指出的那样,这并不总是可以完美执行:

不幸的是,Bazel 目前无法区分直接包含和传递包含,因此它无法检测文件非法直接包含仅允许传递包含的标头的错误情况。例如,如果在上面的示例中 foo.cc 直接包含 baz.h,Bazel 不会抱怨。这将是非法的,因为 foo 不直接依赖于 baz。

因此,除了最坚定的用户之外,它应该阻止所有用户将其放入srcs带有copts = ['-Ithird_party/icu/source/common']选项的私有目标中。

于 2017-08-10T17:24:05.347 回答