CMake 入门
本文最后更新于:2021年1月23日 下午
概述
CMake is an open-source, cross-platform family of tools designed to build, test and package software. CMake is used to control the software compilation process using simple platform and compiler independent configuration files, and generate native makefiles and workspaces that can be used in the compiler environment of your choice. The suite of CMake tools were created by Kitware in response to the need for a powerful, cross-platform build environment for open-source projects such as ITK and VTK. https://cmake.org/
入门
我们先用 CMake
来构建一个简单的 c
程序。
创建 helloworld
文件夹,然后进入这个文件夹,在里边创建一下文件:
.
├── CMakeLists.txt
└── main.c
CMakeLists.txt
是 CMake
的配置文件。main.c
是 c
程序的源文件。
main.c
1 |
|
CMakeLists.txt
1 |
|
执行 cmake ..
进行构建,执行 make
构建 生成后的Makefile 文件。
优化目录结构
新的目录结构如下:
1 |
|
CMakeLists.txt
1 |
|
src/CMakeLists.txt
1 |
|
lib/CMakeLists.txt
1 |
|
src/main.c
1 |
|
lib/zsf_math.h
1 |
|
lib/zsf_math.c
1 |
|
判断语句与循环语句
if 判断语句
CMake 支持 if 语句。非零为真
例子1:
1 |
|
例子2
1 |
|
例子3
1 |
|
变量列表
- CMAKE_INSTALL_PREFIX
命令列表
- cmake_minimum_required(VERSION 3.5)
- project(zsf_Hello C)
- add_executable(zsf_Hello main.c)
- add_subdirectory(./lib)
- add_library(zsfMath STATIC ${DIR_SRC})
- add_definitions(-DFOO -DTEST)
- include_directories(${PROJECT_SOURCE_DIR}/lib)
- aux_source_directory(. DIR_SRC)
- set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
- set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
- file()
- set_target_properties()
- message([STATUS|WARNING|AUTHOR_WARNING|FATAL_ERROR|SEND_ERROR]
“message to display” …) - INSTALL()
set_property()
1 |
|
set_target_properties()
SET_TARGET_PROPERTIES
,其基本语法是:
1 |
|
这条指令可以用来设置输出的名称,对于动态库,还可以用来指定动态库版本和API版本。
在本例中,我们需要作的是向lib/CMakeLists.txt
中添加一条:SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello")
这样,我们就可以同时得到libhello.so/libhello.a
两个库了。
GET_TARGET_PROPERTY(VAR target property)
GET_TARGET_PROPERTY(VAR target property)
具体用法如下例,我们向lib/CMakeListst.txt
中添加:
1 |
|
如果没有这个属性定义,则返回NOTFOUND
.
message()
函数原型
message( [STATUS|WARNING|AUTHOR_WARNING|FATAL_ERROR|SEND_ERROR]
“message to display” …)
1 |
|
例子:
1 |
|
安装命令 INSTALL
1 |
|
参数中的TARGETS
后面跟的就是我们通过ADD_EXECUTABLE
或者ADD_LIBRARY
定义的
目标文件,可能是可执行二进制、动态库、静态库。
目标类型也就相对应的有三种,ARCHIVE特指静态库,LIBRARY特指动态库,RUNTIME
特指可执行目标二进制。
DESTINATION
定义了安装的路径,如果路径以/开头,那么指的是绝对路径,这时候CMAKE_INSTALL_PREFIX
其实就无效了。如果你希望使用CMAKE_INSTALL_PREFIX
来
定义安装路径,就要写成相对路径,即不要以/
开头,那么安装后的路径就是${CMAKE_INSTALL_PREFIX}/<DESTINATION定义的路径>
1 |
|
上面的例子会将:
可执行二进制myrun
安装到${CMAKE_INSTALL_PREFIX}/bin
目录
动态库libmylib
安装到${CMAKE_INSTALL_PREFIX}/lib
目录
静态库libmystaticlib
安装到${CMAKE_INSTALL_PREFIX}/libstatic
目录
特别注意的是你不需要关心TARGETS
具体生成的路径,只需要写上TARGETS
名称就可以
了。
普
1 |
|
可用于安装一般文件,并可以指定访问权限,文件名是此指令所在路径下的相对路径。如果
默认不定义权限PERMISSIONS
,安装后的权限为:OWNER_WRITE
, OWNER_READ
, GROUP_READ
,和WORLD_READ
,即644
权限。
1 |
|
跟上面的FILES
指令使用方法一样,唯一的不同是安装后权限为:OWNER_EXECUTE
, GROUP_EXECUTE
, 和WORLD_EXECUTE
,即755
权限
1 |
|
这里主要介绍其中的DIRECTORY
、PATTERN
以及PERMISSIONS
参数。DIRECTORY
后面连接的是所在Source
目录的相对路径,但务必注意:abc
和abc/
有很大的区别。
如果目录名不以/
结尾,那么这个目录将被安装为目标路径下的abc
,如果目录名以/
结尾,
代表将这个目录中的内容安装到目标路径,但不包括这个目录本身。PATTERN
用于使用正则表达式进行过滤,PERMISSIONS
用于指定PATTERN
过滤后的文件
权限。
我们来看一个例子:
1 |
|
这条指令的执行结果是:
将icons
目录安装到 <prefix>/share/myproj
,将scripts/
中的内容安装到<prefix>/share/myproj
不包含目录名为CVS
的目录,对于scripts/*
文件指定权限为 OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ.
安装时CMAKE脚本的执行:INSTALL([[SCRIPT <file>] [CODE <code>]] [...])
SCRIPT
参数用于在安装时调用cmake脚本文件(也就是<abc>.cmake
文件)CODE
参数用于执行CMAKE
指令,必须以双引号括起来。比如:INSTALL(CODE "MESSAGE(\"Sample install message.\")")
安装还有几个被标记为过时的指令,比如INSTALL_FILES
等,这些指令已经不再推荐使
用,所以,这里就不再赘述了。
动态库版本号
按照规则,动态库是应该包含一个版本号的,我们可以看一下系统的动态库,一般情况是
1 |
|
为了实现动态库版本号,我们仍然需要使用SET_TARGET_PROPERTIES
指令。
具体使用方法如下:SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1)
VERSION
指代动态库版本,SOVERSION
指代API
版本。
将上述指令加入lib/CMakeLists.txt
中,重新构建看看结果。
在build/lib
目录会生成:
1 |
|
终端实例
1 |
|
CMake模块
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!