0

0

c++如何使用cmake构建项目_c++ CMakeLists.txt编写与依赖库关联【指南】

穿越時空

穿越時空

发布时间:2025-12-31 17:32:02

|

348人浏览过

|

来源于php中文网

原创

CMake是生成构建系统配置的元构建工具,非自动构建工具;其核心是通过CMakeLists.txt声明项目信息、标准与依赖,再生成Makefile或VS解决方案等实际构建文件。

c++如何使用cmake构建项目_c++ cmakelists.txt编写与依赖库关联【指南】

直接说结论:CMake 不是“自动构建工具”,而是“生成构建系统配置的元构建工具”——你写 CMakeLists.txt 的本质,是在告诉 CMake “我有哪些源文件、想生成什么目标、依赖哪些库、用什么编译器选项”,它再据此生成 Makefile(Linux/macOS)或 Visual Studio 解决方案(Windows)等真正干活的东西。

怎么写最简可用的 CMakeLists.txt

新手常卡在第一行就报错,核心是版本声明 + 项目名 + 最低 C++ 标准这三要素缺一不可:

  • cmake_minimum_required(VERSION 3.10):低于 3.10 会丢失 target_compile_features 等关键功能;3.20+ 更推荐(支持 FetchContentfind_package(... CONFIG) 更健壮)
  • project(MyApp LANGUAGES CXX):必须显式声明 CXX,否则 add_executable 可能默认当 C 项目处理,导致 std::string 等链接失败
  • set(CMAKE_CXX_STANDARD 17):不设的话默认可能是 C++98,现代库(如 fmtspdlog)直接编译不过
cmake_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)

如何正确链接第三方库(静态 / 动态 / 头文件-only)

错误写法:target_link_libraries(myapp /usr/lib/libjsoncpp.a) —— 路径硬编码、无跨平台性、不检查是否存在。

正确做法分三类:

立即学习C++免费学习笔记(深入)”;

  • 系统级已安装库(如 zlibOpenSSL:用 find_package + target_link_libraries,CMake 自动找头文件路径和库文件
  • 头文件-only 库(如 fmtrange-v3:用 find_package(fmt REQUIRED)target_link_libraries(myapp PRIVATE fmt::fmt),PRIVATE 表示仅本 target 使用,不传递给依赖它的其他 target
  • 未系统安装的本地库(如自己写的 libmath.a:先 add_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_libraries 的作用域(PUBLIC/PRIVATE/INTERFACE)直接影响依赖传递——比如你封装了一个库 mylib 并链接了 boost_filesystem,又希望使用者包含 mylib 就自动获得 boost_filesystem 的头文件,则需写 target_link_libraries(mylib PUBLIC boost::filesystem)

知了追踪
知了追踪

AI智能信息助手,智能追踪你的兴趣资讯

下载

常见报错与绕过陷阱

以下错误出现频率极高,且原因隐蔽:

  • Cannot find -lxxx:不是库没装,而是 find_package(xxx) 成功但没用 target_link_libraries 关联;或用了 find_library 却忘了 target_link_libraries(... ${XXX_LIBRARY})
  • undefined reference to `xxxx' (from std::filesystem):Linux 下 std::filesystem 需要显式链接 -lstdc++fs,加 target_link_libraries(myapp PRIVATE stdc++fs)(Clang/GCC 9+)
  • CMake Error at CMakeLists.txt:12 (add_executable): No SOURCES givenadd_executable 后没跟任何源文件,或变量为空(如 set(SRCS) 写了但没赋值),建议用 message(STATUS "SRCS = ${SRCS}") 调试
  • Windows 下链接 .lib 但运行时报 dll not found:动态库路径没进 PATH,开发期可在 CMake 中加 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) 并把 DLL 拷到该目录

依赖管理进阶:用 FetchContent 嵌入子项目

不想手动下载/编译 gtestspdlog?CMake 3.14+ 提供 FetchContent,直接从 Git 或 URL 拉取并作为子项目构建:

include(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_MakeAvailable 会自动调用 add_subdirectory,所以不用再写一遍;但它会把子项目所有 target 暴露到当前作用域,命名冲突时可用 set(spdlog_SOURCE_DIR ${CMAKE_BINARY_DIR}/_deps/spdlog-src) 控制路径。

真正难的从来不是语法,而是搞清「谁负责提供头文件路径」「谁负责链接符号」「谁负责传播编译定义」——这三个问题理不清,target_include_directoriestarget_compile_definitionstarget_link_libraries 就永远像在碰运气。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

312

2023.08.02

scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

184

2023.10.18

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

263

2023.10.25

scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

184

2023.10.18

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

263

2023.10.25

go中interface用法
go中interface用法

本专题整合了go语言中int相关内容,阅读专题下面的文章了解更多详细内容。

76

2025.09.10

undefined是什么
undefined是什么

undefined是代表一个值或变量不存在或未定义的状态。它可以作为默认值来判断一个变量是否已经被赋值,也可以用于设置默认参数值。尽管在不同的编程语言中,undefined可能具有不同的含义和用法,但理解undefined的概念可以帮助我们更好地理解和编写程序。本专题为大家提供undefined相关的各种文章、以及下载和课程。

3911

2023.07.31

网页undefined是什么意思
网页undefined是什么意思

网页undefined是指页面出现了未知错误的意思,提示undefined一般是在开发网站的时候定义不正确或是转换不正确,或是找不到定义才会提示undefined未定义这个错误。想了解更多的相关内容,可以阅读本专题下面的文章。

2894

2024.08.14

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

3

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 6.3万人学习

Git 教程
Git 教程

共21课时 | 2.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号