是否有解决未定义参考/未解决符号问题的一般准则?

Posted

技术标签:

【中文标题】是否有解决未定义参考/未解决符号问题的一般准则?【英文标题】:Are there general guidelines for solving undefined reference/unresolved symbol issues? 【发布时间】:2010-10-04 06:14:49 【问题描述】:

我在工作的地方遇到了几个“未定义的引用”(链接期间)和“未解析的符号”(dlopen 之后的运行时)问题。这是一个相当大的makefile系统。

是否有链接库和使用编译器标志/选项来规避此类错误的一般规则和指南?

【问题讨论】:

【参考方案1】:

如果您使用的是 MSVC:

您不能通过设置标志来规避此类错误:这意味着某些单元 (.cpp) 没有'已声明标识符的定义。这肯定是由于某处缺少包含或缺少对象定义(通常是静态对象)造成的。

在开发过程中,您可以遵循这些指南(来自 those articles),以确保您的所有 cpp 都包含他们需要的所有标头,但仅此而已:

每个 cpp 文件首先包含自己的头文件。这是最 重要的指导方针;其他一切 从这里开始。唯一的例外 到这个规则是预编译头 包含在 Visual Studio 中;那些 总是必须是第一个包含在 文件。更多关于预编译 本文第二部分的标题。 头文件必须包含解析它所需的所有头文件。 这与第一个齐头并进 指导方针。我知道有些人试图 永远不要在其中包含头文件 声称效率的头文件或 类似的东西。然而, 如果一个文件必须在 头文件可以解析,它必须 被包含在某处。优势 将其直接包含在标题中 文件是我们总是可以决定 拉入我们感兴趣的头文件 并且我们保证它会 按原样工作。我们不必玩 “猜猜你需要什么其他标题” 游戏。 一个头文件应该有最少数量的头文件 有必要解析它。以前的 规则说你应该拥有所有 在头文件中包含您需要的内容。 这条规则说你不应该有任何 超过你必须的。很明显,开始 通过删除(或不添加 第一名)无用的包括 陈述。然后,使用尽可能多的转发 尽可能声明,而不是 包括。如果你只有 类的引用或指针,你 不需要包括那个类' 头文件;前向参考将 做得更好,效率更高。

但正如评论者所建议的,您似乎正在使用 g++...

【讨论】:

从所述问题来看,他有链接排序问题。这不是 .ccp->.o 问题。这是 -lA -lB 与 -lB -lA。更改头文件不会有任何区别。除非他从未定义过“未定义/未解析”元素,否则更改代码将无济于事。 可怕> 哎呀!固定的。 mrree> 我不知道,但在阅读了您的回答后,我知道这是一个 g++ 特定问题(或 makefile 系统问题)?我更习惯于 MSVC 编译器,并且也可能发生完全相同的错误,所以也许我误解了,因为它们具有相同的 desc? 也许吧。我不熟悉 MSVC 编译器错误。但是当他提到“在链接期间”和“在 dlopen 之后的运行时”时,我认为这是库的常见错误排序。见:***.com/questions/492374/… 我明白了,那么我应该补充一点,如果是在 MSVC 的情况下,这是我的答案。 Micheal 在问题中添加精确度后,我将立即删除此答案。【参考方案2】:

建立一个 X 依赖于 Y 而依赖于 Z 的构建系统会有所帮助。当你进入圈子(Z 取决于 X)时,事情就会变得丑陋。

通常是订单库被链接(“-lZ -lY -lX”与“-lX -lY -lZ”)导致悲伤。更罕见的是,您在搜索路径的多个位置有相同的库名称,或者链接到尚未重新编译的过时版本。

"nm --demangle" 可以让您查看定义/使用事物的位置。

"ldd" 可用于查看您依赖的动态库。

gcc/g++ 标志 -print-file-name=LIBRARY 可以帮助准确追踪正在使用的库。


事后思考:(因为您询问规则/指南。)

可以设置一个 makefile 系统:

如果 module=D 依赖于模块 A、B 和 C。 然后尝试制作 module=D 将首先制作模块 A、B 和 C。 而且,更重要的是,module=D 会自动确定其库(-lA 等)、库路径 (-LA) 以及来自模块 A、B 和 C 的 makefile 的包含路径 (-IA)。李>

设置起来可能有点麻烦。上次我这样做时,我倾向于只缓存信息而不是分叉过多的 make 子进程。再加上 makefile-importing 和一个小的 perl 脚本来删除重复项。克鲁奇,我知道。 (那些不想花时间在基础设施上的权力。)但这是可以做到的。

再一次,我使用的是 GNU-make,它有一些扩展。

【讨论】:

以上是关于是否有解决未定义参考/未解决符号问题的一般准则?的主要内容,如果未能解决你的问题,请参考以下文章

什么是未定义的引用/未解决的外部符号错误,我该如何解决?

什么是未定义的引用/未解决的外部符号错误,我该如何解决?

什么是未定义的引用/未解决的外部符号错误,我该如何解决?

什么是未定义的引用/未解决的外部符号错误,我该如何解决?

什么是未定义的引用/未解决的外部符号错误,我该如何解决?

什么是未定义的引用/未解决的外部符号错误,我该如何解决?