CMake是生成构建系统配置的元构建工具,非自动构建工具;其核心是通过CMakeLists.txt声明项目信息、标准与依赖,再生成Makefile或VS解决方案等实际构建文件。
直接说结论:CMake 不是“自动构建工具”,而是“生成构建系统配置的元构建工具”——你写
的本质,是在告诉 CMake “我有哪些源文件、想生成什么目标、依赖哪些库、用什么编译器选项”,它再据此生成
(Linux/
mac
OS)或
(Windows)等真正干活的东西。
怎么写最简可用的
新手常卡在第一行就报错,核心是版本声明 + 项目名 + 最低 C++ 标准这三要素缺一不可:
:低于 3.10 会丢失
等关键功能;3.20+ 更推荐(支持
、
更健壮)
:必须显式声明
,否则
可能默认当 C 项目处理,导致
等链接失败
:不设的话默认可能是 C++98,现代库(如
、
)直接编译不过
如何正确链接第三方库(静态 / 动态 / 头文件-only)
错误写法:
—— 路径硬
编码
、无跨平台性、不检查是否存在。
正确做法分三类:
立即学习
“
C++免费学习笔记(深入)
”;
系统级已安装库(如、)
:用
+
,CMake 自动找头文件路径和库文件
头文件-only 库(如、)
:用
后
,PRIVATE 表示仅本 target 使用,不传递给依赖它的其他 target
未系统安装的本地库(如自己写的)
:先
,再
,最后
注意:
的作用域(
/
/
)直接影响依赖传递——比如你封装了一个库
并链接了
,又希望使用者包含
就自动获得
的头文件,则需写
。
ChatGPT (Windows)
ChatGPT Windows 版本优化了系统兼容性与响应速度,提供多任务处理和对话记录管理功能,适用于办公辅助、创意写作、学习辅导和日常问答。它能帮助用户快速生成文稿、整理资料和高效获取信息,为个人和团队提供稳定、流畅的生产力体验。
下载
常见报错与绕过陷阱
以下错误出现频率极高,且原因隐蔽:
:不是库没装,而是
成功但没用
关联;或用了
却忘了
:Linux 下
需要显式链接
,加
(Clang/GCC 9+)
:
后没跟任何源文件,或变量为空(如
写了但没赋值),建议用
调试
Windows 下链接
但运行时报
:动态库路径没进
,开发期可在 CMake 中加
并把 DLL 拷到该目录
依赖管理进阶:用
嵌入子项目
不想手动下载/编译
或
?CMake 3.14+ 提供
,直接从 Git 或 URL 拉取并作为子项目构建:
注意:
会自动调用
,所以不用再写一遍;但它会把子项目所有 target 暴露到当前作用域,命名冲突时可用
控制路径。
真正难的从来不是语法,而是搞清「谁负责提供头文件路径」「谁负责链接符号」「谁负责传播编译定义」——这三个问题理不清,
、
、
就永远像在碰运气。
CMakeLists.txtMakefileVisual Studio 解决方案CMakeLists.txtcmake_minimum_required(VERSION 3.10)target_compile_featuresFetchContentfind_package(... CONFIG)project(MyApp LANGUAGES CXX)CXXadd_executablestd::stringset(CMAKE_CXX_STANDARD 17)fmtspdlogcmake_minimum_required(VERSION 3.10)
project(MyApp LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_executable(myapp main.cpp utils.cpp)
target_link_libraries(myapp /usr/lib/libjsoncpp.a)zlibOpenSSLfind_packagetarget_link_librariesfmtrange-v3find_package(fmt REQUIRED)target_link_libraries(myapp PRIVATE fmt::fmt)libmath.aadd_library(math STATIC IMPORTED)set_property(TARGET math PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/lib/libmath.a)target_link_libraries(myapp PRIVATE math)target_link_librariesPUBLICPRIVATEINTERFACEmylibboost_filesystemmylibboost_filesystemtarget_link_libraries(mylib PUBLIC boost::filesystem)Cannot find -lxxxfind_package(xxx)target_link_librariesfind_librarytarget_link_libraries(... ${XXX_LIBRARY})undefined reference to `xxxx' (from std::filesystem)std::filesystem-lstdc++fstarget_link_libraries(myapp PRIVATE stdc++fs)CMake Error at CMakeLists.txt:12 (add_executable): No SOURCES givenadd_executableset(SRCS)message(STATUS "SRCS = ${SRCS}").libdll not foundPATHset(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)FetchContentgtestspdlogFetchContentinclude(FetchContent)
FetchContent_Declare(
spdlog
GIT_REPOSITORY https://github.com/gabime/spdlog.git
GIT_TAG v1.12.0
)
FetchContent_MakeAvailable(spdlog)
add_executable(myapp main.cpp)
target_link_libraries(myapp PRIVATE spdlog::spdlog)
FetchContent_MakeAvailableadd_subdirectoryset(spdlog_SOURCE_DIR ${CMAKE_BINARY_DIR}/_deps/spdlog-src)target_include_directoriestarget_compile_definitionstarget_link_libraries