阅读导引
- 1.cmake简介
- 2.cmake语法
- 3.构建方式
- 4.CMAKE_EXPORT_COMPILE_COMMANDS选项
- 5.CMake命令
- 5.1 cmake_minimum_required 命令
- 5.2 project 命令
- 5.3 set命令
- 5.4 message命令
- 5.5 find_package命令
- 5.6 include_directories命令
- 5.7 add_executable命令
- 5.8 add_library命令
- 5.9 target_link_libraries 命令
- 6.补充
1.cmake简介
CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性。CMake的所有的语句都写在CMakeLists.txt的文件中。
2.cmake语法
- 变量使用${}方式取值,但是在 IF 控制语句中是直接使用变量名;
- 指令(参数 1 参数 2…),参数使用括弧括起,参数之间使用空格或分号分开;
- 指令是大小写无关的,参数和变量是大小写相关的。但推荐你全部使用大写指令。
- 以#开头,到行末尾的是注释
- cmake的构建指令为"cmake path [参数选项]"
3.构建方式
cmake有两种构建方式
1.内部构建
cmake .
make
2.外部构建
推荐使用
mkdir build
cd build
cmake ..
make
两种方法最大的不同在于执行cmake和make的工作路径不同。
第一种方法中,cmake生成的所有中间文件和可执行文件都会存放在项目目录中;称为“内部构建”。而第二种方法中,中间文件和可执行文件都将存放再build目录中。
第二种方法的优点显而易见,它最大限度的保持了代码目录的整洁。同时由于第二种方法的生成、编译和安装是发生在不同于项目目录的其他目录中,所以第二种方法就叫做“外部构建”。cmake强烈推荐使用外部构建的方法。
4.CMAKE_EXPORT_COMPILE_COMMANDS选项
默认不开启,开启的两种方法:
在CMakeLists.txt中添加 set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
在命令行中添加-DCMAKE_EXPORT_COMPILE_COMMANDS=on
开启后,其生成的文件compile_commands.json,包含所有编译单元所执行的指令,简单理解,就是一个保存编译链接过程的详细信息的文件
如下所示:
[
{
"directory": "/home/cheng/Downloads/location_detection/2bu",
"command": "/usr/bin/c++ -I/home/cheng/Downloads/location_detection/include -I/home/cheng/somelib/libtorch/include -std=c++14 -O2 -msse4 -g -o CMakeFiles/location_detection.dir/src/cotek_location_detection.cc.o -c /home/cheng/Downloads/location_detection/src/cotek_location_detection.cc",
"file": "/home/cheng/Downloads/location_detection/src/cotek_location_detection.cc"
},
{
"directory": "/home/cheng/Downloads/location_detection/2bu",
"command": "/usr/bin/c++ -DAT_PARALLEL_OPENMP=1 -I/home/cheng/Downloads/location_detection/include -isystem /home/cheng/somelib/libtorch/include -isystem /home/cheng/somelib/libtorch/include/torch/csrc/api/include -isystem /usr/local/include/opencv -std=c++14 -O2 -msse4 -g -D_GLIBCXX_USE_CXX11_ABI=1 -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wno-write-strings -Wno-unknown-pragmas -Wno-missing-braces -fopenmp -o CMakeFiles/detection.dir/src/cotek_detection_node.cc.o -c /home/cheng/Downloads/location_detection/src/cotek_detection_node.cc",
"file": "/home/cheng/Downloads/location_detection/src/cotek_detection_node.cc"
}
]
5.CMake命令
5.1 cmake_minimum_required 命令
如下所示
cmake_minimum_required(VERSION 3.1.0)
该命令规定了cmake程序的最低版本。这行命令是可选的,我们可以不写这句话,但在有些情况下,如果CMakeLists.txt文件中使用了一些高版本cmake特有的一些命令的时候,就需要加上这样一行,提醒用户升级到该版本之后再执行cmake。
5.2 project 命令
如下所示
project(location_detection)
制定项目工程的名称,这里注意该名称并不是最后编译完成后生成可执行文件的名称,而是给项目起的命名
,项目最终编译生成的可执行文件名称则是由ADD_EXECUTABLE命令来指定的。
5.3 set命令
SET命令可以用来显式的定义变量。如:
set(CMAKE_BUILD_TYPE "Debug")
代表将 CMAKE_BUILD_TYPE赋值为“Debug”
5.4 message命令
主要用来产生一系列信息,类似与cmake过程中输出的日志,方便我们进行debug调试,可以打印出变量值。
语法message([<mode>] "message text" ...)
mode 的值包括 FATAL_ERROR、WARNING、AUTHOR_WARNING、STATUS、VERBOSE等。
我主要使用其中的 2 个——FATAL_ERROR、STATUS。
FATAL_ERROR
:产生 CMake Error,会停止编译系统的构建过程;
STATUS
:最常用的命令,常用于查看变量值,类似于编程语言中的 DEBUG 级别信息。
"message text"为显示在终端的内容。
如下例子:
message(STATUS "Pytorch status:")
message(STATUS " libraries: ${TORCH_LIBRARIES}")
进行cmake时会打印出
Pytorch status:
-- libraries: torch;torch_library;/home/cheng/somelib/libtorch/lib/libc10.so
5.5 find_package命令
命令是用来查找依赖包的,理想情况下,一句find_package()把一整个依赖包的头文件包含路径、库路径、库名字、版本号等情况都获取到,后续只管用就好了。如下
# 添加torch库
set(CMAKE_PREFIX_PATH /home/cheng/somelib/libtorch/share/cmake/Torch)
find_package(Torch REQUIRED)
find_package(OpenCV 3 REQUIRED)
注意这里我的opencv是通过make && make install 方式安装的,所以cmake回去内部对应的查找opencv,而我的torch并没有安装,只是下载deb包解压了,所以首先需要,找到包含torch的cmake文件,一般在解压的库中,如下地址/home/cheng/somelib/libtorch/share/cmake/Torch
5.6 include_directories命令
如下所示
include_directories(
include
/home/cheng/somelib/libtorch/include
${OpenCV_INCLUDE_DIRS}
/usr/include
)
INCLUDE_DIRECTORIES类似gcc中的编译参数“-I”,指定编译过程中编译器搜索头文件的路径,通常用来指定头文件搜索目录。注意
:如果在cmake过程中,提示你某个.h
文件找不到,多半是这里出问题了,请详细检查该处命令。
5.7 add_executable命令
使用给定的源文件,为工程引入一个可执行文件。如下所示
add_executable(detection src/get.cc)
使用指定的 /src/get.cc 源文件,生成一个名为detection的可执行文件。
5.8 add_library命令
主要作用就是将指定的源文件生成链接文件,然后添加到工程中去。
如下
add_library(${PROJECT_NAME} src/ck_detection.cc)
这里是将, /src/ck_detection.cc源文件生成链接文件,然后取PROJECT_NAME的值,即前面我们定义的location_detection项目,将该链接文件添加到location_detection工程中去。
5.9 target_link_libraries 命令
该指令的作用为将目标文件与库文件进行链接。如下所示
target_link_libraries(
detection
${TORCH_LIBRARIES}
${OpenCV_LIBS}
${DEPENDENCIES}
-lpthread
)
这里的detection 是我们通过add_executable指令生成的已经创建的可执行文件。
6.补充
其他还有很多知识,暂时没用到,上述知识足够构建一个简单的项目了,挖坑,以后补
上述教程完整CMakeLists.txt
cmake_minimum_required(VERSION 3.1.0)
project(location_detection)
set(CMAKE_BUILD_TYPE "Debug")
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_CXX_FLAGS "-std=c++14 -O2 ${SSE_FLAGS} -msse4")
# 添加torch库
set(CMAKE_PREFIX_PATH /home/cheng/somelib/libtorch/share/cmake/Torch)
find_package(Torch REQUIRED)
find_package(OpenCV 3 REQUIRED)
if(NOT Torch_FOUND)
message(FATAL_ERROR "Pytorch not found")
endif(NOT Torch_FOUND)
if(NOT OpenCV_FOUND)
find_package(OpenCV 2.4.3 QUIET)
if(NOT OpenCV_FOUND)
message(FATAL_ERROR "OpenCV > 2.4.3 not found.")
endif()
endif()
message(STATUS "Pytorch status:")
message(STATUS " libraries: ${TORCH_LIBRARIES}")
message(STATUS "OpenCV library status:")
message(STATUS " version: ${OpenCV_VERSION}")
message(STATUS " libraries: ${OpenCV_LIBS}")
message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}")
include_directories(
include
/home/cheng/somelib/libtorch/include
#${OpenCV_INCLUDE_DIRS}
/usr/include
)
#message(">>> include_dirs=${dirs}") #打印一下目录情况
add_executable(detection src/cotek_detection_node.cc)
add_library(${PROJECT_NAME} src/cotek_location_detection.cc)
target_link_libraries(
detection
${PROJECT_NAME}
${TORCH_LIBRARIES}
${OpenCV_LIBS}
${DEPENDENCIES}
-lpthread
)