前言
我们使用 Make
工具构建项目时,需要编写 Makefile
,但不同的平台 Make
工具是不一样的,比如Linux
的GNU Make
,Windows
的 nmake
,它们对 Makefile
的规范也是不一样的,如果软件要跨平台,则需要针对每一种 Make
工具写一份 Makefile
,非常浪费时间
而且当软件比较庞大时,Makefile
的编写也会变的复杂。
CMake 简介
CMake(Cross-Platform-Make
)是一个开源、跨平台的软件构建工具,它使用与平台独立的配置文件来对软件编译过程进行控制,根据用户所需,生成 Makefile
或者IDE
的project。
CMake 构建过程
编写
CMake
配置文件CMakeLists.txt
,一般放在项目的最顶层目录下运行
cmake
命令,参数为CMakeLists.txt
所在根路径,执行完成后得到Makefile
文件。使用
make
命令进行编译。1
2
3mkdir -p build && cd build
cmake ..
make
cmake基本语法
指定最小版本
如果使用的
CMake
版本低于该版本,则会发出致命错误1
cmake_minimum_required(VERSION 3.9)
设置工程名 可以同时指定工程版本和语言,
CXX
代表C++
1
project(sunflower VERSION 0.0.1 LANGUAGES C CXX)
单行注释
1
# 我是注释
多行注释
1
2
3#[[我是多行注释
我是多行注释
]]设置
c/c++
版本1
2set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 11)设置编译选项
1
2set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -w -O3")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -w -O3")添加宏定义
1
add_definitions(-DSPDLOG_ACTIVE_LEVEL=SPDLOG_LEVEL_INFO)
设置头文件搜索目录
实现编译时的
[-I]
选项,设置后引用头文件不需要使用相对路径,直接引用文件名1
2
3
4
5include_directories(
"${PROJECT_SOURCE_DIR}/include"
"${PROJECT_SOURCE_DIR}/depends/json/"
"${PROJECT_SOURCE_DIR}/depends/leveldb/include"
)设置库文件搜索目录
实现编译时的[-L]选项,项目内部明确路径的库文件,可以通过该命令指定
1
2
3
4link_directories(
"${PROJECT_SOURCE_DIR}/depends/json/lib"
"${PROJECT_SOURCE_DIR}/depends/leveldb"
)查找指定库文件
查找到指定的预编译库,并将它的路径存储在变量中。
默认的搜索路径为
cmake
包含的系统库,因此如果是NDK
的公共库只需要指定库的name
即可(不需path
),类似的命令还有find_file()
、find_path()
、find_program()
、find_package()
1
find_library(log-lib,log)
查找指定目录下源文件
获取指定目录下源文件列表,保存到DIR_SRCS
变量中,后续编译构建目标可执行文件注意这里不能递归获取子目录下的源文件
1
aux_source_directory(${PROJECT_SOURCE_DIR}/src DIR_SRCS)
添加子目录源文件
使用命令add_subdirectory
指明本项目包含一个子目录,这样子目录下的 CMakeLists.txt
文件和源文件也会被处理。项目包含多个子目录时,通常可以在子目录下也定义
CMakeLists.txt
文件,并通过add_library
生成包含子目录源码的库文件,并最终链接到目标可执行文件1
2add_subdirectory(utils)
add_subdirectory(config)递归查找目录下的所有源文件
可以通过file
命令递归获取指定目录下的所有源文件,这样可以不用为子目录专门定义CMakeLists.txt
,也不需要通过链接的方式集成各个子目录,而是统一编译构建1
2
3
4
5file(GLOB_RECURSE DIR_SRCS
${PROJECT_SOURCE_DIR}/src/*.c
${PROJECT_SOURCE_DIR}/src/*.cc
${PROJECT_SOURCE_DIR}/src/*.cpp
)设置可执行文件输出路径
1
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
生成可执行文件
1
add_executable(${PROJECT_NAME} ${DIR_SRCS})
生成库文件
1
2add_library(${PROJECT_NAME} STATIC ${DIR_SRCS})
add_library(${PROJECT_NAME} SHARED ${DIR_SRCS})链接库文件
1
2
3
4
5
6
7set(EXTRA_LIBS
sasl2
libleveldb.a
)
target_link_libraries(${PROJECT_NAME}
${EXTRA_LIBS}
)
常用变量
1 | PROJECT_SOURCE_DIR:工程的根目录 |
自定义变量
使用SET
, 比如:
1 | set(BINARY_NAME "juce_jni") |
支持 Debug 版本
设置不同版本的编译选项
1
2set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")
set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")cmake 时指定版本
1
2cmake .. -DCMAKE_BUILD_TYPE=Debug
cmake .. -DCMAKE_BUILD_TYPE=Release
完整示例
工程结构
1 | +-- CMakeTest |
CMakeList.txt
1 | cmake_minimum_required(VERSION 3.7.1) |
本文转载自: CSDN