CMake
Table of Contents
CMake note.
<!– more –>
CMake
simple example
writing a cmakelists.txt
创建一个 CMakeLists.txt 文件,填入下面内容
cmake_minimum_required(VERSION 3.15...3.21) project(MyProject VERSION 1.0 DESCRIPTION "Very nice project" LANGUAGES CXX ) add_executable(myexample simple.cpp)
创建 simple.cpp 文件填入下面内容
/* simple.c or simple.cpp */ #include <stdio.h> int main() { printf("Hello, World!\n"); return 0; }
building with cmake
cd CPPConcurrencyInAction # -S 指定源代码目录为 ./CPPConcurrencyInAction # -B 指定构建目录为 ./CPPConcurrencyInAction/BUILD # 配置并生成makefiles,设置所有options为默认设置,并将其缓存到CMakeCache.txt文件中 cmake -S . -B BUILD # 调用构建系统执行构建,无论你的构建系统是make还是ninja还是基于IDE的系统,都可以使用统一的命令 # -j 2 在两个CPU 核心上执行构建 # -v verbosely show commands used to build (详细列出构建使用的命令) cmake --build BUILD # 指定只编译 CPPConcurrencyInAction target cmake --build BUILD --target CPPConcurrencyInAction
usage
指定 c++版本
set(CMAKE_CXX_STANDARD 14)
指定 Visual Studio 版本
cmake -G "Visual Studio 17 2022"
指定 CPU 架构
cmake -G "Visual Studio 17 2022" -A Win32 -S \path_to_source\ -B "build32" cmake -G "Visual Studio 17 2022" -A x64 -S \path_to_source\ -B "build64" cmake --build build32 --config Release cmake --build build64 --config Release
指定编译生成的 app 目录
# 项目目录结构如下 # Test # CMakeLists.txt # main.cpp # 执行编译后,test.exe 目录为 Test/bin/test.exe cmake_minimum_required (VERSION 3.15) project(Test) set(CMAKE_CXX_STANDARD 17) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/bin") add_executable(test main.cpp)
利用 add_subdirectory 组织多个工程
目录结构如下:
LLVM-Kaleidoscope CMakeLists.txt chapter-0 CMakeLists.txt main.cpp chapter-1 CMakeLists.txt main.cpp
# LLVM-Kaleidoscope/CMakeLists.txt cmake_minimum_required (VERSION 3.15) project(Kaleidoscope) set(CMAKE_CXX_STANDARD 17) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/bin") add_subdirectory(chapter-0) add_subdirectory(chapter-1) # LLVM-Kaleidoscope/chapter-0/CMakeLists.txt add_executable(chapter_0 main.cpp)
cd LLVM-Kaleidoscope # 执行下面命令,在LLVM-Kaleidoscope/build目录下生成工程 cmake -S . -B build # 执行下面命令,编译所有工程生成 chapter-0.exe chapter-1.exe cmake --build build
打印 CMake 变量
message(PROJECT_SOURCE_DIR="${PROJECT_SOURCE_DIR}")
构建错误定位
下面文件中会列出具体的错误信息。可以已经具体错误信息再进一步定位错误。
xxx/build/CMakeFiles/CMakeConfigureLog.yaml xxx/build/CMakeFiles/CMakeError.log
Error
windows
could not find any instance of Visual Studio
没有安装 VS CMake 组件 和 Visual Studio 扩展开发
The CXX compiler identification is unknown
project_source_dir 为空
调用 project() 之后 PROJECT_SOURCE_DIR 变量才生效
# ERROR cmake_minimum_required (VERSION 3.15) set(CMAKE_CXX_STANDARD 17) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/bin") message(PROJECT_SOURCE_DIR="${PROJECT_SOURCE_DIR}") project(Kaleidoscope) # RIGHT cmake_minimum_required (VERSION 3.15) project(Kaleidoscope) set(CMAKE_CXX_STANDARD 17) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/bin") message(PROJECT_SOURCE_DIR="${PROJECT_SOURCE_DIR}")
LINK : fatal error LNK1104: 无法打开文件“ucrtd.lib”
微软安装 windows sdk 导致的 bug。
修改注册表 \HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Kits\Installed Roots@KitsRoot10 的值为 C:\Program Files (x86)\Windows Kits\10\
error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2'
case 1
编译使用的 Debug,引用的 lib 使用的 release。修改 VS 工程如下设置选项:
Properties/Configuration Properties / C C++ / Code Generation/Runtime Library/Multi-threaded DLL
或者 cmake 文件中添加如下代码:
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDLL")
参考资料
- More Modern CMake https://hsf-training.github.io/hsf-training-cmake-webpage/
- It's Time To Do CMake Right https://pabloariasal.github.io/2018/02/19/its-time-to-do-cmake-right/
- Modern-Cmake https://cliutils.gitlab.io/modern-cmake/
- Effective Modern CMake https://gist.github.com/mbinna/c61dbb39bca0e4fb7d1f73b0d66a4fd1