c++ - 为什么两个目标使用 cmake 进行不同的链接?

标签 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_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_main.cpp 片段: enter image description here

这是在 agent_client.cpp 中定义的导致 undefined reference 的函数 enter image description here

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/

相关文章:

c++ - main()是用一个自动变量创建的,如果是,它的用途是什么?

c++ - OpenCV/C++ 程序比它的 numpy 对应程序慢,我该怎么办?

c++ - 为什么 GetOverlappedResult 为 ReadDirectoryChangesW 提供 0 字节结果?

c++ - 如何在自己的仅 header 库中包含升压 header

c++ - 指针变量的地址

linux - 如何使用 ExtUtils::MakeMaker 在自定义目录中安装数据

opengl - GLEW 构建失败

C项目有两个例子,好像只有一个可以编译,makefile问题

visual-studio-2008 - CMake 构建 ActiveX OCX?

linux - arm-linux 下缺少 libopencv_ts 缺失