include_directories
参数应该是find_package调用生成的* _INCLUDE_DIRS变量以及需要包含的任何其他目录。如果您使用catkin和Boost,则include_directories调用应如下所示:1
2# 先调用find_package(Boost catkin),才能使用下面两个宏
include_directories(include ${Boost_INCLUDE_DIRS} ${catkin_INCLUDE_DIRS})
include是目录名,不是命令,一般放头文件。使用message函数发现catkin_INCLUDE_DIRS是/opt/ros/kinetic/include/usr/include
不能直接include当前文件夹的头文件,这倒是奇怪。需要加一行include_directories(.)。另一种解决方法就是在add_executable里添加用到的头文件
添加库路径
1 | LINK_DIRECTORIES(/usr/lib/) |
并不是必须的,如果能直接链接就不需要。
ADD_LIBRARY
生成库文件是ADD_LIBRARY,它的功能是用来指定库来构建。默认情况下,catkin构建共享库。
构建库如下PointManage:1
2
3
4
5
6
7add_library(PointManage src/point_manage.cpp)
target_link_libraries(PointManage
${catkin_LIBRARIES} -pthread -llog4cpp -lcgicc -lmysqlclient jsoncpp Qt5::Core Qt5::Xml
)
add_executable(point_node src/point_manage_node.cpp src/point_manage.cpp)
target_link_libraries(point_node ${catkin_LIBRARIES} -llog4cpp -lmysqlclient -pthread Qt5::Core Qt5::Xml)
库PointManage用到了Qt库,此时也需要加上target_link_libraries命令,编译才能成功。
add_library(lib a.cpp),如果a.cpp中使用了类Test,对应头文件test.h和源文件test.cpp。这种情况下,光include "test.h"不够,应当改成add_library(lib a.cpp test.cpp)
链接库
target_link_libraries必须放在add_executable(或者add_library)的后面。一般要先写好后者,然后再链接库:1
2
3
4
5add_executable(test "main.c")
target_link_libraries(test
${catkin_LIBRARIES}
) //必须跟上面的test同名,后者是很多共享库,大部分是Boost,显然ROS底层用的是Boost
但是注意,如果是生成动态库文件,最好不要再让它链接其他库文件,有时会失败。对于静态库,禁止链接其他库。
查看是否链接动态库成功,可以使用Linux的ldd命令

从报错内容可以看出是缺了distance函数,也就是要链接的so文件里没有distance函数
ALL_TARGET_LIBRARIES 变量
为了避免target_link_libraries后面跟很长一串库的名字,而且库增减的时候它也得跟着增减,我们在CMakeLists一开始定义一个变量: set(ALL_TARGET_LIBRARIES "")
然后在每个库对应的XX.cmake文件中,把库的名字合并到这个变量中去,list(APPEND ALL_TARGET_LIBRARIES ${XX_LIBRARIES}),这样在target_link_libraries就只使用ALL_TARGET_LIBRARIES这一个变量就好了。
install命令
安装网上下载的库时常常最后一步是make install,这是使用CMake的install函数完成的,该函数的参数:1
2
3
4TARGETS 目标安装
ARCHIVE DESTINATION 静态库和DLL(Windows).lib存根
LIBRARY DESTINATION 非DLL共享库和模块
RUNTIME DESTINATION 可执行目标和DLL(Windows)样式共享库
ROS的launch文件可以安装到${CATKIN_PACKAGE_SHARE_DESTINATION}:1
2
3install(DIRECTORY launch/
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/launch
PATTERN ".svn" EXCLUDE)
