为什么在定义变量和链接库时"undefined reference"?
Why "undefined reference" when the variable is defined and the library is linked?
我们有一些应用程序链接到我们自己的几个库。我最近添加了一个链接到这些库的新应用程序,该应用程序在Windows上成功编译。
但是,在 Linux 上,我看到对静态变量的"未定义引用"错误,这当然意味着未定义该变量。该错误发生在库中,但仅在链接到新应用程序时(现有应用程序仍可正常链接(。
如您所见,编译器说kAppVersion
是未定义的。当它实际上是在 Version.cpp 中定义的,并且 common 是链接的(在 CMakeLists.txt 中指定(。我们认为这可能与target_link_libraries
排序有关,但common
移动到base
之前(发生错误的位置(似乎没有效果。此外,在其他CMakeList中.txt(例如,为了协同作用(,排序似乎无关紧要,因为此应用程序已成功编译。这个类似的问题似乎暗示了排序很重要,但我在这方面没有任何成功:
问题:库已链接,但引用未定义
我唯一的想法是,在 synergyd.cpp 或 CDaemonApp 中可能有问题.cpp但我看不到任何在 Linux 上编译而不是 Windows 上的
明显东西。Scanning dependencies of target synergyd
[ 90%] Building CXX object src/cmd/synergyd/CMakeFiles/synergyd.dir/synergyd.o
Linking CXX executable ../../../../../bin/debug/synergyd
../../../../../lib/debug/libarch.a(CArch.o): In function `~XExitApp':
/srv/buildbot/synergy/1.4-linux32/build/src/lib/arch/../synergy/XSynergy.h:114: undefined reference to `vtable for XExitApp'
../../../../../lib/debug/libarch.a(CArch.o): In function `CArchAppUtil::exitApp(int)':
/srv/buildbot/synergy/1.4-linux32/build/src/lib/arch/CArchAppUtil.h:31: undefined reference to `XExitApp::XExitApp(int)'
/srv/buildbot/synergy/1.4-linux32/build/src/lib/arch/CArchAppUtil.h:31: undefined reference to `typeinfo for XExitApp'
../../../../../lib/debug/libarch.a(CArchAppUtilUnix.o): In function `CArchAppUtilUnix::parseArg(int const&, char const* const*, int&)':
/srv/buildbot/synergy/1.4-linux32/build/src/lib/arch/CArchAppUtilUnix.cpp:32: undefined reference to `CApp::isArg(int, int, char const* const*, char const*, char const*, int)'
/srv/buildbot/synergy/1.4-linux32/build/src/lib/arch/CArchAppUtilUnix.cpp:37: undefined reference to `CApp::isArg(int, int, char const* const*, char const*, char const*, int)'
../../../../../lib/debug/libbase.a(CLog.o): In function `CLog::insert(ILogOutputter*, bool)':
/srv/buildbot/synergy/1.4-linux32/build/src/lib/base/CLog.cpp:213: undefined reference to `kAppVersion'
collect2: ld returned 1 exit status
make[2]: *** [../../bin/debug/synergyd] Error 1
make[1]: *** [src/cmd/synergyd/CMakeFiles/synergyd.dir/all] Error 2
make: *** [all] Error 2
完整的代码可以从我们的存储库中浏览。
真正的问题:arch
和synergy
之间的循环库依赖关系。此外,base
实际上没有链接到common
库(在 CMakeList 中.txt base
(。
有趣的是,这是由库的 CMakeLists.txt 文件中的配置问题引起的。这与CMakeLists无关.txt对于我添加的新synergyd
应用程序。
问题是我没有将库相互链接,其中新调用被添加到其他库中的类。但是,现在似乎存在循环链接的问题。
例如,我本可以添加...
if (UNIX)
target_link_libraries(arch synergy)
endif()
。到 CMakeLists.txt在arch
库中,就像arch
现在在synergy
库中调用某些内容一样。但这是无效的,因为synergy
已经在arch
中调用了某些东西.
显然,这在Windows上无关紧要。
我不太确定是什么原因导致这种情况开始发生,因为它都是以前编译良好的旧代码,并且在其他应用程序中仍然如此。我怀疑很可能与最近从 CArch 中删除样板有关,而不是 CDaemonApp 正在做的事情(甚至可能是两者的结合(。
更新
以防万一有人关心 ;-( - 我认为这与 arch
和 synergy
之间糟糕的循环库依赖关系有关,再加上CDaemonApp.cpp
不包括CApp.h
的事实 - 这意味着它包含在其他点,导致奇怪的未定义引用错误。
为了正确解决这个问题,我删除了循环依赖,这似乎是问题的核心。
更新 2
代码现在完全编译,万岁!
我仍然看到最后一个错误(这个问题的主题(:
[ 90%] Building CXX object src/cmd/synergyd/CMakeFiles/synergyd.dir/synergyd.o
Linking CXX executable ../../../../../bin/debug/synergyd
../../../../../lib/debug/libbase.a(CLog.o): In function `CLog::insert(ILogOutputter*, bool)':
/home/nick/Projects/synergy/branches/1.4/src/lib/base/CLog.cpp:213: undefined reference to `kAppVersion'
collect2: ld returned 1 exit status
make[2]: *** [../../bin/debug/synergyd] Error 1
make[1]: *** [src/cmd/synergyd/CMakeFiles/synergyd.dir/all] Error 2
make: *** [all] Error 2
这仅仅是由于base
库未链接到common
库造成的。将以下代码添加到 CMakeLists.txt 文件以修复此问题:
if (UNIX)
target_link_libraries(base common)
endif()
仍然不确定为什么开始发生这种情况,只是很高兴它已修复。
更新 3
这是提交:r1354
首先,链接的顺序确实很重要,至少对于 g++ 来说是这样。如果A
使用B
中的符号,那么B
应该在A
:g++ ... -lA -lB
之后提及
我也看到了一个undefined reference to vtable for XExitApp
.此错误表示您在XExitApp
中有一个未定义的虚拟函数。如果您不想定义该函数,请通过添加= 0
使其成为纯虚拟
我唯一注意到的是你缺少"../../lib/synergy"在/synergyd/CMakeLists.txt
的set(inc...
部分中。这是否与问题有关,我只能猜测。
您收到的所有链接错误似乎是由于链接器找不到它正在寻找的符号。这样做的常见原因是相关的 .o 文件不存在、未包含在构建中或编译不正确。
我将首先清理,更改 CMakeList.txt 文件以尽可能匹配已知的工作版本,并在打开所有编译器/警告的情况下重建所有内容。如果这不起作用(相同的错误或不同的错误(,我会更仔细地查看哪些有效,哪些无效。你说Windows版本有效,但Linux版本不行。两者之间有什么区别,其中哪些可以解释这个问题。与一个正确构建的类似项目类似:两个项目之间有什么区别。
- 我的项目不会像"undefined reference to `grpc::g_core_codegen_interface'"那样使用未定义的引用错误进行编译
- Visual Studio Code "undefined reference to `WinMain@16'"
- 使用 MATLAB 编码器生成C++代码:编译错误"undefined reference to `rgb2gray_tbb_real64'"
- 为什么创建友元类的实例会导致"undefined reference to"错误?
- Tensorflow c++ api undefined reference to 'tflite::D efaultErrorReporter()'
- 为什么在使用 SDL2 时仍然收到'undefined reference'链接器错误?
- OpenCV undefined reference to 'cv::imread(cv::String const&, int)'
- Libcurl c++ "undefined reference to" (Windows/MinGW/g++)
- 尝试使用 extern "C" 调用 C 中的C++方法,得到"undefined reference to"对象的链接器错误
- build error : undefined reference to `yyFlexLexer::yyFlexLex
- 安卓 NDK 制造。数百"undefined reference error"
- 当我尝试进行TPC-E测试时,实用程序抱怨"undefined reference"
- 声明和定义函数静态会产生"undefined reference to function_name()"
- C++ : "undefined reference to"可能是因为CMake文件
- 包含<iostream>时"Undefined reference"错误
- CMake 'undefined reference' CERN-ROOT 的错误
- 生成错误:"cannot find target for file"和"undefined reference"
- AppData\Local\Temp\cc59LXDc.o:test1.cpp: undefined reference to 'constructNewObjectOfClass
- YAML-cpp 编译错误:"undefined reference to YAML::LoadFile"
- 添加 cpp11 插件时出现错误消息"Undefined reference to boost (...)"