c++ - Bazel 链接器未找到函数定义
问题描述
在尝试添加 Bazel 构建文件以在 ICU 中构建 gennorm2 工具方面,我已经取得了相当大的进展。这是我使用 Bazel target进行中的 PR//icu4c/source/tools/gennorm2
。
我目前在运行这些错误时遇到bazelisk build //icu4c/source/tools/gennorm2 --verbose_failures --sandbox_debug
了困难。
它们引用定义在urename.h
. 据我了解,它urename.h
也用于通过附加带有版本号 ( _68
) 的后缀来重命名某些函数,但我定义了一个预处理器常量U_DISABLE_RENAMING
来禁用该特定行为。这只会改变错误输出中未定义函数名称的名称,但不会改变它(例如:错误现在抱怨u_errorName
而不是u_errorName_68
)。
令我困惑的部分是为什么错误输出声称找不到这些符号。如您所见,目标//icu4c/source/tools/gennorm2
取决于//icu4c/source/common:platform
,而后者又取决于,其中包括应该匹配
//icu4c/source/common:headers
的字段。hdrs = glob(["unicode/*.h", "unicode/*.h",])
/icu4c/source/common/unicode/urename.h
如果有帮助,这是使用当前基于 autotools 的 configure + make build 在重新检出 ICU时运行时的详细日志输出。make VERBOSE=1
解决方案
一位队友能够查看并帮助我解决错误并最终修复它们。
第一件事是承认它确实是一个链接器错误,这可以通过注意到错误消息引用链接器程序ld
来看到。
这很重要,因为我们之前在调试编译配置时花时间在错误的地方,就好像问题发生在链接器阶段之前的编译阶段一样。(但我了解了调试编译问题的一种方法是使用 给出的原始 GCC 命令--verbose_failures --sandbox_debug
并将其替换-c
为/tmp 中的 .txt 文件-E
并将其更改为-o
/tmp 中的 .txt 文件,以保存编译器在所有包含后对该文件看到的输出是递归内联的)。这意味着我通过为编译阶段指定预处理器定义来解决问题的尝试被误导了。
该项目关于依赖项的文档显示,我错误地指定了对其中一个目标的依赖项,仅指定标头 ( //icu4c/source/common:headers
) 而不是相关的定义和标头 ( //icu4c/source/common:platform
)。
之后,我们解决了另一个小而有趣的问题。gennorm2
目标取决于获取当前年份的代码(例如:用于打印包含年份范围的版权声明的帮助消息)。作为一个 i18n 库,ICU 在//icu4c/source/i18n:icu4ci18n
. 这会为一个孤立的用例创建过多的代码依赖项(并将导致后续工作出现问题),因此我们将gennorm2
调用那些日历年 fns ( ucal_open
, ucal_getNow
, ucal_setMillis
, ucal_get
, ucal_close
) 的代码块替换为 libc 日期库函数给我们年份作为数字,并添加linkopts = ["-ldl"]
到dl
日期库中的链接。
推荐阅读
- python - Fuzzywuzzy 匹配来自 Python 中不同数据帧的多列
- bitnami - 文件下载 URL 从 Bitnami Canvas LMS 中的公共 IP 地址更改为本地 IP 地址
- python - 使用数学技巧找出一个数字是否是一个完美的正方形
- xtext - 通过 Xtext 编辑器更新 Sirius 图
- hazelcast - Hazelcast VersionedPortalble 的使用
- jquery - AJAX响应后如何通过jQuery设置表单
- spring-boot - 具有多个模块的 Spring 数据不起作用
- python - 当我使用 Bootstrap 的模式时,我的 Django 表单没有呈现
- c# - 将 WCF SOAP 和 WCF REST 服务托管为 Azure 应用服务
- c++ - 如何在 C++ 中的每个嵌套循环的新列中打印输出?