我有这个编译好的目标。
#
file(GLOB SOURCE_FILES
8021QBG/*.h
8021QBG/*.cpp
)
add_library(8021qbg SHARED
${SOURCE_FILES}
)
set_target_properties(8021qbg PROPERTIES LINKER_LANGUAGE CXX)
set(CMAKE_CXX_FLAGS_CUSTOM " ")
set_target_properties(8021qbg PROPERTIES COMPILE_FLAGS " ${CMAKE_CXX_FLAGS_CUSTOM} ${CMAKE_CXX_FLAGS_COMMON}")
add_dependencies(8021qbg core )
target_link_libraries(8021qbg -L${PROJECT_BINARY_DIR})
target_link_libraries(8021qbg -L/home/user/protocol_so )
target_link_libraries(8021qbg -L${PROJECT_SOURCE_DIR}/lib64 )
target_link_libraries(8021qbg -L${PROJECT_SOURCE_DIR})
target_link_libraries(8021qbg protocol_common thread vip core m xml2)
target_include_directories(8021qbg PUBLIC
8021QBG
nte-encap
)
这个失败了。
#
file(GLOB SOURCE_FILES
Agent/*.h
Agent/*.cpp
)
add_library(agent SHARED
${SOURCE_FILES}
)
set_target_properties(agent PROPERTIES LINKER_LANGUAGE CXX)
set(CMAKE_CXX_FLAGS_CUSTOM " ")
set_target_properties(agent PROPERTIES COMPILE_FLAGS " ${CMAKE_CXX_FLAGS_CUSTOM} ${CMAKE_CXX_FLAGS_COMMON}")
add_dependencies(agent core)
target_link_libraries(agent -L${PROJECT_BINARY_DIR})
target_link_libraries(agent -L/home/user/protocol_so )
target_link_libraries(agent -L${PROJECT_SOURCE_DIR}/lib64 )
target_link_libraries(agent -L${PROJECT_SOURCE_DIR})
target_link_libraries(agent protocol_common thread vip core xml2 pthread)
target_include_directories(agent PUBLIC
Agent
nte-encap
)
这些目标也有相同的标志:
set (CMAKE_CXX_FLAGS_COMMON "-g -fpermissive -std=gnu89 -Wall -O0 -m64 -fPIC -DLINUX -DCPU_64 -DXSTREAM ")
set (CMAKE_SHARED_LINKER_FLAGS "-Wl,--unresolved-symbols=ignore-in-shared-libs -shared -Wl,-rpath,/home/user/protocol_so:/home/user/cmake_libs/lib64:libwifi")
if(NOT CMAKE_CXX_CREATE_SHARED_LIBRARY)
set(CMAKE_CXX_CREATE_SHARED_LIBRARY
"<CMAKE_CXX_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>")
endif()
这是链接阶段
/usr/bin/g++ -fPIC -g -Wl,--unresolved-symbols=ignore-in-shared-libs -shared -Wl,-rpath,/home/user/protocol_so:/home/user/cmake_libs/lib64:libwifi -shared -Wl,-soname,libagent.so -o libagent.so CMakeFiles/agent.dir/Agent/agent_common.cpp.o CMakeFiles/agent.dir/Agent/agent_main.cpp.o CMakeFiles/agent.dir/Agent/agent_client.cpp.o CMakeFiles/agent.dir/Agent/agent_cmd.cpp.o CMakeFiles/agent.dir/Agent/agent_go.cpp.o -L/home/user/cmake_libs/cmake-build-debug-rurem -L/home/user/protocol_so -L/home/user/cmake_libs/lib64 -L/home/user/cmake_libs -lprotocol_common -lthread -lvip libcore.so -lxml2 -lpthread -L/home/user/cmake_libs/lib64 -lprotocol_common -lthread -lvip -lcrypto -lglib-2.0 -lm -lxml2 -lpthread -Wl,-rpath,/home/user/cmake_libs/cmake-build-debug-rurem
这是错误代码
/home/user/cmake_libs/Agent/agent_main.cpp:47: undefined reference to `agent_client_register'
/home/user/cmake_libs/Agent/agent_main.cpp:48: undefined reference to `agent_client_unregister'
/home/user/cmake_libs/Agent/agent_main.cpp:49: undefined reference to `agent_client_register_task'
/home/user/cmake_libs/Agent/agent_main.cpp:50: undefined reference to `agent_client_unregister_task'
Cmake 将每个 *.cpp 文件编译为 *.o 对象,然后链接器将它们组合成一个 *.so lib -> 在链接器阶段我遇到了这个错误。
源位于“代理”文件夹中,我将其添加到目标“代理”。
UDP> 简单的 makefile 和 GCC 构建这个库。 生成文件部分:
libagent.so: ${wildcard Agent/*.[c,h]} libcore.so
$(CC) $(CFLAGS) -fPIC -shared -o $@ $(filter %.c,$^) $(IPATH) $(RPATH) $(TE_VIP) -lcore -lxml2 -lpthread
gcc 命令
gcc -g -Wall -O0 -m64 -Wl,--unresolved-symbols=ignore-in-shared-libs -fPIC -shared -o libagent.so -Inte-include -Ixst_inc -Ixst_tls -L./lib64 -L./cmake-build-debug-rurem -Wl,-rpath,/home/user/protocol_so:/home/user/lib64:libwifi -DLINUX -DCPU_64 -DXSTREAM -lprotocol_common -lthread -lvip -lcore -lxml2 -lpthread
UDP#2.
在带有 gcc v9.1.0 的 arm 机器上,它通过 makefile 成功构建。
在带有 gcc v4.3.4 的 x86 机器上,我有这样 undefined reference 。
这是编译命令
g++ -g -Wall -O0 -m64 -Wl,--unresolved-symbols=ignore-in-shared-libs -fPIC -shared -o 0libagent.so -Inte-include -Iinc -Itls -L/home/user/cmake_libs/lib64 -L/home/user/cmake_libs -Wl,-rpath,/home/user/protocol_so:/home/user/cmake_libs/lib64:libwifi -DLINUX -DCPU_64 -DXSTREAM -lprotocol_common -lthread -lvip -lcore -lxml2 -lpthread Agent/agent_main.cpp Agent/agent_cmd.cpp Agent/agent_client.cpp Agent/agent_go.cpp Agent/agent_common.cpp
这是在 agent_client.cpp
中定义的导致 undefined reference 的函数
UPD#3
nm 表示定义在对象中。
> nm CMakeFiles/agent.dir/Agent/agent_client.cpp.o
...
00000000000007e2 T _Z21agent_client_registeriP20_protocol_callback_t
0000000000000000 T _Z21agent_client_run_taskiPv
0000000000000033 T _Z22agent_client_do_actionPviS_S_
...
x86 机器 - SUSE 11 sp3 x64
为什么会失败? 如何解决?
最佳答案
重点不在cmake,更不在make命令。我认为这是关于 gcc 版本支持。在 x86 上我有 gcc v4.3.4。
正如@AlexCohn 在评论中所说
I would try to declare agent_client_register() and the rest of them as extern "C" in agent_client.h and make sure this header is included in both agent_client.cpp and agent_main.cpp
关于c++ - 为什么两个目标使用 cmake 进行不同的链接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57398675/