我们有一些应用程序链接到我们自己的几个库。我最近添加了一个链接到这些库的新应用程序,这在Windows上成功编译。
但是,在Linux上,我看到静态变量存在“未定义的引用”错误,这当然意味着未定义变量。错误发生在库中,但仅在链接到新应用程序时(现有应用程序仍然链接正常)。
如您所见,编译器说kAppVersion
未定义。实际上它是在Version.cpp中定义的,并且common是链接的(在CMakeLists.txt中指定)。我们认为它可能与target_link_libraries
排序有关,但将common
移动到base
之前(发生错误的地方)似乎没有效果。此外,在其他CMakeLists.txt(例如,对于协同作用)中,排序似乎是无关紧要的,因为该应用程序成功编译。这个类似的问题似乎暗示订购很重要,但我没有取得任何成功:
Qustion:library is linked but reference is undefined
我唯一的想法是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
可以从our repository浏览完整代码。
答案 0 :(得分:3)
真正的问题: arch
和synergy
之间的循环库依赖关系。另外,base
实际上没有链接到common
库(在base
的CMakeLists.txt中)。
有趣的是,这是由库的CMakeLists.txt文件中的配置问题引起的。这与我添加的新synergyd
应用程序的CMakeLists.txt无关。
问题是我没有将新的调用添加到其他库中的类的库中。但是,现在似乎存在循环链接的问题。
例如,我本可以添加...
if (UNIX)
target_link_libraries(arch synergy)
endif()
...到arch
库中的CMakeLists.txt,arch
现在调用synergy
库中的内容。但这是无效的,因为synergy
已经调用了arch
中的内容。
显然这在Windows上无关紧要。
我不太确定是什么原因导致这种情况开始发生,因为它是以前编译好的所有旧代码,并且在其他应用程序中仍然如此。我怀疑最近可能与最近从CArch中移除锅炉板有关,而不是CDaemonApp正在做的事情(或者甚至可能是两者的组合)。
以防万一有人关心;-) - 我认为这与arch
和synergy
之间糟糕的循环库依赖关系之间的关系,以及{{1 }}不包括CDaemonApp.cpp
- 意味着它包含在其他某个点,导致奇怪的未定义引用错误。
为了妥善解决这个问题,我已经删除了循环依赖,这似乎是问题的核心。
代码现在完全编译,欢呼!
我仍然看到最后一个错误(这个问题的主题):
CApp.h
这只是由[ 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
库引起的。将以下代码添加到CMakeLists.txt文件中以修复此问题:
common
仍然不确定为什么会这样开始发生,只是很高兴它已经修好了。
这是提交:r1354
答案 1 :(得分:2)
首先,链接的顺序确实很重要,至少与g ++有关。如果A
使用B
中的符号,则应在B
之后提及A
:g++ ... -lA -lB
我也看到undefined reference to vtable for XExitApp
。此错误表示您在XExitApp
中有一个未定义的虚函数。如果您不想定义该功能,请通过添加= 0
答案 2 :(得分:0)
我唯一注意到的是你在set(inc...
的{{1}}部分中遗漏了“../../lib/synergy”。这是否与问题相关我只能猜测。
您获得的所有链接错误似乎是由于链接器未找到它正在查找的符号。通常的原因是相关的.o文件不存在,未包含在构建中,或者编译不正确。
我首先要清理,更改CMakeList.txt文件以尽可能匹配已知的工作版本,并在打开所有编译器/警告的情况下重建所有内容。如果这不起作用(相同的错误或不同的错误),我会更仔细地看看有什么作用,什么不行。你说Windows构建工作但Linux没有。两者之间有什么区别,哪些可以解释这个问题。与构建正确的一个类似项目类似:两个项目之间的差异是什么。