查看cmake版本: cmake --version
,Ubuntu自带的是3.5.1
cmake和qmake都用于产生Makefile,然后执行make
命令进行编译,make还有其他参数,叫做make目标
升级 CMake 1 2 3 4 5 6 7 8 9 sudo apt-get install -y build-essential libssl-dev wget https: tar -zxvf cmake-3.19 .2 .tar.gz cd cmake-3.19 .2 / ./bootstrap make sudo make install hash -r cmake --version
报错: Could not find CMAKE_ROOT !!! CMake has most likely not been installed correctly. 先执行hash -r
再使用
还可参考: cmake源码安装 安装CMake和cmake-gui ,
cmake-gui 在where is the source code
里选择源代码位置,在where to build the binaries
里选择编译出的文件,一般是在源代码目录里新建build
文件夹。
先点一次Configure
,出现配置对话框,选默认或者交叉编译(最后一个选项)。如果出现红色区域,再点一次。直到没有红色区域之后,点击configure
,配置完成后点击generate
,会在build文件夹下生成工程文件,然后去build文件夹里执行make
常见的make目标 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 make all:编译程序、库、文档等(等同于make) make install:安装已经编译好的程序,会默认把程序安装至 /usr/local /bin make unistall:卸载已经安装的程序。 make clean:删除由make命令产生的文件(例如object file,*.o) make -j N : 同时允许N个任务进行,如果不指定N则进行无限个任务,结果会将CPU性能榨干。N的最大值取决于CPU性能,不要把N设置太大,更不要不指定,否则可能死机。 make check:测试刚刚编译的软件(某些程序可能不支持,有时会测试很长时间,这就没有必要) make -i: 忽略指令执行错误,并继续执行,且如果出错的话就会生成目标文件。这个一般用在调试的时候。 make -k: 出错也不停止运行,不仅可以忽略指令错误,而且还能忽略makefile规则错误
注释方法 : CMake 3.0以上版本的多行注释:从#[[
开始,在块注释的另一端以]]
结束。但是并不好用,似乎和Tab对齐有关。
语法规则:
变量使用${}方式取值, 但是在IF控制语句中是直接使用变量名
环境变量使用$ENV{}方式取值, 使用SET(ENV{VAR} VALUE)赋值
指令(参数1 参数2…) 参数使用括弧括起, 参数之间使用空格或分号分开
有时候看到一些工程有一个cmake
文件夹,里面放几个cmake文件,打开发现是一些cmake的命令。这是因为工程规模太大,有些库比如PCL在每个CMakeLists
里使用,每次都添加太麻烦,所以做成文件形式,在用到的时候在CMakeLists
里 include(cmake/PCL.cmake)
基本规则 预定义变量,设置方式是set(VARIABLE value)
,大小写都是敏感的,可以用message函数查看:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 PROJECT_NAME PROJECT_SOURCE_DIR PROJECT_BINARY_DIR CMAKE_CURRENT_SOURCE_DIR EXECUTABLE_OUTPUT_PATH LIBRARY_OUTPUT_PATH CMAKE_MAJOR_VERSION CMAKE_MINOR_VERSION CMAKE_PATCH_VERSION CMAKE_SYSTEM CAMKE_SYSTEM_NAME UNIX WIN32 BUILD_SHARED_LIBS CMAKE_C_COMPILER/CMAKE_CXX_COMPILER CMAKE_CXX_FLAGS CMAKE_BUILD_TYPE BUILD_SHARED_LIBS
add_compile_options 下面的代码里,foo
不会按照-Wall
编译,但是bar
会。1 2 3 add_library(foo ...) add_compile_options(-Wall 03) add_library(bar ...)
-Wall
显示所有警告。O3
(字母O)是编译优化的程度选择,有O1 O2 O3。数字越大编译优化越多,程序执行速度越快 但编译时间越长,不过一般程序看不出来。
CMAKE_CXX_STANDARD CMake 3.1或者更高版本可使用set(CMAKE_CXX_STANDARD 11)
,不能用17
最好把add_compile_options(-std=c++17)
改为跨平台的写法: set(CMAKE_CXX_STANDARD 17)
,也就是x86
跨arm
平台
一般第三方库里都有个configure
文件,它是个Shell脚本,内容很多../configure 是用来检测你的安装平台的目标特征的,比如它会检测你是不是有CC或GCC。主要功能是生成 Makefile,为下一步的编译做准备,你可以通过在./configure
后加上参数来对安装进行控制,比如./configure --prefix=/usr
是将该软件安装在 /usr 下面,执行文件就会安装在/usr/bin
(而不是默认的 /usr/local/bin
),资源文件就会安装在 /usr/share
(而不是默认的/usr/local/share)
message函数 1 2 3 message(STATUS "12345" ) message(STATUS " include dirs: ${catkin_INCLUDE_DIRS} " ) message(STATUS " include dirs:" ${catkin_INCLUDE_DIRS} )
如果在执行cmake时,遇到一个错误情况需要停止执行,可以用FATAL_ERROR
:1 2 3 if( SOME_COND ) message( FATAL_ERROR "You can not do this at all, CMake will exit." ) endif()
如果出现这种情况还要继续编译,那么就换成SEND_ERROR
指令最好全用大写 路径名中不要用\,而是用/,例如include_directories(F:/Eigen)
常用命令 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 CMAKE_MINIMUM_REQUIRED(VERSION 3.3) PROJECT add_compile_options(-std=c++11) set (CMAKE_BUILD_TYPE "Release" ) if (CMAKE_BUILD_TYPE STREQUAL "Release" ) message(STATUS "build type is Release" ) endif() include_directories link_directories ADD_EXECUTABLE(bin_file_name ${SRC_FILES} ) add_definitions ADD_LIBRARY link_libraries(lib1 lib2) SET_TARGET_PROPERTIES ADD_SUBDIRECTORY
获取环境变量 获取bash.rc中的环境变量,通过ENV前缀来访问环境变量,读取环境变量使用$ENV{JAVA_HOME}
,查看环境变量:1 message(STATUS " java home: $ENV{JAVA_HOME}" )
写环境变量如下:1 set( ENV{PATH} /home/martink )
cmake判断操作系统和架构 1 2 3 4 5 6 7 8 9 10 11 12 13 14 message(${CMAKE_HOST_SYSTEM_NAME}) message(${CMAKE_HOST_SYSTEM_PROCESSOR}) if (CMAKE_HOST_SYSTEM_NAME MATCHES "Linux" ) message("this is Linux" ) elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Android" ) message("this is Android" ) endif() if (CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "aarch64" ) message("this is aarch64 cpu" ) elseif(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "x86_64" ) message("this is x86_64 cpu" ) endif()
获得include的文件路径 1 2 3 4 5 6 include_directories( include /usr/include/eigen3 ) get_property(dirs DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES) MESSAGE("include path: ${dirs} " )
指定生成文件的输出路径 使用SET命令重新定义EXECUTABLE_OUTPUT_PATH
和LIBRARY_OUTPUT_PATH
变量来指定最终的二进制文件的位置1 2 SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
上面的两条命令通常紧跟ADD_EXECUTABLE
和ADD_LIBRARY
,与其写在同一个CMakeLists.txt即可
include_directories 和 target_include_directories 都是添加头文件搜索路径。差别:
PRIVATE
:target对应的源文件使用PUBLIC
:target对应的头文件、源文件都使用
如果有不同目录相同名称的头文件会产生影响,所以这里建议针对特定的 target 使用 target_include_directories
参考:CMake基本教程 子工程和链接静态库 CMake使用进阶