c++ - Bazel 构建 C++ 中的 "ambiguous symbol"

标签 c++ visual-c++ build bazel cl

背景

我正在使用 Bazel 构建 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.hb/cpp/src/strings/stringpiece.h 都有 class StringPiecethird_party/icu/source/common/unicode/stringpiece.hclass 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:无法打开包含文件:'unicode/utypes.h':没有这样的文件或目录

如果我将 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:无法打开包含文件:'unicode/utypes.h':没有这样的文件或目录

如果我改为添加 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 编译得很好,所以我不需要更改源代码。如何更改构建文件以正确构建此构建?如何让 icu 中的所有内容访问 unicode 中的 header ,但不将 unicode/stringpiece.h 暴露给依赖于 的目标icu?

最佳答案

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

要限制可见性,请查看 the documentation :

For cc_library rules, headers in hdrs comprise the public interface of the library and can be directly included both from the files in hdrs and srcs of the library itself as well as from files in hdrs and srcs of cc_* rules that list the library in their deps. Headers in srcs must only be directly included from the files in hdrs and srcs of the library itself.

这意味着 hdrs 定义了可传递的可见 header ,而 srcs 用于“私有(private)” header 。

然而,正如文档进一步指出的那样,这并不总是能够完美执行:

Unfortunately Bazel currently cannot distinguish between direct and transitive inclusions, so it cannot detect error cases where a file illegally includes a header directly that is only allowed to be included transitively. For example, Bazel would not complain if in the example above foo.cc directly includes baz.h. This would be illegal, because foo does not directly depend on baz.

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

关于c++ - Bazel 构建 C++ 中的 "ambiguous symbol",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45601780/

相关文章:

c++ - 在类中使用 static_assert - 如何?

c++ - 单例析构函数没有被调用?

c++ - 将 2 字节十六进制转换和分离为两个字符,高两个十六进制转到一个字符,低两个十六进制转到 C++ 中的第二个字符

c++ - Q : C++ - Reversing a string (sentence and word) using a class

ios - Unity 在 iPhone 上的 GetCloudProjectId() 崩溃

c++ - Std 或 boost atomic unsigned char[32]

c++ - 如何在 Messagebox 中显示变量+文本? Winapi32 C++

c++ - 如何在C++概念中定义emplace_back和其他可变参数模板函数?

recursion - 如何在 NuSpec 文件中递归地包含目录

jenkins - 在 Jenkins 中设置构建状态