定义变量并链接库时,为什么使用“未定义的引用”?
我们有几个应用程序链接到我们自己的几个库。我最近添加了一个链接到这些库的新应用程序,并且这在Windows上成功编译。定义变量并链接库时,为什么使用“未定义的引用”?
但是,在Linux上,我看到一个“未定义的引用”错误的静态变量,这当然意味着该变量未定义。该错误发生在库中,但只有链接到新应用程序时(现有应用程序仍可正常链接)。你可以看到,编译器说kAppVersion
是未定义的。实际上它在Version.cpp中定义,并且通用链接(在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浏览。
首先,链接顺序的确很重要,至少在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不能。两者之间有什么区别,哪些可以解释这个问题。与正确构建的一个类似项目类似:两个项目之间有什么区别。
我相信这条线是不正确的 - >你错过了“../../lib/synergy” 另外,谢谢,但我明白链接错误,我意识到可能是什么原因......但正如你所看到的,解决方案并不明显(可能为什么你无法解决它)。 – 2012-04-06 22:17:54
请参阅我的答案为实际解决方案。不管怎么说,还是要谢谢你。 – 2012-04-07 00:15:35
真正的问题总之:arch
和synergy
之间的循环库依赖关系。另外,base
实际上未链接到common
库(在base
的CMakeLists.txt中)。
有趣的是,这是由库的CMakeLists.txt文件中的配置问题造成的。这与我添加的新的synergyd
应用程序的CMakeLists.txt无关。
问题是我没有将库链接到其他库中将新调用添加到类中的对方。但是,现在似乎有一个循环链接的问题。
例如,我可以加...
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
我知道排序评论会进来,这就是为什么我花了这么多时间在这个问题上 - 你可以看到,之前订购常见基地没有纠正这个问题。 – 2012-04-06 10:06:54
连接顺序除非库使用ld的'--no-as-needed'选项链接。 – 2012-04-06 10:14:52
我不是说链接顺序无关紧要 - 请阅读我在说什么。我试过改变顺序,但它没有解决问题。这个问题可能不一定是由链接顺序造成的(除非cmake以某种方式改变它)。 – 2012-04-06 22:16:24