[Build]cmake常用配置项
常用设置
配置与构建(CMD)
3.15版本(2019年6月)之前,配置与构建比较麻烦,以windows为例,命令有以下三种方式:
- 第1种:nmake
cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release path/to/source/dir nmake
- 第2种:VS版本加msbuild,以VS2015 x64为例:
cmake -G "Visual Studio 14 Win64" path/to/source/dir msbuild Project.sln
- 第3种:architecture参数(x64或win32)加msbuild:
cmake -A x64 path/to/source/dir msbuild Project.sln
3.15版本开始,构建命令无需区分平台(老版本想要无视平台需安装ninja),且默认x64:
cmake path/to/source/dir
cmake --build . --target install --config Release
参考:How to use CMake to install
https://stackoverflow.com/a/48428846/1645289
设置编译输出路径
在CMakeList.txt中如下设置后,无论是编译可执行文件还是编译静态库,都会输出到指定目录下,而不再是默认的当前目录。
#静态库输出目录(lib, a)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "lib/")
#编译时动态库输出目录(dll + lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "lib/")
#动态库输出目录(dll, so)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "lib/")
#可执行文件输出目录
set(EXECUTABLE_OUTPUT_PATH "bin/")
参考:
is CMake ignoring CMAKE_LIBRARY_OUTPUT_DIRECTORY?
https://stackoverflow.com/a/38450844/1645289
How do I make CMake output into a ‘bin’ dir? https://stackoverflow.com/a/6595001/1645289
cmake 常用设定及函数
https://blog.csdn.net/LaineGates/article/details/79190398
获取指定目录下的所有源文件
获取./src
目录下的所有hpp和cpp文件(只获取./src
当前目录文件,不递归查询./src
下的子目录):
file(GLOB CPP_FILES ./src/*.hpp ./src/*.cpp)
add_library(mylib STATIC ${CPP_FILES})
获取./src/player/
目录和./src/monster/
目录下的所有cpp文件(同时递归这两个目录下的所有子目录):
file(GLOB_RECURSE CPP_FILES
./src/player/*.cpp
./src/monster/*.cpp)
参考:How to use cmake GLOB_RECURSE for only some subdirectories
https://stackoverflow.com/a/27994855/1645289
打印log
if (NOT CMAKE_VERSION VERSION_GREATER "3.0")
message(FATAL_ERROR "cmake version 3.x is required!")
endif()
打印变量
message(STATUS "foo include dir: ${foo_INCLUDE}")
修改默认的CMAKE_MODULE_PATH目录
CMAKE_MODULE_PATH是供find_package
搜索第三方库用的。cmake的默认Modules目录在安装目录中:cmake-3.11.3-win64-x64\share\cmake-3.11\Modules
。
如果要追加Modules目录,有3种方式:
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_PATH}:${CMAKE_MODULE_PATH}")
LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_PREFIX}")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
find_package用法
通常情况下,包含第三方库需要写以下内容
include_directories("${project_root_path}/include/")
link_directories(./lib)
add_executable(myapp myapp.cpp)
target_link_libraries(myapp mylib)
如果引用的很多个第三方库,那么类似上面的内容会写很多,且如果自己的多个项目都引用了某个第三方库,那么我每个项目的CmakeList.txt
都得写一遍,重复劳动很多。那么有没办法为每个第三方库只定义一次它的头文件和库文件信息,然后在自己的工程中只指定名称即可?(类似编译Java的Maven仓库)答案是当然可以,find_package
帮你解决。
find_package
定义在自己工程的CmakeList.txt中:
find_package( XXX CONFIG REQUIRED )
然后cmake就会在默认的Modules(即CMAKE_MODULE_PATH
指定的目录)目录中搜索这个XXX第三方库。
搜索有两种模式:FindXXX.cmake
和XXXConfig.cmake
。前者叫做Module模式,后者叫做Config模式。
- Module模式
搜索CMAKE_MODULE_PATH指定路径下的FindXXX.cmake文件,通过该文件从而找到XXX库的头文件和lib文件位置。FindXXX.cmake中需要定义XXX_INCLUDE_DIRS
和XXX_LIBRARIES
。 - Config模式
搜索XXX_DIR指定路径下的XXXConfig.cmake文件(XXX_DIR定义在自己工程的CMakeList.txt或者cmake-gui的环境变量中),通过该文件从而找到XXX库的头文件和lib文件位置。XXXConfig.cmake中需要定义XXX_INCLUDE_DIRS
和XXX_LIBRARIES
Config模式示例:
先在自己工程的CMakeList.txt中添加
set(XXX_DIR D:/sdk/XXX-0.9.9.0/bin)
find_package( XXX CONFIG REQUIRED )
其中CONFIG
表示使用Config模式搜索,默认是Module模式;然后D:/sdk/XXX-0.9.9.0/cmake目录下必须存在XXXConfig.cmake文件,否则当执行cmake时会提示找不到XXXConfig.cmake。
XXXConfig.cmake和XXXTargets.cmake都不是手动编写的,而是CMake自动生成的!!
生成Config.cmake的参考代码:
https://github.com/g-truc/glm/blob/0d973b40a49e550b1ea7df22a8573bc5fff84f24/CMakeLists.txt#L175
生成Targets.cmake的参考代码:
https://github.com/g-truc/glm/blob/0d973b40a49e550b1ea7df22a8573bc5fff84f24/CMakeLists.txt#L198
使用通配符批量指定头文件或源文件 (include source files batch using wildcard)
GLOB:
FILE(GLOB cpp_files ../src/*.cc)
add_executable(helloworld ${cpp_files})
There’s also GLOB_RECURSE
if you want to find the files recursively.
How to use all *.c files in a directory with the Cmake build system?
https://stackoverflow.com/a/3366701
Automatically add all files in a folder to a target using CMake?
https://stackoverflow.com/a/3201211
How to enable Google Sanitizers in CMake
Configuration for GCC in CMakeLists.txt
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fsanitize=leak -fsanitize=thread -g")
Configuration for xcode schema
in CMake:
cmake_minimum_required(VERSION 3.13)
set(CMAKE_XCODE_GENERATE_SCHEME ON)
set(CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER ON)
set(CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN ON)
When Build:
xcodebuild -enableAddressSanitizer YES
Reference:
What’s the proper way to enable AddressSanitizer in CMake that works in Xcode
https://stackoverflow.com/a/45940322
How to change the name of CMakeLists.txt
There’s no reasonable excuse that CMake doesn’t use a specified file extension like every other tool in the toolkit. You can do this by putting a dummy CMakeLists.txt, which contains:
cmake_minimum_required(VERSION 3.8)
INCLUDE("meaningfulFilename.cmake")
Then put your actual cmake code in the .cmake file.
Origin:
https://stackoverflow.com/a/53743295/1645289
add_subdirectory: relative patch of subdirectory
Add subdirectory in current directory:
add_subdirectory(Lua)
Add subdirectory in relative path:
add_subdirectory(./../Lua build_lua)
Visual Studio
Set startup project
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT MyExeTarget)
Origin:
https://stackoverflow.com/a/59789571/1645289
Compile with /MT
or /MD
How to set Runtime Library
for Visual Studio:
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
Origin:
Compile with /MT instead of /MD using CMake
https://stackoverflow.com/a/14172871/1645289
Compiler
How to enable C++17 features for compiler
#enable C++17 features
target_compile_features(${MY_PROJECT_NAME} PRIVATE cxx_std_17)
CMake Examples
Comprehensive
Command line C++ barcode reader for Windows, Linux, and macOS.
https://github.com/dynamsoft-dbr/cmake
learning cmake
https://github.com/Akagi201/learning-cmake
Useful CMake Examples
https://github.com/ttroy50/cmake-examples
A curated list of awesome CMake resources, scripts, modules, examples and others.
https://github.com/onqtam/awesome-cmake
A template for modern C++ projects using CMake, clang-format and unit testing, with support for downstream inclusion
https://github.com/filipdutescu/modern-cpp-template
iOS, MacOS
A CMake toolchain file for iOS, watchOS and tvOS C/C++/Obj-C++ development
https://github.com/leetal/ios-cmake
Example. Compile android, iOS, mac static lib on MacOS.
https://github.com/9b9387/CMakeCrossCompiling
伦常乖舛,立见消亡;德不配位,必有灾殃。----《朱子家训》