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

C++ 是否有解决未定义参考/未解决符号问题的一般准则?,c++,reference,undefined,symbols,C++,Reference,Undefined,Symbols,我在工作中遇到了几个“未定义的引用”(链接期间)和“未解析的符号”(dlopen之后的运行期间)问题。这是一个相当大的makefile系统 是否有链接库和使用编译器标志/选项来避免这些类型错误的一般规则和指南?设置一个生成系统,其中X依赖于Y,而Y依赖于Z有助于。当你进入圆圈(Z取决于X)时,事情就会变得丑陋 通常是顺序库被链接(“-lZ-lY-lX”vs“-lX-lY-lZ”)导致了悲伤。更罕见的是,您在搜索路径上的多个位置都有相同的库名称,或者您针对尚未重新编译的过时版本的链接 “nm--d

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


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

设置一个生成系统,其中X依赖于Y,而Y依赖于Z有助于。当你进入圆圈(Z取决于X)时,事情就会变得丑陋

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

“nm--demangle”可以让您看到事物的定义/使用位置

“ldd”可用于查看您所依赖的动态库

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


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

可以设置makefile系统,以便:

  • 如果模块=D取决于模块A、B和C
  • 然后尝试使module=D将首先生成模块A、B和C
  • 更重要的是,module=D将自动确定其库(-lA等)、库路径(-lA)以及模块A、B和C的makefile中的包含路径(-IA)
这可能会有点麻烦。上次我这样做时,我倾向于只缓存信息,而不是分叉过多的make子进程。再加上makefile导入和一点perl脚本来删除重复项。克鲁奇,我知道。(当权者不想在基础设施上花费时间。)但这是可以做到的

同样,我使用的是GNU make,它有一些扩展。

如果您使用的是MSVC: 您无法通过设置标志来避免此类错误:这意味着某些单元(.cpp)没有声明标识符的定义。这肯定是由于缺少include或缺少对象定义(通常是静态对象)造成的

在开发过程中,您可以遵循这些指导原则(从),以确保您的所有cpp包括他们需要的所有标题,但不包括更多:

  • 每个cpp文件首先包括自己的头文件。这是最重要的 重要方针;其他一切 从这里开始。唯一的例外 与此规则对应的是预编译头 包括在VisualStudio中;那些 始终必须是第一个包含在 档案。关于预编译的更多信息 本文第二部分中的标题
  • 头文件必须包括解析它所需的所有头文件。 这与第一个问题密切相关 指南我知道有些人试图 不要在文件中包含头文件 声称效率或可用性的头文件 沿着这些路线的东西。然而, 如果文件必须包含在 头文件可以被解析,它必须 被包括在某个地方。优势 将其直接包含在标题中 文件是我们随时可以决定的 输入我们感兴趣的头文件 我们保证它会 按原样工作。我们不必玩游戏 “猜猜你还需要什么标题” 游戏
  • 头文件应具有最小数量的头文件 需要解析它。前 规则说你应该拥有所有的 在头文件中包含所需的内容。 这条规则说你不应该吃任何东西 比你必须做的还要多。显然,开始吧 通过删除(或不在 第一名)包括 声明。然后,使用尽可能多的转发 尽可能地声明,而不是 包括。如果你所拥有的只是 类的引用或指针,您可以 不需要包括该类的 头文件;未来参考将 做得好,效率更高

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

从所述问题来看,他有链接排序问题。这不是一个.ccp->.o问题。它是-lA-lB vs-lB-lA。更改周围的头文件不会有任何区别。除非他从未定义过“未定义/未解析”元素,否则更改代码不会有帮助!固定的。mrree>我没有意识到这一点,但在阅读了您的答案后,我了解到这是一个特定于g++的问题(或makefile系统问题)?我更习惯于MSVC编译器,这些完全相同的错误也会发生,所以我可能误解了,因为它们有相同的描述?也许。我不熟悉MSVC编译器的错误。但当他提到“链接期间”和“dlopen之后的运行期间”时,我认为这是库的常见错误排序。看:我明白了,那么我应该补充一点,如果是在MSVC的情况下,这是我的答案。一旦Micheal在问题中添加精确性,我将删除此答案。