对于 CMake 专家来说,这个错误可能微不足道,但我似乎对此视而不见。我尝试过两种方法。
我有一个用 C 编写的库,并使用 gcc 9.4.0 作为静态和动态库进行编译。我已经将库分开编译,它成功地构建并链接到它的
main.c
以使用 Makefile 生成可执行文件。当我这样做时 nm -D mylib.so
我得到了我需要的所有符号和功能。
现在,我尝试将这个库与 ROS 一起使用(意味着使用 CMake 进行构建和链接),但程序无法链接。我尝试了两种方法:按原样使用库,并使用 CMake 重新构建库。两者都失败了。为了保持示例简短,我删除了 catkin 使用的行,这些行基本上告诉 CMake 链接到所有 ROS 基础设施。可以说,目标 (my_node) 的 main.cpp 使用了库中未找到的
void* CreateEnvironment();
函数(与任何其他函数相同)。说:
#include <mylib/mylib.h>
int main(int argc, char** argv){
foo();
return 0;
}
void foo(){
void ptr = CreateEnvironment();
}
使用 CMake 它拒绝链接。 CMakeLists.txt如下:
cmake_minimum_required(VERSION 3.0.2)
find_library(
MY_LIB
NAME mylib
PATHS "${PROJECT_SOURCE_DIR}/lib"
NO_DEFAULT_PATH # Can add or remove this, no difference
)
add_library(mylib SHARED IMPORTED)
set_target_properties(mylib PROPERTIES IMPORTED_LOCATION "${MY_LIB}")
add_executable(my_node src/main.cpp)
target_link_libraries(my_node mylib ${catkin_LIBRARIES})
它运行:
/usr/bin/c++ -rdynamic CMakeFiles/…/main.cpp.o -o /home/…/clips_node -Wl,-rpath,/home/…/lib:/opt/ros/noetic/lib /home/…/lib/libmylib.so […]
/usr/bin/ld: CMakeFiles/…/main.cpp.o: in function `foo()':
main.cpp:(.text+0x11): undefined reference to `CreateEnvironment()'
尝试过这种方法,认为我的库可能是用不同的标准构建的,或者并非所有符号都被导出,或者导出不兼容等等。由同一系统构建并强制使用 C++ 而不是 C 应该使其可链接......但事实并非如此。
再次创建 SO,并且所有符号均通过
nm -D
可见。这是与可执行目标的链接失败的原因。
cmake_minimum_required(VERSION 3.0.2)
## Build library
SET(MYLIB_INCLUDE_DIR "${PROJECT_SOURCE_DIR}/include/mylib")
AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/src/mylib MYLIB_SOURCES)
add_library(mylib ${MYLIB_SOURCES})
target_include_directories(mylib PRIVATE ${MYLIB_INCLUDE_DIR})
set_target_properties(mylib PROPERTIES
LINKER_LANGUAGE "CXX"
ENABLE_EXPORTS 1
)
## Build node
add_executable(my_node src/main.cpp)
target_include_directories(my_node PUBLIC ${MYLIB_INCLUDE_DIR})
target_link_libraries(my_node mylib ${catkin_LIBRARIES})
输出几乎与方法 #1 相同,只是库的路径发生了变化。
target_link_libraries
target_link_libraries
target_link_libraries
到目前为止,共享对象似乎已传递给链接器,但由于某种原因,它拒绝链接文件。使用 Makefile,我知道我可以更改顺序,因为某些库必须前置,某些库必须附加,但 CMake 似乎都是自动的,到目前为止我还没有找到错误。
目前我也遇到和你一样的问题。请问您这个问题解决了吗? 如果是这样,你能告诉我你的解决方案吗?