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)