如何将Makefile转换为ROS CMakeLists.txt并解决csmc库函数未定义引用问题
解决ROS环境下CMakeLists.txt链接csmc库的未定义引用问题
看起来你遇到的是链接阶段未正确关联csmc库的问题,这在从Makefile转CMake时很常见。下面是具体的解决步骤和修改后的CMakeLists示例:
问题根源
你的错误undefined reference to 'SmcWSetResolveSpeed'说明编译通过了(头文件路径没问题),但链接器找不到这些函数对应的实现——也就是没有把csmc库正确链接到你的可执行文件mover上。同时你原来的Makefile还用到了-pthread参数,这部分在CMake里也需要显式添加。
修正后的CMakeLists.txt关键部分
先看核心修改点,再给完整示例:
正确查找csmc库
find_library需要明确库的名称(不带lib前缀和.so后缀),如果库不在系统默认路径(比如/usr/lib),要通过PATHS指定库所在目录:# 查找csmc库,找不到就报错 # 若库在自定义路径,添加PATHS参数,比如:PATHS /opt/csmc/lib find_library(CSMC_LIBRARY NAMES csmc REQUIRED)链接库到可执行文件
在add_executable之后,必须用target_link_libraries把找到的csmc库、pthread以及ROS的catkin库都链接进去:add_executable(mover src/mover.cpp) # 假设你的源文件在src目录下 target_link_libraries(mover ${catkin_LIBRARIES} # ROS基础库 ${CSMC_LIBRARY} # 刚才找到的csmc库 pthread # 对应原来Makefile的-pthread )添加编译选项
对应原来Makefile的-Wall,在CMake里用:add_compile_options(-Wall)
完整的CMakeLists.txt示例
cmake_minimum_required(VERSION 3.0.2) project(your_package_name) # 替换成你的ROS包名 # 编译选项:C++11标准 + Wall警告 add_compile_options(-std=c++11 -Wall) # 查找ROS依赖(根据你的需求添加更多组件) find_package(catkin REQUIRED COMPONENTS roscpp ) # 查找csmc库 # 如果库不在系统默认路径,添加PATHS指定路径,比如PATHS /usr/local/lib/csmc find_library(CSMC_LIBRARY NAMES csmc REQUIRED) catkin_package( # 如果你的包要导出头文件或库,取消下面的注释并修改 # INCLUDE_DIRS include # LIBRARIES your_package_name # CATKIN_DEPENDS roscpp ) # 头文件目录(如果csmc头文件不在默认路径,添加对应的路径) include_directories( include ${catkin_INCLUDE_DIRS} # 比如:/opt/csmc/include ) # 生成可执行文件 add_executable(mover src/mover.cpp) # 链接依赖库 target_link_libraries(mover ${catkin_LIBRARIES} ${CSMC_LIBRARY} pthread )
额外检查点
- 确认
libcsmc.so(或静态库libcsmc.a)确实存在于你指定的路径(或系统默认库路径) - 如果csmc的头文件不在系统默认路径(比如
/usr/include),一定要在include_directories里添加头文件所在目录 - 运行
catkin_make前,可以先删除build和devel目录,避免缓存问题:rm -rf build devel catkin_make
内容的提问来源于stack exchange,提问作者daRula




