【问题标题】:Why two targets linking differently using cmake?为什么两个目标使用 cmake 以不同方式链接?
【发布时间】:2019-08-07 16:23:25
【问题描述】:

我有这个编译好的目标。

#
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 机器上,我有这些未定义的引用。

这是编译命令

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 中定义的导致未定义引用的函数

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

为什么会失败? 如何解决?

【问题讨论】:

  • 所以链接器告诉你agent_client_register等尚未定义。您认为这些函数的定义在哪里?
  • @john,在Agent/agent_client.cpp 中,这个文件被编译为对象和链接器添加的对象,但是它不起作用,并且Agent/agent_client.h 包含在Agent/agent_main.cpp 中并带有必要的声明。
  • 我问的不是声明,问题是缺少定义。所以又是同样的问题。你认识这些函数的名字吗?是您编写(或下载或复制或其他)的代码中的定义。目前还没有迹象表明任何事情都不起作用,到目前为止,您似乎根本没有这些函数的定义。除非你能告诉我不同​​。
  • 我会尝试在 agent_client.h 中将 agent_client_register() 和其余的声明为 extern "C" 并确保包含此标头在 agent_client.cppagent_main.cpp 中。
  • @AlexCohn,奇怪,在带有 gcc 9.1 的 arm 机器上这是不必要的,但在 x86 上它可以工作!谢谢!

标签: c++ makefile cmake g++


【解决方案1】:

重点不在 cmake 中,甚至不在 make 命令中。我认为这是关于 gcc 版本的支持。在 x86 上,我有 gcc v4.3.4。

正如@AlexCohn 在 cmets 中所说的

我会尝试将 agent_client_register() 和其余的声明为 agent_client.h 中的 extern "C" 并确保此标头包含在 agent_client.cpp 和 agent_main.cpp 都有

【讨论】:

  • 似乎在一种情况下,调用的是 gcc 而不是 g++
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-13
  • 1970-01-01
  • 2019-03-15
  • 1970-01-01
  • 2022-01-26
  • 1970-01-01
相关资源
最近更新 更多