传统的CMake构建安装
回顾:
PUBLIC 表示链接库不仅会应用于当前目标,还会传递给依赖于当前目标的其他目标。 PRIVATE 表示链接库仅应用于当前目标。
INTERFACE 表示链接库仅适用于依赖于当前目标的其他目标,而不适用于当前目标本身。
目录:
/usr/bin 系统预装的程序
usr/local 用户安装的软件默认位置
usr/local/src 用户编译软件时所用源码的存放位置
现代CMake
cmake -B build -DCMAKE_INSTALL_PREFIX=/temp/test
创建build目录并生成build/Makefile,这里设置CMAKE_INSTALL_PREFIX变量来决定make install的位置
-G指定生成器
例如使用Ninja:
安装Ninja构建工具:sudo apt install ninja-build
使用Ninja进行构建:cmake … -G Ninja
生成可执行文件:cmake --build . --parallel 4
添加可执行文件作为构建目标
方法1:直接写
add_executable(main main.cpp)
方法2:先创建目标,再添加源文件
add_executable(main)
target_sources(main PUBLIC main.cpp other.cpp)
方法3:使用GLOB自动查找当前目录下指定扩展名的文件,实现批量添加源文件.
最好是启用CONFIGURE_DEPENDS选项,添加新文件时会自动更新变量
cmake_minimum_required(VERSION 3.10)
project(yx)
file(GLOB sources CONFIGURE_DEPENDS *.cpp *.h)
add_executable(main ${sources})
方法4:使用GLOB_RECURSE可以包含所有子文件夹下的文件
为了避免将build目录里临时生成的cpp也加进来,建议把源码都放在src目录下
方法5:aux_source_directory自动根据指定的目录搜集需要的文件,不用写后缀名了
aux_source_directory(. sources)就是把当前目录下需要的文件搜集到sources变量中
CMAKE_BUILD_TYPE控制构建类型
默认空字符串,相当于Debug调试模式
其它模式:Release、MinSizeRel、RelWithDebInfo,这3种模式都定义了NDEBUG宏,会导致assert被去掉
使用:set(CMAKE_BUILD_TYPE Release)
大多数项目为了默认为Release模式,CMakeLists中会写如下三行
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
NDEBUG宏的使用
在CMakeLists中写上add_definitions(-DNDEBUG),即定义了NDEBUG宏
这样对于下面的test.cpp,assert不起作用,输出xx
#include <iostream>
#include <cassert>
int main()
{
int m=3;
#ifdef NDEBUG
std::cout<<"xx"<<std::endl;
#else
std::cout<<"yy"<<std::endl;
#endif
assert(m == 2);
return 0;
}
几个目录
PROJECT_SOURCE_DIR:最近一次调用project命令的CMakeLists所在目录
CMAKE_CURRENT_SOURCE_DIR:当前CMakeLists所在目录
CMAKE_SOURCE_DIR:最最外层CMakeLists所在目录
PROJECT_SOURCE_DIR与CMAKE_CURRENT_SOURCE_DIR的区别:如果当前CMake里没有project指令,那么就找当前的上一层,如果上一层有,那么PROJECT_SOURCE_DIR是上一层的所在目录
PROJECT_BINARY_DIR:当前项目的输出路径,存放main.exe
CMAKE_CURRENT_BINARY_DIR:当前输出路径
CMAKE_BINARY_DIR:根项目输出路径
project的languages
:默认C和CXX
project(yx LANGUAGES C CXX)
设置c++标准
:不要使用target_compile_options来添加-std=c++17,因为-std只是gcc的选项,无法跨平台。
正确设置方法:set(CMAKE_CXX_STANDARD 17)
检测到不支持上述标准时会报错:set(CMAKE_CXX_STANDARD_REQUIRED ON)
不使用GCC特性,避免移植到MSVC上出错:set(CMAKE_CXX_EXTENSIONS OFF)
避免Windows.h的max宏与std::max冲突
使用add_definitions为编译器添加预定义的宏定义
if(WIN32)
add_definitions(-DNOMINMAX -D_USE_MATH_DEFINES)
endif()
示例模板
示例模板
cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
project(yx LANGUAGES C CXX)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
if(WIN32)
add_definitions(-DNOMINMAX -D_USE_MATH_DEFINES)
endif()
if(NOT MSVC)
find_program(CCACHE_PROGRAM ccache)
if(CCACHE_PROGRAM)
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${
CCACHE_PROGRAM})
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ${
CCACHE_PROGRAM})
endif()
endif()
aux_source_directory(. sources)
add_executable(main ${
sources})
链接静态库文件
├── CMakeLists.txt
├── test.cpp
└── threes
├── CMakeLists.txt
├── helper.cpp