C++ 为什么两个目标使用cmake链接不同?

C++ 为什么两个目标使用cmake链接不同?,c++,makefile,cmake,g++,C++,Makefile,Cmake,G++,我有一个编译正常的目标 # 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_ta

我有一个编译正常的目标

#
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()
这是错误代码

/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

UDP2

在带有gcc v9.1.0的arm机器上,它通过makefile成功构建

在带有gcc v4.3.4的x86机器上,我有这样未定义的引用

这是编译命令

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_main.cpp的一部分:

这是在agent_client.cpp中定义的函数,它会导致未定义的引用

UPD3

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在评论中所说的那样

我会尝试声明代理\客户\注册,其余的则为 在agent_client.h中插入C,并确保此标头包含在 agent_client.cpp和agent_main.cpp


所以链接器告诉您代理、客户、注册等尚未定义。你认为这些函数的定义在哪里?@john,在Agent/Agent_client.cpp中,这个文件编译为object和linker添加的object,但它不起作用,Agent/Agent_client.h包含在Agent/Agent_main.cpp中,并带有必要的声明。我不是问声明,问题是缺少定义。同样的问题。你能认出这些功能的名称吗?是您编写、下载或复制的代码中的定义。目前还没有任何迹象表明任何东西都不起作用,到目前为止,您似乎根本没有这些函数的定义。除非你能告诉我不同的地方。我会尝试在agent\u client.h中将agent\u client\u register和其余部分声明为extern C,并确保这个头包含在agent\u client.cpp和agent\u main.cpp中。@AlexCohn,奇怪的是,在带有gcc 9.1的arm机器上它是不必要的,但在x86上它可以工作!非常感谢。在一种情况下,似乎调用了gcc而不是g++。
> 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_
...