本文共 6233 字,大约阅读时间需要 20 分钟。
引用
推荐 严重推荐Extracted CMake API reference
我在/home/yuhs/novatel_ws建立了一个novatel的工作空间
在我的电脑上有如下目录地址:
/home/yuhs/novatel_ws/devel/lib /home/yuhs/novatel_ws/devel/lib/novatel /home/yuhs/novatel_ws/devel/lib/novatel/novatel_node/home/yuhs/novatel_ws/src/novatel/include/novatel
/usr/local/include/novatel打印这些catkin系统变量信息如下:
CATKIN_PACKAGE_LIB_DESTINATION:lib CATKIN_PACKAGE_BIN_DESTINATION:lib/novatel CATKIN_PACKAGE_INCLUDE_DESTINATION:include/novatelCMakeList.txt 文件中,命令名字是不区分大小写的,而参数和变量是大小写相关的
ros的包 catkin_make后,可执行文件在./devel/lib/proj_name/proj_name_node
catkin_package( INCLUDE_DIRS include LIBRARIES novatel CATKIN_DEPENDS serial roslib roscpp rosconsole tf gps_msgs nav_msgs sensor_msgs DEPENDS Boost )
_FOUND _INCLUDE_DIRS or _INCLUDES _LIBRARIES or _LIBS _DEFINITIONS
命令用法:
find_package(<package> [version] [EXACT] [QUIET] [[REQUIRED|COMPONENTS] [components...]] [NO_POLICY_SCOPE])例如:
find_package(Boost 1.49.0 COMPONENTS unit_test_framework serialization) Boost就是package,COMPONENTS 后面跟着的就是列出的一些与包相关的部件清单,这句话我也没太理解,以后再补充,当找到package后,Boost_INCLUDE_DIR这个变量就是被赋值了的,这都是自动化完成的
REQUIRED 参数
其含义是指是否是工程必须的,表示如果报没有找到的话,cmake的过程会终止,并输出警告信息。对应于COMPONENTS
如何理解这个参数COMPONENTS参数的含义
version参数
需要一个版本号,它是正在查找的包应该兼容的版本号(格式是major[.minor[.patch[.tweak]]])。EXACT选项
要求版本号必须精确匹配。如果在find-module内部对该命令的递归调用没有给定[version]参数,那么[version]和EXACT选项会自动地从外部调用前向继承。对版本的支持目前只存在于包和包之间(详见下文)。QUIET 参数:
会禁掉包没有被发现时的警告信息。对应于Find<name>.cmake模块中的 NAME_FIND_QUIETLY。find_package(catkin COMPONENTS serial roslib roscpp rosconsole tf gps_msgs nav_msgs sensor_msgs)
加入了catkin的关键字,每个ros的包都至少有一个find_package需要依赖catkin这个包
上面命令解释:查找catkin包,并且这个catkin包依赖组件:serial roslib roscpp rosconsole tf gps_msgs nav_msgs sensor_msgs如果子文件夹Cmakelists.txt当中没有project(name_xxx1),那么使用PROJECT_NAME就会继承父文件夹当中的project(name_xxx)定的 name_xxx1,如果子目录当中的Cmakelists.txt当中定义过project(name_xxx2),那么子目录当中的Cmakelists.txt当中的 PROJECT_NAME就会是子Cmakelists.txt定义的这个name_xxx
add_subdirectory 会去这个指定的目录寻找子cmakelists.txt
在交叉目录 需要寻找头文件的时候,调用者的目录当中的CMakeLists.txt当中添加头文件路径引用:跟库相关的几个命令讲解的帖子
ADD_LIBRARY 告诉工程,生成一个库,并将源码链接到具体名字的库当中
例如: add_library(lib_name ${SRC_LISTS}) #将集合里的所有的源文件生成一个静态库,该静态库的名字lib_name,注意,在整个CmakeLists里都要用lib_name这个语法:TARGET_LINK_LIBRARIES(targetlibrary1 <debug | optimized> library2 ..)
比如(以下写法(包括备注中的)都可以):
TARGET_LINK_LIBRARIES(myProject hello),连接libhello.so库到myProject(可执行文件)当中 TARGET_LINK_LIBRARIES(myProject libhello.a) TARGET_LINK_LIBRARIES(myProject libhello.so)再如:
TARGET_LINK_LIBRARIES(myProject libeng.so) #将libeng.so链接到myProject中。 TARGET_LINK_LIBRARIES(myProject eng) TARGET_LINK_LIBRARIES(myProject -leng)target_link_libraries(lib_name #链接静态库需要的依赖库
${OpenCV_LIBS} ${PROJECT_SOURCE_DIR}/lib/libCommonUtilities.so ${PROJECT_SOURCE_DIR}/lib/libInuStreams.so ) 从这个例子当中可以看出target_link_libraries功能,如果第一个是静态库(因为没有用shared相关的关键词,所以为静态),那么就是把其他库也连接到这个静态库当中,第一个参数也可以是执行文件,然后将库链接到可执行的应用文件中,如下例子所示语法:
link_directories(directory1 directory2 ...) 它相当于g++命令的-L选项的作用,也相当于环境变量中增加LD_LIBRARY_PATH的路径的作用。 比如: LINK_DIRECTORIES("/opt/MATLAB/R2012a/bin/glnxa64") export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MATLAB/bin/glnxa64List of direct link dependencies.
比如: LINK_LIBRARIES("/opt/MATLAB/R2012a/bin/glnxa64/libeng.so") LINK_LIBRARIES("/opt/MATLAB/R2012a/bin/glnxa64/libmx.so") 也可以写成: LINK_LIBRARIES("/opt/MATLAB/R2012a/bin/glnxa64/libeng.so" "/opt/MATLAB/R2012a/bin/glnxa64/libmx.so")先生成可执行文件,后把库连接到可执行文件中即可
add_executable(hello ${APP_SRC}) target_link_libraries(hello libhello)理解
例子说明,如下所示:
project(HELLO)set(LIB_SRC hello.c)set(APP_SRC main.c)add_library(libhello ${LIB_SRC})add_executable(hello ${APP_SRC})target_link_libraries(hello libhello)
里面有一点不爽,对不?
因为我的可执行程序(add_executable)占据了 hello 这个名字,所以 add_library 就不能使用这个名字了 然后,我们去了个libhello 的名字,这将导致生成的库为 libhello.lib(或 liblibhello.a),很不爽 想生成 hello.lib(或libhello.a) 怎么办? 添加一行 set_target_properties(libhello PROPERTIES OUTPUT_NAME "hello") 就可以了