cmake(catkin_make) 自建库封装package
https://blog.csdn.net/convpool/article/details/87726649
以下为自建库封装过程,及用find_package 工具自动找到自建库头文件及库文件的完整过程。
1、新建链接库包
目录树如下
mylib
├── CMakeLists.txt
├── mylib
│ ├── mylib.cpp
│ └── mylib.h
├── mylib-config.cmake.in (便于find_package使用找到头文件位置和库位置)
└── package.xml
package.xml
ros 编译所需文件
<?xml version="1.0"?>
<package format="2">
<name>mylib</name>
<version>0.0.0</version>
<description>
1
</description>
<maintainer email="111@gmail.com">Jerry JI</maintainer>
<license>BSD</license>
<author email="111@gmail.com">Jerry JI</author>
<buildtool_depend>catkin</buildtool_depend>
<build_depend>g++-static</build_depend>
<export>
<build_type>cmake</build_type>
</export>
</package>
CMakeLists.txt
cmake_minimum_required(VERSION 2.8.12)
project(mylib) #工程名
#安装包内必须文件及文件夹
install(FILES package.xml DESTINATION share/mylib/)
#编译配置
add_library(mylib SHARED mylib/mylib.cpp)
set(TARGET_COMPILE_FLAGS "${TARGET_COMPILE_FLAGS} -std=c++11")
set_target_properties(mylib PROPERTIES
COMPILE_FLAGS ${TARGET_COMPILE_FLAGS})
#安装相关文件
install(
TARGETS mylib #待安装库、可执行文件名
EXPORT mylibExport #待输出安装配置文件 note 2
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin
)
# 安装头文件
file(GLOB_RECURSE hdrs "*.h")
foreach(HDR ${hdrs})
file(RELATIVE_PATH REL_FIL ${PROJECT_SOURCE_DIR} ${HDR})
get_filename_component(INSTALL_DIR ${REL_FIL} DIRECTORY)
install(
FILES
${HDR}
DESTINATION
include/${INSTALL_DIR}
)
endforeach()
# 安装产生的头文件
file(GLOB_RECURSE hdrs "*.h.in")
foreach(HDR ${hdrs})
file(RELATIVE_PATH REL_FIL ${PROJECT_SOURCE_DIR} ${HDR})
get_filename_component(DIR ${REL_FIL} DIRECTORY)
get_filename_component(FIL_WE ${REL_FIL} NAME_WE)
install(
FILES
${PROJECT_BINARY_DIR}/${DIR}/${FILE_WE}
DESTINATION
include/${DIR}
)
endforeach()
#安装find_package所需的配置文件
set(MYLIB_CMAKE_DIR share/mylib/cmake) #note 1
include(CMakePackageConfigHelpers)
configure_package_config_file(
mylib-config.cmake.in #用于转变成.cmake文件的输入文件
${PROJECT_BINARY_DIR}/cmake/mylib/mylib-config.cmake #find_package 找到的文件
PATH_VARS MYLIB_CMAKE_DIR #此处与 note 1 变量名一致
INSTALL_DESTINATION ${CMAKE_INSTALL_PREFIX}/share/mylib
)
install(
EXPORT mylibExport #待输出安装配置文件 note 2
DESTINATION share/mylib/cmake/
FILE MYLIBTargets.cmake #待输出安装配置文件名 note 3
)
install(
FILES ${PROJECT_BINARY_DIR}/cmake/mylib/mylib-config.cmake#find_package 找到的文件
DESTINATION share/mylib/
)
mylib-config.cmake.in
@PACKAGE_INIT@
#MYLIB_CMAKE_DIR 以及 PACKAGE_MYLIB_CMAKE_DIR中的MYLIB_CMAKE_DIR部分均与note 1的变量名一致
set_and_check(MYLIB_CMAKE_DIR "@PACKAGE_MYLIB_CMAKE_DIR@")
include("${MYLIB_CMAKE_DIR}/MYLIBTargets.cmake")#待输出安装配置文件名 note 3
list(APPEND mylib_INCLUDE_DIRS ${PACKAGE_PREFIX_DIR}/include/mylib/ )#配置头文件目录
list(APPEND mylib_LIBRARIES ${PACKAGE_PREFIX_DIR}/lib/libmylib.so)#配置库文件目录
mylib下的源文件
mylib.h
#ifndef MYLIB_H
#define MYLIB_H
#include <iostream>
void hello();
#endif//MYLIB_H
mylib.cpp
#include "mylib.h"
void hello()
{
std::cout<<"hello world!"<<std::endl;
}
上述文件编写完成后可以用以下命令来编译安装
catkin_make_isolated --install && source devel_isolated/setup.sh #ros 的安装方式,自动安装到install_isolated所在目录下
或
mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=./install && make install #cmake 的安装方式,可以安装到指定目录下
2、测试程序
以下为测试程序包目录树
test
├── CMakeLists.txt
├── launch
│ └── test.launch
├── package.xml
└── src
└── testnode.cpp
package.xml
<?xml version="1.0"?>
<package format="2">
<name>test</name>
<version>0.0.0</version>
<description>
This is a ROS implementation of test by bit RCIV
</description>
<maintainer email="111@gmail.com">Jerry JI</maintainer>
<license>BSD</license>
<author email="111@gmail.com">Jerry JI</author>
<buildtool_depend>catkin</buildtool_depend>
<build_depend>g++-static</build_depend>
<depend>mylib</depend>
<depend>roscpp</depend>
<depend>roslaunch</depend>
<depend>roslib</depend>
<export>
</export>
</package>
CMakeLists.txt
cmake_minimum_required(VERSION 2.8.3)
project(test)
set(PACKAGE_DEPENDENCIES
roscpp
roslib
)
find_package(catkin REQUIRED COMPONENTS ${PACKAGE_DEPENDENCIES})
find_package(mylib REQUIRED) #找到自建库安装包
#安装所需文件夹
install(DIRECTORY launch DESTINATION share/test/)
catkin_package(
CATKIN_DEPENDS ${PACKAGE_DEPENDENCIES}
DEPENDS
INCLUDE_DIRS
)
#mylib_INCLUDE_DIRS 为mylib mylib-config.cmake.in文件内设置好的头文件目录
include_directories(SYSTEM ${catkin_INCLUDE_DIRS} ${mylib_INCLUDE_DIRS})
add_executable(testnode src/testnode.cpp )# 编译可执行文件
#mylib_LIBRARIES 为mylib mylib-config.cmake.in文件内设置好的库文件
target_link_libraries(testnode PUBLIC ${catkin_LIBRARIES} ${mylib_LIBRARIES} )
set(TARGET_COMPILE_FLAGS "${TARGET_COMPILE_FLAGS} -std=c++11")
set_target_properties(testnode PROPERTIES
COMPILE_FLAGS ${TARGET_COMPILE_FLAGS})
#安装可执行文件等
install(TARGETS testnode
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
install(
TARGETS testnode
EXPORT testnodeExport
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION}
)
src/testnode.cpp
#include <ros/ros.h>
#include <mylib.h>
int main(int argc, char** argv)
{
ros::init(argc, argv, "testnode");
ros::NodeHandle nh;
hello();
ros::spin();
return 0;
}
launch/test.launch
<?xml version="1.0" encoding="UTF-8"?>
<launch>
<node pkg="test" type="testnode" name="testnode" args="" output="screen">
</node>
</launch>
上述文件编写完成后可以用以下命令来编译,运行
catkin_make_isolated --install && source devel_isolated/setup.sh #ros 的安装方式,自动安装到install_isolated所在目录下
roslaunch test test.launch