我正在尝试理解为什么在编译使用CMake生成的项目时会出现链接错误。
CMakeFiles.txt 为项目中的每个文件夹构建一个静态库,然后以以下方式将它们全部链接在一起:
然后在每个子文件夹中,我有一个简单的CMakeLists.txt文件,如下所示:
CMakeFiles.txt 为项目中的每个文件夹构建一个静态库,然后以以下方式将它们全部链接在一起:
# root CMakeLists.txt
add_subdirectory(subfolder1)
add_subdirectory(subfolder2)
add_subdirectory(...)
add_executable(target ${SOURCES})
set(LIBRARIES
LIB_FOO
LIB_BAR
...
)
target_link_libraries(target
${LIBRARIES}
)
然后在每个子文件夹中,我有一个简单的CMakeLists.txt文件,如下所示:
file(GLOB FOO_SOURCE *.cpp)
add_library(LIB_FOO ${FOO_SOURCE})
现在这个代码可以正常工作并编译,但是在链接时出现了未定义的引用错误,因此我尝试调查是否所有内容都可用,看起来是这样的。实际的错误如下:
libLIB_WORLD.a(World.cpp.o): In function `World::generate(WorldGenOptions)':
World.cpp:(.text+0x803): undefined reference to `MapGenerator::MapGenerator(BlockMap*)'
World.cpp:(.text+0x837): undefined reference to `MapGenerator::generate(bool, WorldGenOptions)'
现在,MapGenerator.cpp已成为LIB_MAP
的一部分,因此我检查文件是否存在并包含符号:
:~$ nm libLIB_MAP.a | grep generate
....
00000000000044dc T _ZN12MapGenerator8generateEb15WorldGenOptions
:~$ nm CMakeFiles/LIB_MAP.dir/MapGenerator.cpp.o | grep generate
....
00000000000044dc T _ZN12MapGenerator8generateEb15WorldGenOptions
所以这个符号现在已经存在了,接下来我检查它是否与 ld 正确链接:
:~$ make VERBOSE=1
/usr/bin/g++ ... libLIB_MAP.a libLIB_WORLD.a ...
因此,它实际上是与无法找到符号的其他库一起在链接阶段出现的。
我有什么微不足道的问题没注意到吗?我对CMake非常新,所以我想不出什么主意。
VERBOSE=1
写的那个,LIB_MAP
在LIB_WORLD
之前链接。 - JackCMakeLists.txt
文件本身中,而是只在需要的地方使用了我的GNU ARM交叉编译工具链,并使用了SET(CMAKE_C_LINK_EXECUTABLE "<CMAKE_LINKER> <CMAKE_C_LINK_FLAGS> -o <TARGET> --start-group <OBJECTS> <LINK_LIBRARIES> --end-group")
。 - Florian