编译与链接
编译器
通过环境变量指定编译器:
$ CC=clang CXX=clang++ cmake ..
通过参数指定编译器:
$ cmake -D CMAKE_C_COMPILER=clang -D CMAKE_CXX_COMPILER=clang++ ..
也可以在 cmake 脚本中指定:
set(CMAKE_C_COMPILER clang)
set(CMAKE_CXX_COMPILER clang++)
环境检查
CheckCCompilerFlags
CheckCSourceCompiles
CheckCSourceRuns
CheckCXXCopmilerFlags
CheckCXXSourceCompiles
CheckCXXSourceRuns
以下示例用于检查当前 linux 系统中是否有 sendfile()
系统调用.
include(CheckCSourceRuns)
check_c_source_runs(
"
#include <sys/sendfile.h>
#include <errno.h>
int main(void) {
int s = 0;
int fd = 1;
ssize_t n;
off_t off = 0;
n = sendfile(s, fd, &off, 1);
if (n == -1 && errno == ENOSYS) {
return 1;
} else {
return 0;
}
}
"
HAS_SENDFILE
)
if (HAS_SENDFILE)
message("Has sendfile")
endif ()
# 从缓存变量中移除 HAS_SENDFILE.
unset(HAS_SENDFILE CACHE)
编译选项
对当前目录作用域及子目录作用域中的所有目标(targets) 都有效:
add_compile_options(-Wall -Wextra -Werror -Wpedantic --pedantic-errors)
target_add_compile_options(Foo -Wall -Wextra -Werror -Wpedantic --pedantic-errors)
编译器特性
比如, 我们要求使用 c++17
的标准来编译目标 Foo
.
target_compile_features(Foo PRIVATE cxx_std_17)
CMake 是如何处理这些编译选项的呢? 首先 cmake 命令在生成配置文件时, 会打印这样的信息:
-- Detecting CXX compile features
-- Detecting CXX compile features - done
这里, 运持的是 cmake 自己提供的一些编译器特性检查模块. 并会生成一个基于当前
编译器版本号对应的所有 C++ 版本. 如果对某个版本是完全支持的, 就会有类似
CMAKE_CXX17_STANDARD__HAS_FULL_SUPPORT
这样的临时属性. 如果不是完整支持的,
就会进行一些临时的编译任务, 编译一些 c++ 代码片段, 以检测当前编译器对某个特性
是否支持.
静态编译可执行文件
只需要修改一下链接时的选项即可:
target_link_libraries(Foo -static)
生成静态库
默认情况下, 如果不指定库类型时, 默认编译出的是动态库.
add_library(Foo ${FOO_SRC_FILES})
此时, 可以修改选项 BUILD_SHARE_LIBS
:
cmake -DBUILD_SHARE_LIBS=OFF ....