1. cmake_minimum_required(VERSION 2.8.3)
每一个 catkin CMakeLists.txt 必须以 CMake 需要的版本开始,Catkin 需要版本 2.8.3 或者更高
2. project(project-name)
定义工程名称,执行后则编译时可以使用变量 ${PROJECT_NAME}
注:
(1)如果子文件夹 CMakeLists.txt 中没有语句: project(PROJECT_NAME)
那么使用PROJECT_NAME就会继承父文件夹中的CMakeLists.txt定义
(2)如果子文件夹中的CMakeLists.txt有定义,则按照定义进行
3. find_package( [VERSION] [EXACT] [QUIET] [MODULE][REQUIRED] [[COMPONENTS] [components…]] [OPTIONAL_COMPONENTS components…])
在全局,全盘寻找指定name的库,找到后,就会将name_xxxx等变量赋值,就可以用对应的变量了
举例说明:
<NAME>_FOUND
若找到package,则此变量为1,否则为0
<NAME>_INCLUDE_DIRS or <NAME>_INCLUDES
头文件的路径
<NAME>_LIBRARIES or <NAME>_LIBS
库文件的路径
<NAME>_VERSION_STRINGS
版本信息的字符串
关键字解释:
VERSION和EXACT:
都是可选的,version指定的是版本,如果指定就必须检查找到的包的版本是否和version兼容。
如果指定EXACT则表示必须完全匹配的版本而不是兼容版本就可以。
QUIET:
可选字段,表示如果查找失败,不会在屏幕进行输出
但是如果指定了REQUIRED字段,则QUIET无效,仍然会输出查找失败提示语。
MODULE:
可选字段,前面提到说“如果Module模式查找失败则回退到Config模式进行查找”
但是假如设定了MODULE选项,那么就只在Module模式查找,
如果Module模式下查找失败并不回落到Config模式查找。
REQUIRED:
可选字段,表示一定要找到包,找不到的话就立即停掉整个cmake。
而如果不指定REQUIRED则cmake会继续执行。
COMPONENTS components...:
可选字段,表示查找的包中必须要找到的组件(components)
如果有任何一个找不到就算失败,类似于REQUIRED,导致cmake停止执行。
OPTIONAL_COMPONENTS components...:
可选的模块,找不到也不会让cmake停止
举例:
find_package(Boost 1.49.0 COMPONENTS unit_test_framework serialization)
Boost就是package,COMPONENTS 后面跟着的就是列出的一些与包相关的部件清单,若找不到,cmake停止执行
4. catkin_package()
参数解释:
INCLUDE_DIRS(字符串列表)
– CMAKE_CURRENT_SOURCE_DIR到C / C ++的相对路径
LIBRARIES(字符串列表)
–lib_name,这个lib_name的库会出现在这个catkin的catkin_LIBRARIES宏变量中,
同时也会出现在${PROJECT_NAME}_LIBRARIES宏变量中,
别的工程是可以通过find_package找到这个lib_name库的。
当前,如果逻辑目标名称与安装的名称不同,则此操作将中断。
CATKIN_DEPENDS(字符串列表)
此项目所依赖的catkin项目列表。当代码可以通过find_package()或pkg-config找到该项目时,将使用它。
列出的每个项目必须是已经被find_package或在.pc文件中的被使用。
因此,需要添加它们的INCLUDE_DIRS和LIBRARIES。
只有在保证它们可以find_package并且具有pkg-config文件的情况下,
才应使用这种catkin项目。一般来说这种项目为ros下的项目。
DEPENDS(字符串列表)
此项目所依赖的CMake项目的列表。
由于它们可能不能被find_packag或缺少pkg-config文件以及变量INCLUDE_DIRS,LIBRARIES,
因此将它们直接传递。这就要求它已被find_package()找到
或者是拥有变量(<name>_FOUND,<name>_INCLUDE_DIRS,等)。
CFG_EXTRAS(字符串)
一个负责外部配置的CMake文件
其中包含find_package-ing 之后该程序包的用户应该可以访问的其他内容。
该文件必须位于子目录中cmake或为绝对路径。所有传递的额外文件都必须具有唯一的基名,
因为它们被安装到单个文件夹中。可以有各种附加的文件扩展名:对于一个普通cmake的文件只是.cmake
对于使用的CMake的展开的文件configure_file()使用.cmake.in或文件通过empy使用扩展.cmake.em。
模板可以使用布尔变量DEVELSPACE 和来区分devel-和installspace INSTALLSPACE。
如果设置了全局变量$ {PROJECT_NAME} _CFG_EXTRAS,它将放在显式传递的参数之前。
EXPORTED_TARGETS(字符串列表)
通常会生成代码的目标名称列表。
下游程序包可以取决于这些目标,以确保在使用代码之前就已生成它们。生成CMake配置文件将确保目标存在。
如果设置了全局变量$ {PROJECT_NAME} _EXPORTED_TARGETS,它将放在显式传递的参数之前。
SKIP_CMAKE_CONFIG_GENERATION(bool)
跳过为软件包生成CMake配置文件的选项
SKIP_PKG_CONFIG_GENERATION(bool)
跳过为软件包生成pkg-config文件的选项
举例:
1. catkin_package(DEPENDS Boost)
catkin 将 find_package(Boost)(作用于全局), 并向 ${your_pkg_LIBRARIES} 添加 ${Boost_LIBRARIES},
向 ${your_pkg_INCLUDE_DIRS} 添加 ${Boost_INCLUDE_DIRS}, 但是应该先进行find_package()
2. catkin_package(CATKIN_DEPENDS roscpp std_msgs)
CATKIN_DEPENDS 选项和 DEPENDS 选项十分相似,但是对于CATKIN_DEDPENS来说,
你只能在其列表中放置 catkin 程序包(即是用roscreate-pkg创建的程序包)。
3.catkin_package(
INCLUDE_DIRS include
LIBRARIES ${PROJECT_NAME}
CATKIN_DEPENDS roscpp nodelet
DEPENDS eigen opencv
)
5. 关于添加消息的操作
首先在catkin_make()中增加message_runtime的CATKIN_DEPENDS
然后使用add_message_files() 添加定义好的消息文件,格式为 xxx.msg.
最后告诉cmake配置生成消息相关文件,使用generate_messages()
举例:
catkin_package(
...
CATKIN_DEPENDS message_runtime ...
...
)
add_message_files(
FILES
xxx.msg(自己更改定义的文件名)
)
generate_messages(
DEPENDENCIES
std_msgs
)
附:添加消息的一般操作步骤(不止是修改cmakelist文件)
>>>首先是修改package.xml文件,确保该文件中与message有关的内容没有被注释掉。
>>>然后修改CMakeist.txt文件:
在find_package函数中加入message_generation依赖;
在catkin_package函数中加入message_runtime依赖;
修改add_message_file函数,添加入自己创建的Num.msg文件;
或者在add_service_file函数中添加入自己创建的srv文件;
确保generate_messages函数被调用运行,去掉注释符号#;
>>>重新编译生成软件包,会生成对应消息的头文件,include之后就可以在程序中对消息进行编程操作。
6. include_directories(, , …, )
添加头文件目录,以包含find_package路径以及其他需要的路径。
参数形如:
*_INCLUDE_DIRS
举例:使用catkin and Boost ,形式如下:
include_directories(
include
${Boost_INCLUDE_DIRS}
${catkin_INCLUDE_DIRS}
)
7. link_directories(, , …, )
添加需要链接的库文件目录,用来加载外加的=动态链接库或静态链接库的搜索路径,相当于gcc的-L参数
举例:
link_directories(
/usr/local/cuda/lib64
)
8. link_libraries()
添加需要链接的库文件路径,注意这里是全路径
举例:
LINK_LIBRARIES("/opt/MATLAB/R2012a/bin/glnxa64/libeng.so")
9. target_link_libraries()
将其他库与已有的库进行链接,添加链接库,相同于指定-l参数
举例:
//以下这些库名写法都可以。
TARGET_LINK_LIBRARIES(myProject libeng.so)
TARGET_LINK_LIBRARIES(myProject eng)
TARGET_LINK_LIBRARIES(myProject -leng)
10. add_library( [STATIC | SHARED | MODULE] [EXCLUDE_FROM_ALL] source1 source2 … sourceN)
添加一个名为<name>的库文件,该库文件将会根据调用的命令里列出的源文件来创建。
<name>对应于逻辑目标名称,而且在一个工程的全局域内必须是唯一的。
待构建的库文件的实际文件名根据对应平台的命名约定来构造(比如lib<name>.a或者<name>.lib)
指定STATIC,SHARED,或者MODULE参数用来指定要创建的库的类型。
STATIC库是目标文件的归档文件,在链接其它目标的时候使用。
SHARED库会被动态链接,在运行时被加载。MODULE库是不会被链接到其它目标中的插件,
但是可能会在运行时使用dlopen-系列的函数动态链接。如果没有类型被显式指定,
这个选项将会根据变量BUILD_SHARED_LIBS的当前值是否为真决定是STATIC还是SHARED.
举例:
add_library(
${PROJECT_NAME}_lib #使用当前项目名称做为库名称
src/YoloObjectDetector.cpp
)
11. add_executable( [WIN32] [MACOSX_BUNDLE] [EXCLUDE_FROM_ALL] source1 source2 … sourceN)
使用给定的源文件,为工程引入一个可执行文件
举例:
add_executable(
${PROJECT_NAME}
src/yolo_object_detector_node.cpp
)
12. add_dependencies(target-name depend-target1 depend-target2 …)
为顶层目标引入一个依赖关系。让一个顶层目标依赖于其他的顶层目标。
一个顶层目标是由命令ADD_EXECUTABLE,ADD_LIBRARY,或者ADD_CUSTOM_TARGET产生的目标。
为这些命令的输出引入依赖性可以保证某个目标在其他的目标之前被构建。
举例:
add_dependencies(
<target-name>
${${PROJECT_NAME}_EXPORTED_TARGETS}
${catkin_EXPORTED_TARGETS}
)
13. add_definitions(-DFOO -DBAR …)
添加编译宏定义,为源文件的编译添加由-D引入的define flag
举例:
add_definitions(-DDARKNET_FILE_PATH="${DARKNET_PATH}")
14. message([SEND_ERROR | STATUS | FATAL_ERROR] “message to display”)
在执行cmake时打印消息
举例:
message(STATUS "Darknet path dir = ${DARKNET_PATH}")
15. generate_dynamic_reconfigure_options(xxx.cfg …)
生成动态参数配置文件
举例:
generate_dynamic_reconfigure_options(
cfg/Tutorials.cfg
)
(i) set_target_properties() 函数
用于库文件重命名输出
举例:
set_target_properties(
rviz_image_view
PROPERTIES OUTPUT_NAME image_view
PREFIX ""
)
(ii) 自定义输出路径:
目标文件的默认路径有时候必须改为自定义的路径。自定义的路径中,有一些默认的规则。
举例:
set_target_properties(
python_module_library
PROPERTIES LIBRARY_OUTPUT_DIRECTORY
${CATKIN_DEVEL_PREFIX}/${CATKIN_PACKAGE_PYTHON_DESTINATION}
)
(iii) add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
为构建添加一个子路径。
add_subdirectory 会去这个指定的目录寻找子cmakelists.txt
在交叉目录需要寻找头文件的时候,调用者的目录当中的CMakeLists.txt当中添加头文件路径
add_library,target_link_libraries,set_target_properties,target_link_libraries使用联系
project(Camera_sugan) #工程名字
cmake_minimum_required(VERSION 2.6) #编译最低cmake版本
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11" ) #设置c++编译器
find_package(OpenCV REQUIRED) #在整个电脑上找opencv包
include_directories( #包含头文件路径
./include/inudev/
./src/
)
set(SRC_LISTS #将所有的源文件列为一个集合,集合名字叫做SRC_LISTS
./src/inuitive.cpp
./src/runCamera_Qfeeltech.cpp
)
add_library(libsugan ${SRC_LISTS}) #将集合里的所有的源文件生成一个静态库,该静态库的名字libsugan,注意,在整个CmakeLists里都要用libsugan这个名字来代替之前那个集合生成的库。
target_link_libraries(libsugan #链接静态库需要的依赖库
${OpenCV_LIBS}
${PROJECT_SOURCE_DIR}/lib/libCommonUtilities.so
${PROJECT_SOURCE_DIR}/lib/libInuStreams.so
)
存储出来的结果就是liblibsugan.a,看着很别扭,为了大众点,我们用下面这句,保证了存储出来的静态库叫做libsugan.a 想更改可以使用以下函数
set_target_properties(libsugan PROPERTIES OUTPUT_NAME "sugan")
#如果想链接生成的这个库必须使用 “add_library(libsugan ${SRC_LISTS})”指明的名字
add_executable(demo ./src/main.cpp)
target_link_libraries(demo libsugan)