【问题标题】:"ambiguous symbol" in Bazel building C++Bazel 构建 C++ 中的“歧义符号”
【发布时间】:2023-04-01 22:40:01
【问题描述】:

背景

我正在使用 Bazel 使用 cl 编译 C++ 在 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.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: 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 的目标?

【问题讨论】:

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


    【解决方案1】:

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

    如需限制可见性,请查看the documentation

    对于 cc_library 规则,hdrs 中的标头构成库的公共接口,并且可以直接从库本身的 hdrs 和 srcs 中的文件以及 cc_* 规则的 hdrs 和 srcs 中的文件中包含他们部门的图书馆。 srcs 中的标头只能直接从库本身的 hdrs 和 srcs 中的文件中包含。

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

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

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

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

    【讨论】:

    • 我将所有 .h 文件从 hdrs 移动到 srcs,但出现与以前相同的错误。关于 icu::StringPiece,我不想在a.cc 中使用它,我想使用其他 StringPiece
    • icu_54?然后指定icu_54::StringPiece
    • 不,我想使用 cpp/src/strings/stringpiece。我不希望 icu stringpiece.h 对 a.cc 可见,但在构建 a.cc 时它需要对 schriter.h 可见。我使用带有target_include_directories(icucommon PRIVATE source/common) 的cmake 做到了这一点,但似乎无法使用Bazel 获得相同的结果。
    • 现在已解决。我认为根本问题是我们的项目在其#include 语句中使用了相对路径。我改变了它们所有的绝对路径,现在它不会尝试使用 icu_54::StringPiece 当它应该使用不同的 StringPiece。
    猜你喜欢
    • 1970-01-01
    • 2017-05-02
    • 2021-10-17
    • 1970-01-01
    • 2012-05-07
    • 1970-01-01
    • 1970-01-01
    • 2010-09-27
    • 2023-01-04
    相关资源
    最近更新 更多