cmake 备忘

automake 系列工具友好性的确不咋地,而且只限于 *inux 平台。跨平台还是 cmake 为佳,也有越来越多的项目在使用 cmake,比如 google 的 gRPC,比如 zlib 也支持 cmake。

如果只是说要编译三方库为自己所用,一般来说不需要掌握怎么编写 CMakeLists.txt;只有当自己的项目需要用 cmake 管理、组织编译时才需要弄懂 CMakeLists.txt 中的“语言”怎么编写。

使用 cmake

mkdir build && cd build && cmake .. && cmake --build . --target install

cmake --build . 在 linux 下等价于 make,在 windows 下等同于 msvc 生成解决方案

外部编译

mkdir build && cd build && cmake ..

就是让源码文件和 cmake 生成的工程文件分开,将 cmake 生成的工程文件放在一个单独的目录下面。

坚持使用 build 目录,进行外部编译。以避免在源码目录中混杂垃圾文件。

生成器 generator -G

cmake -G "<generator>" -DCMAKE_INSTALL_PREFIX=stage ..

cmake-generators 文档 描述

Command-Line Build Tool Generators

……

IDE Build Tool Generators

These generators support Integrated Development Environment (IDE) project files. Since the IDEs configure their own environment one may launch CMake from any environment.

Visual Studio Generators

VS 2017 supports multiple installations on the same machine. The CMAKE_GENERATOR_INSTANCE variable may be set as a cache entry containing the absolute path to a Visual Studio instance. If the value is not specified explicitly by the user or a toolchain file, CMake queries the Visual Studio Installer to locate VS instances, chooses one, and sets the variable as a cache entry to hold the value persistently.

Platform Selection -A

The CMAKE_GENERATOR_PLATFORM variable may be set, perhaps via the cmake(1) -A option, to specify a target platform name (architecture)1. For example:

  • cmake -G "Visual Studio 14 2015" -A Win32 / cmake -G "Visual Studio 15 2017" -A Win32
  • cmake -G "Visual Studio 14 2015" -A x64 / cmake -G "Visual Studio 15 2017" -A x64
  • cmake -G "Visual Studio 14 2015" -A ARM / cmake -G "Visual Studio 15 2017" -A ARM
  • cmake -G "Visual Studio 15 2017" -A ARM64

For compatibility with CMake versions prior to 3.1, one may specify a target platform name optionally at the end of the generator name. This is supported only for:

  • Visual Studio 14 2015 Win64 / Visual Studio 15 2017 Win64, Specify target platform x64.
  • Visual Studio 14 2015 ARM / Visual Studio 15 2017 ARM, Specify target platform ARM.

sup 1Supported Platforms (Visual C++)

Toolset Selection -T

The v140 toolset that comes with Visual Studio 14 2015 is selected by default. The CMAKE_GENERATOR_TOOLSET option may be set, perhaps via the cmake(1) -T option, to specify another toolset.

The v141 toolset that comes with Visual Studio 15 2017 is selected by default.

For each toolset that comes with this version of Visual Studio, there are variants that are themselves compiled for 32-bit (x86) and 64-bit (x64) hosts (independent of the architecture they target). By default Visual Studio chooses the 32-bit variant even on a 64-bit host. One may request use of the 64-bit host tools by adding a host=x64 option to the toolset specification. See the CMAKE_GENERATOR_TOOLSET variable for details.

针对 MSVC 总结:三种或四种平台,桌面开发主要针对 win32 和 x64;工具集基本对应 MSVC 版本,高版本 MSVC 可选择低版本的工具集;另外,还有个平台版本(即 SDK version),似乎在 cmake 中并不重要。

安装各版本的平台工具集:VS2010 之后版本的 VS 都有这个功能, 可以通过切换平台工具集, 在使用最新的 IDE 的同时, 用旧版本来进行编译, 彻底杜绝兼容问题2摘自

sup 2: MSVC 各版本之间的兼容问题是个老梗了,ε=(´ο`*)))唉,不过 v141 is binary compatible with v140

Extra Generators

……

增删变量 -D

-D<var>:<type>=<value> 添加变量及值到 CMakeCache.txt 中。注意 -D 后面不能有空格,type 为 string 时可省略。例如:cmake -DCMAKE_BUILD_TYPE:STRING=Debug。MinGW Generator 默认生成 CMAKE_BUILD_TYPE 为空,即 release;NMake Generator默认生成 CMAKE_BUILD_TYPE 为 Debug。

-U<globbing_expr> 删除 CMakeCache.txt 中的变量。注意 -U 后面不能有空格,支持 globbing 表达式,比如 *,? 等。例如:cmake -UCMAKE_BUILD_TYPE

编译模式

1
2
cmake .. -G "Visual Studio 14 2015" -DCMAKE_INSTALL_PREFIX="install_root" # -DCMAKE_BUILD_TYPE="Release"
cmake --build . --target install --config Release

如果前一条命令不指定 -DCMAKE_BUILD_TYPE="Release",只是单独在第二条命令中 --config=Release,会造成什么后果?无任何后果。当使用 MSVC 时,CMAKE_BUILD_TYPE 选项被忽略

Specifies the build type on single-configuration generators. CMAKE_BUILD_TYPE 的意义

This variable is only meaningful to single-configuration generators (such as Makefile Generators and Ninja) i.e. those which choose a single configuration when CMake runs to generate a build tree as opposed to multi-configuration generators which offer selection of the build configuration within the generated build environment.

调试版本后缀

1
2
-DCMAKE_DEBUG_POSTFIX="d"
# -DCMAKE_RELEASE_POSTFIX=xx

MT 和 MD

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 1. 追加 `CMAKE_CXX_FLAGS_Build Type`
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")

# 2. 替换 `CMAKE_CXX_FLAGS_Build`
set(CMAKE_CXX_FLAGS_RELEASE "/MT")
set(CMAKE_CXX_FLAGS_DEBUG "/MTd")

# 3. 或者将已经存在的 `/MD、/MDd` 替换为 `/MT、/MTd`
if (MSVC)
set(CompilerFlags
CMAKE_CXX_FLAGS
CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_RELEASE
CMAKE_C_FLAGS
CMAKE_C_FLAGS_DEBUG
CMAKE_C_FLAGS_RELEASE
)
foreach(CompilerFlag ${CompilerFlags})
string(REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}")
endforeach()
endif(MSVC)

摘自:https://blog.csdn.net/frank_liuxing/article/details/74010939

原文描述提到“如果CMAKE Flags已经设置了/MD,可以不能发挥作用。可以采用方法2” 但很可能是错误的,后者覆盖前者:

If your CMake flags already contain /MD, you can ensure that the above commands are executed after the point at which /MD is inserted (the later addition of /MT overrides the conflicting existing option) 来自 stackoverflow

安装路径

-DCMAKE_INSTALL_PREFIX

其他参数

清理之后重新构建、编译

当出现 xx 等无法理解的问题时(尤其是在同一目录下同时编译 Debug 和 Release 版本时出现依赖库异常时),尝试删除 cmake 临时文件(CMakeCache.txt CMakeFiles\ 等)所在目录,再次执行试试

cmake-gui

编写 CMakeLists.txt