CMake常见问题

以前写Makefile很多,但是Makefile是类Linux系统的专属编译规则文件,涉及到跨平台(主要是Windows的VC)编译时,现阶段CMake是标配。CMake其实是在linux的makefile和windows的vcproj之上又做了一层,用于生成不同平台的编译规则(或者项目)文件,相当于编译规则的规则,其规则代码是写在CMakeLists.txt里的。

罗列一些常见问题于此:

分离式编译

通常test.c编译的中间文件test.o就会在同一目录,包括最终的可招行结果文件。以往在写Makefile时,还需要专门写个make clean来清理哪些中间文件。CMake一开始就考虑到了保持源代码的干净,这样也方便不同编译参数的结果文件能够并存。所以通常使用CMake时并不是直接make完事,而是在源码目录里先创建一个build目录,接着是:

cd build && cmake .. && make

这样清理中间文件就变得非常简单,直接删除掉build目录就行。

cmake版本不匹配

打开CMakeLists.txt,可能第一条对cmake的版本限制为

cmake_minimum_required(VERSION 3.16...3.28)

而系统安装的是3.10,不匹配怎么办呢?这种不匹配经常遇到,因为在编译五花八门的代码时,各家的版本要求都可能不一样。

幸运的是cmake只是一个规则生成程序,不涉及太多三方依赖,可以很容易地从官方网站下载编译好的软件版本,直接使用。具体为,访问 https://cmake.org/files/ ,找个目标版本,点击进去后下载即可,llinux环境时,可以下载.sh脚本,例如:cmake-3.20.6-linux-x86_64.sh。接着只需要覆盖终端的PATH,确保优先找到本地下载的cmake文件。

编译Debug或Release

编译参数指定类型即可,比如编译Release:

cmake --build . --config Release

cmake参数传宏

cmake通过-DXXX的方式来向编译代码设定宏定义。除不同软件有自己支持的宏外,cmake也有一些内置能用的宏,例如:

cmake . -DCMAKE_INSTALL_PREFIX=`pwd`/output 
        -DCMAKE_C_FLAGS_RELEASE="-Os -g0 -s" -DCMAKE_CXX_FLAGS_RELEASE="-Os -g0 -s"
        -DDISABLE_SHARED=ON

跨平台指定c++版本

在书写CMakeLists.txt时,指定c++版本比较特殊,如果只是针对linux的gcc,当然可以写成:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

但windows上并不支持-std参数的,所以需要写成:

set(CMAKE_CXX_STANDARD 11)

针对特定编译器做宏定义

在写CMakeLists.txt时,有时候需要针对特定的编译器平台指定宏,最常见的例子就是写c++时用到std::min(),但在windows上,windows.h里定义了一个名为min的宏,为了避免冲突,就需要针对VC定义NOMINMAX宏,写法如下:

if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
    add_compile_definitions(NOMINMAX)
endif()

如何支持安装命令及安装时去除符号表

要支持install命令,是需要在CMakefile.txt中指定安装路径的,如下即表示将project_name的结果安装到bin目录下:

install(TARGETS project_name DESTINATION bin)

安装命令即为:

cmake --install . --config Release

如果需要去除符号表,让结果二进制文件更小点,命令为:

cmake --install . --config Release --strip

 

发表于 06月05日 11:43   修改于 09月05日 20:04   评论:0   阅读:2992  



回到顶部

首页 | 关于我 | 关于本站 | 站内留言 | rss
python logo   django logo   tornado logo