CMakeLists 基础

Reference:

  1. SLAM - CMake入门基础

0. 常用预定义变量

# Variable	                # Info
CMAKE_SOURCE_DIR	        根源代码目录,工程顶层目录。暂认为就是PROJECT_SOURCE_DIR
CMAKE_CURRENT_SOURCE_DIR	当前处理的 CMakeLists.txt 所在的路径
PROJECT_SOURCE_DIR	        工程顶层目录
CMAKE_BINARY_DIR	        运行cmake的目录。外部构建时就是build目录
CMAKE_CURRENT_BINARY_DIR	The build directory you are currently in.当前所在build目录
PROJECT_BINARY_DIR	        暂认为就是CMAKE_BINARY_DIR

1. 第一个CMakeLists.txt文件

文件树如下:

├── CMakeLists.txt
├── main.cpp

CMakeLists.txt 文件如下:

cmake_minimum_required(VERSION 3.5) #设置CMake最小版本
project (hello_cmake) #设置工程名,自动生成一些变量,比如PROJECT_NAME
add_executable(hello_cmake main.cpp) #生成可执行文件

注意事项:

  • CMake 命令不区分大小写。习惯上,CMake 命令全小写,预定义变量全大写。
  • command(parameter1 parameter2 …),参数使用括号括起,参数之间使用空格或分号分开。

2. 如果工程里有其他的头文件呢?

文件树如下:

├── CMakeLists.txt
├── include
│   └── Hello.h
└── src
    ├── Hello.cpp
    └── main.cpp

CMakeLists.txt 文件如下:

cmake_minimum_required(VERSION 3.5)#最低CMake版本
project (hello_headers)# 工程名
add_executable(hello_headers src/Hello.cpp #用所有的源文件生成一个可执行文件
						   src/main.cpp )#不建议对源文件使用变量
target_include_directories(hello_headers#设置这个可执行文件hello_headers需要包含的库的路径
    PRIVATE 
        ${PROJECT_SOURCE_DIR}/include
)
#PROJECT_SOURCE_DIR指工程顶层目录
#PRIVATE指定了库的范围

3. 如果工程里包含静态库呢?

文件树如下:

├── CMakeLists.txt
├── include
│   └── static
│       └── Hello.h
└── src
    ├── Hello.cpp
    └── main.cpp

main.cpp

#include "static/Hello.h" // 这里需要注意

int main(int argc, char *argv[])
{
    Hello hi;
    hi.print();
    return 0;
}

CMakeLists.txt 文件如下:

cmake_minimum_required(VERSION 3.5)
project(hello_library)
############################################################
# Create a library
############################################################
#库的源文件Hello.cpp生成静态库libhello_library.a
add_library(hello_library STATIC 
    src/Hello.cpp
)
target_include_directories(hello_library
    PUBLIC 
        ${PROJECT_SOURCE_DIR}/include
)
# target_include_directories为一个目标(可能是一个库library也可能是可执行文件)添加头文件路径。
############################################################
# Create an executable
############################################################
#指定用哪个源文件生成可执行文件
add_executable(hello_binary 
    src/main.cpp
)
#链接可执行文件和静态库
target_link_libraries(hello_binary
    PRIVATE 
        hello_library
)
#链接库和包含头文件都有关于scope这三个关键字的用法。

4. 如果工程里包含共享库呢?

文件树如下:

├── CMakeLists.txt
├── include
│   └── shared
│       └── Hello.h
└── src
    ├── Hello.cpp
    └── main.cpp

CMakeLists.txt 文件如下:

cmake_minimum_required(VERSION 3.5)
project(hello_library)
############################################################
# Create a library
############################################################
#根据Hello.cpp生成动态库libhello_library.so
add_library(hello_library SHARED 
    src/Hello.cpp
)
#给动态库hello_library起一个别的名字hello::library
add_library(hello::library ALIAS hello_library)
#为这个库目标,添加头文件路径,PUBLIC表示包含了这个库的目标也会包含这个路径
target_include_directories(hello_library
    PUBLIC 
        ${PROJECT_SOURCE_DIR}/include
)
############################################################
# Create an executable
############################################################
#根据main.cpp生成可执行文件
add_executable(hello_binary
    src/main.cpp
)
#链接库和可执行文件,使用的是这个库的别名。
target_link_libraries( hello_binary
    PRIVATE 
        hello::library
)

5. 如果工程里包含第三方库呢?

main.c 如下所示:

#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/filesystem.hpp>
/*Boost库是为C++语言标准库提供扩展的一些C++程序库的总称,由Boost社区组织开发、
维护。Boost库可以与C++标准库完美共同工作,并且为其提供扩展功能。*/
int main(int argc, char *argv[])
{
 ...
 return 0;
}

CMakeLists.txt 文件如下:

cmake_minimum_required(VERSION 3.5)
project (third_party_include)
# find a boost install with the libraries filesystem and system
find_package(Boost 1.46.1 REQUIRED COMPONENTS filesystem system)
# check if boost was found
if(Boost_FOUND)
    message ("boost found")
else()
    message (FATAL_ERROR "Cannot find Boost")
endif()
# Add an executable
add_executable(third_party_include main.cpp)
# link against the boost libraries
target_link_libraries( third_party_include
    PRIVATE
        Boost::filesystem
)

如上所述,find_package()函数将从 CMAKE_MODULE_PATH 中的文件夹列表中搜索 “FindXXX.cmake” 中的CMake模块。find_package 参数的确切格式取决于要查找的模块。这通常记录在 FindXXX.cmake 文件的顶部。
参数:

  • Boost:库名称。这是用于查找模块文件 FindBoost.cmake 的一部分;
  • 1.46.1:需要的boost库最低版本;
  • REQUIRED:告诉模块这是必需的,如果找不到会报错;
  • COMPONENTS:要查找的库列表。从后面的参数代表的库里找 boost。

可以使用更多参数,也可以使用其他变量。在后面的示例中提供了更复杂的设置。

尽管大多数现代库都使用导入的目标,但并非所有模块都已更新。如果未更新库,则通常会发现以下可用变量:

  • xxx_INCLUDE_DIRS:指向库包含目录的变量;
  • xxx_LIBRARY:指向库路径的变量。

然后可以将它们添加到您的 target_include_directories 和 target_link_libraries 中,如下所示:

# Include the boost headers
target_include_directories( third_party_include
    PRIVATE ${Boost_INCLUDE_DIRS}
)

# link against the boost libraries
target_link_libraries( third_party_include
    PRIVATE
    ${Boost_SYSTEM_LIBRARY}
    ${Boost_FILESYSTEM_LIBRARY}
)

6. 如何设置构建类型呢?

文件树如下:

├── CMakeLists.txt
├── main.cpp

CMakeLists.txt 文件如下:

cmake_minimum_required(VERSION 3.5)
#如果没有指定则设置默认编译方式
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
  #在命令行中输出message里的信息
  message("Setting build type to 'RelWithDebInfo' as none was specified.")
  #不管CACHE里有没有设置过CMAKE_BUILD_TYPE这个变量,都强制赋值这个值为RelWithDebInfo
  set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE)
  # 当使用cmake-gui的时候,设置构建级别的四个可选项
  set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
    "MinSizeRel" "RelWithDebInfo")
endif()

project (build_type)
add_executable(cmake_examples_build_type main.cpp)

CMake 命令行中设置构建类型:

cmake .. -DCMAKE_BUILD_TYPE=Release #生成命令行时指定

注意使用了 cmake 获取使用的命令行标志 “-D”。 也可以写成:

cmake … -D CMAKE_BUILD_TYPE=Release


**构建级别:**
- Release —— 不可以打断点调试,程序开发完成后发行使用的版本,占的体积小。它对代码做了优化,因此速度会非常快。
在编译器中使用命令:`-O3 -DNDEBUG` **可选择此版本**;
- Debug ——调试的版本,体积大。
在编译器中使用命令:`-g` 可选择此版本;
- MinSizeRel —— 最小体积版本。
在编译器中使用命令:`-Os -DNDEBUG` 可选择此版本;
- RelWithDebInfo —— 既优化又能调试。
在编译器中使用命令:`-O2 -g -DNDEBUG` 可选择此版本。

```c
set(<variable> <value>... [PARENT_SCOPE])

7. 如何设置编译方式呢?

CMakeLists.txt 文件如下:

cmake_minimum_required(VERSION 3.5)
project (compile_flags)
add_executable(cmake_examples_compile_flags main.cpp)
#为可执行文件添加私有编译定义
target_compile_definitions(cmake_examples_compile_flags #建议使用
    PRIVATE EX3
)

对于编译器选项,还可以使用 target_compile_options() 函数。

target_compile_definitions(<target>
   <INTERFACE|PUBLIC|PRIVATE> [items1...] )
  • target 指的是由 add_executable() 产生的可执行文件或 add_library() 添加进来的库;
  • <INTERFACE|PUBLIC|PRIVATE> 指的是 [items...] 选项可以传播的范围;
  • PUBLIC and INTERFACE 会传播 <target> 的 INTERFACE_COMPILE_DEFINITIONS 属性;
  • PRIVATE and PUBLIC 会传播 <target> 的 COMPILE_DEFINITIONS 属性。

8. 最终例子

CMakeLists.txt 文件如下:

cmake_minimum_required(VERSION 3.0.2)
project(slam2d)
## Compile as C++11, supported in ROS Kinetic and newer
# add_compile_options(-std=c++11)

set(CMAKE_BUILD_TYPE "Release")
set(CMAKE_CXX_FLAGS  "-std=c++14")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -Wall -g")

## Find catkin macros and libraries
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
## is used, also find other catkin packages
find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  sensor_msgs
  std_msgs
  rosbag
  tf
)

## System dependencies are found with CMake's conventions
find_package(Eigen3)
find_package(Ceres)
find_package(PCL)
find_package(OpenCV REQUIRED)

###################################
## catkin specific configuration ##
###################################
catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES slam2d
 CATKIN_DEPENDS nav_msgs roscpp rospy sensor_msgs std_msg tf
 DEPENDS EIGEN3 PCL
)

###########
## Build ##
###########

include_directories(
# include
  src
  ${catkin_INCLUDE_DIRS}
  ${PCL_INCLUDE_DIRS}
  ${EIGEN3_INCLUDE_DIR}
  ${OpenCV_INCLUDE_DIRS}
)

add_executable(slam2d_node  src/slam2d_node.cpp)
target_link_libraries(slam2d_node 
					 ${catkin_LIBRARIES} 
				 	 ${CERES_LIBRARIES} 
					 ${PCL_LIBRARIES} 	     
					 ${OpenCV_LIBS}
)
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要在 Pointcloud 中调用 tracker.cpp,需要做以下更改: 1. 在 Pointcloud 目录下的 CMakeLists.txt 文件中添加一个新的可执行文件 target,用于编译 tracker.cpp: ```cmake add_executable(pointcloud pointcloud.cpp utils.h obstacle_detector.cpp obstacle_detector.h) add_executable(tracker tracker/tracker.cpp tracker/obstacle_detector.cpp tracker/obstacle_detector.h tracker/utils.h tracker/track/track.cpp tracker/track/obstacle_detector.cpp tracker/track/obstacle_detector.h tracker/track/kalman.cpp tracker/track/kalman.h) add_executable(munkres tracker/munkres/munkres.cpp tracker/munkres/matrix.cpp tracker/munkres/matrix.h) ``` 2. 如果 tracker.cpp 依赖于 pointcloud.cpp 或者 obstacle_detector.cpp,那么需要将这些文件添加到 target 的源文件列表中: ```cmake add_executable(tracker tracker/tracker.cpp tracker/obstacle_detector.cpp tracker/obstacle_detector.h pointcloud.cpp obstacle_detector.cpp) ``` 3. 如果 tracker.cpp 还依赖于其他的头文件或库,需要添加相应的包含路径和链接库路径: ```cmake include_directories(/path/to/include) # 添加头文件包含路径 link_directories(/path/to/lib) # 添加链接库路径 target_link_libraries(tracker library_name) # 链接所需的库 ``` 请根据实际情况修改上述路径和库名称,然后再次运行 cmake 和 make 命令来重新编译项目。这样就可以生成 Pointcloud、Tracker 和 Munkres 三个可执行文件,并且 Pointcloud 中可以调用 tracker.cpp。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值