Catkin是基于CMake的编译构建系统,具有以下特点:
Catkin沿用了包管理的传统像 find_package()基础结构,pkg-config扩展了CMake,例如
软件包编译后无需安装就可使用,自动生成find_package()代码,pkg-config文件,解决了多个软件包构建顺序问题
一个Catkin的软件包(package)必须要包括两个文件:
package.xml:
包括了package的描述信息name, description, version, maintainer(s), license,opt. authors, url’s,dependencies, plugins, etc…
CMakeLists.txt:
构建package所需的CMake文件
调用Catkin的函数/宏
解析package.xml
找到其他依赖的catkin软件包
将本软件包添加到环境变量
< name>-包的名字
< version>-包的版本号(格式:xxx.xxx.xxx)
< description>-包的内容描述
< maintainer>-维护包的人员的名字
< license>-软件许可证 (例如GPL,BSD,ASL,TODO)
< author> - 原作者名
< url> - 介绍本package的网站链接
< package format=“2”> 格式2
< buildtool_depend>编译构建工具,构建工具依赖关系指定此软件包需要构建自身的构建系统工具。通常只有catkin;
< build_depend>编译依赖项,构建依赖关系指定构建此包所需的包,如果你只使用一些特定的依赖来构建你的包, 而不是在执行时,你可以使用
< build_export_depend>指定包构需要哪些包用来build;
< package format=“2”> 格式2
< exec_depend>
运行依赖项,指定运行此包中的代码需要哪些包,或针对此包构建库;
< doc_depend>
文档依赖项;
< depend>
指定依赖项为编译、导出、运行需要的依赖,最常用,可以涵盖上面的
< build_depend>,< build_export_depend>和< exec_depend>;
定义CMake 版本 (固定要写)
每个 catkin CMakeLists.txt 文件都必须以所需的 CMake 版本开头。
Catkin 需要 2.8.3 或更高版本。现在已经有3.10了
cmake_minimum_required(VERSION 3.10)
CMake项目函数指定包的名称(固定要写)。比如我们正在制作一个名为robots_brain的包
project(robot_brain)
在 CMake 中,可以再CMake 脚本中任何需要的地方使用变量${PROJECT_NAME }引用项目名称。
set(CMAKE_CXX_STANDARD 14)
通过为CMAKE_CXX_STANDAND赋值,指定要使用 C/C++ 的什么版本;
set(CMAKE_CXX_STANDARD_REQUIRED ON)
通过为CMAKE_CXX_STANDARD_REQUIRED赋值,设置指定的C++编译器版本是
必须的,如果不设置,或者为OFF,则指定版本不可用时,会使用上一版本;
编译一个项目,需要使用CMake 的 find_package函数确定依赖的其他CMake包并找到它们,一般情况下至少会有一个catkin依赖:
find_package(catkin REQUIRED)
除此之外,项目依赖的其他软件包,都会自动成为catkin的组件(components)(就CMake而言)。如果将它们指定为组件,而不是在这些包上使用find_package,它将更简单。例如,如果使用包nodelet
find_package(catkin REQUIRED COMPONENTS nodelet)
如果使用 C++ 和 Boost,需要在 Boost 上调用find_package()并指定您使用 Boost 的哪些部分作为组件。
例如,如果想使用 Boost 线程,便这样写:
find_package(Boost REQUIRED COMPONENTS thread)
如果CMake通过 find_package()查找到一个软件包,它就会创建几个CMake环境变量,以提供有关已查找到的软件包的信息。这些环境变量可以在后面的CMake脚本中使用,它们表示软件包导出的头文件所在的位置、源文件所在的位置、软件包依赖的库以及这些库的查找路径,环境变量的名字遵循_,即包名-属性:
_FOUND:当库被查找到时置为true,否则为false
_INCLUDE_DIRS或_INCLUDES:软件包导出的头文件路径
_LIBRARIES或_LIBS:软件包导出的库的路径
_DEFINITIONS:?
Catkin软件包(指的是外部软件包等等)严格意义上并不是catkin的组件,而且,CMake的功能组件功能被用于catkin的设计,以节省大量的打字时间。
对于catkin软件包,以catkin的组件的方式 find_package它们是有好处的,因为这个过程以catkin_prefix的形式创建了一组环境变量。例如,在程序中要使用nodelet软件包,推荐查找软件包的方式是:
find_package(catkin REQUIRED COMPONENTS nodelet)
这就意味着nodelet导出的头文件路径、库等都会附加到 catkin_variables上,比如,catkin_INCLUDE_DIRS不仅包含catkin的头文件路径,也包含了nodelet软件包的头文件路径,这在后面会派上用场。
记住要在catkin_package()前面,cmakelists的注释为#号
set(ROS_DEPENDENCIES
roscpp std_msgs
behaviortree_cpp_v3
actionlib_msgs
actionlib
message_generation
genmsg
)
//包含行为树库的路径,同时还包含了创建action 和 service 相关的库
find_package(catkin REQUIRED COMPONENTS
${ROS_DEPENDENCIES})
----------------------------------------------------------
find_package(catkin REQUIRED
COMPONENTS
//含有msg的要添加以下包依赖生成信息
message_generation
//以下包属于信息的类型,看需要获取
//http://wiki.ros.org/genmsg?distro=noetic
genmsg
std_msgs
//含有action要添加以下两个包依赖
actionlib_msgs
actionlib
)
add_message_files(
FILES
BehaviorTree.msg
NodeParameter.msg
NodeStatus.msg
StatusChange.msg
StatusChangeLog.msg
TreeNode.msg
)
add_service_files(
FILES
do_what.srv
)
add_action_files(
DIRECTORY action//找不到路径则详细说明存放的目录
FILES Shoot.action
)
generate_messages(
DEPENDENCIES
std_msgs # Or other packages containing msgs
genmsg//也可
actionlib_msgs
)
<depend>message_generationdepend>
<depend>std_msgsdepend>
<depend>geometry_msgsdepend>
<depend>actionlibdepend>
<depend>actionlib_msgsdepend>
<exec_depend>message_runtimeexec_depend>
add_dependencies(some_target ${catkin_EXPORTED_TARGETS})
add_dependencies(some_target ${${PROJECT_NAME}_EXPORTED_TARGETS})
add_dependencies(shoot_action_server ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS} ros_behaviortree_demo_gencpp)
catkin_package()是一个由catkin提供的CMake宏。需要指定特定的catkin信息到编译系统,而这些信息又会被为find_package和pkg-config生成代码和其他CMake文件, 以便其他包可以获取有关此包的信息。
可以说catkin_package()是作用在find_package()中的,它安装 package.xml 文件。
必须在使用add_library()或add_executable()声明任何目标之前调用此函数。该函数有 5 个可选参数:
catkin_package( INCLUDE_DIRS include
LIBRARIES ${PROJECT_NAME}
CATKIN_DEPENDS roscpp nodelet
DEPENDS eigen opencv)
catkin_package(
INCLUDE_DIRS include
LIBRARIES ros_behaviortree_demo
CATKIN_DEPENDS ${ROS_DEPENDENCIES}//find_package已经定义的
# DEPENDS system_lib
)
include_directories的参数应该是由调用find_package生成的* _INCLUDE_DIRS变量以及需要包含的任何其他目录。如果使用catkin和Boost,include_directories()的调用为:
include_directories(include {Boost_INCLUDE_DIRS} {catkin_INCLUDE_DIRS})
第一个参数“include”表示包中的include/目录也是路径的一部分。
add_executable(myProgram src/main.cpp src/some_file.cpp src/another_file.cpp)
add_library({PROJECT_NAME} {${PROJECT_NAME}_SRCS})
//将 foo与libmoo.so链接起来
add_executable(foo src/foo.cpp)
add_library(moo src/moo.cpp)
target_link_libraries(foo moo)
//else
add_library(rm_common SHARED ${sources} include/rm_common/referee/data.h)
add_executable(test_kalman test/test_kalman_filter.cpp)
target_link_libraries(rm_common ${catkin_LIBRARIES})
target_link_libraries(test_kalman rm_common ${catkin_LIBRARIES})
注意,在大多数使用情况下,没有必要使用link_directories(),因为该信息通过find_package()已经自动提取到了。
编译完成后,目标被放入catkin工作空间下的devel目录。一般希望将目标安装到系统上,以使其他用户使用,或者安装到本地目录来测试系统级别的安装。也就是说,如果希望能够对代码进行make install,就需要明确目标结束的位置。
上述过程可以使用CMake的 install()函数实现,该函数的参数有:
TARGETS:要安装的目标
ARCHIVE DESTINATION:静态库和动态链接库DLL(Windows).lib存根
LIBRARY DESTINATION:非DLL共享库和模块
RUNTIME DESTINATION:可执行目标和DLL(Windows)模式共享库
例子:
install(TARGETS ${PROJECT_NAME}
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION})
除了这些标准的目标,还要安装一些文件到特定的目录下,即一个包含Python绑定的库必须要安装到另外的不同的目录下,这对Python是重要的:
install(TARGETS python_module_library
ARCHIVE DESTINATION ${CATKIN_PACKAGE_PYTHON_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_PYTHON_DESTINATION})
catkin_install_python(PROGRAMS scripts/myscript
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION})
如果只是安装了Python的脚本,不提供任何模块的话,就不用创建上文提到的 setup.py文件,也不用调用catkin_python_setup()。
install(DIRECTORY include/${PROJECT_NAME}/
DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
PATTERN ".svn" EXCLUDE)
或者如果include目录下的子文件夹无法和软件包名匹配时:
install(DIRECTORY include/
DESTINATION ${CATKIN_GLOBAL_INCLUDE_DESTINATION}
PATTERN ".svn" EXCLUDE)
install(DIRECTORY launch/
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/launch
PATTERN ".svn" EXCLUDE)
参考连接:
来自知乎
来自廖总
优秀的相关文章