【CMake】使用 CMake 将单模块 C 项目构建为库并链接主程序

LuckiBit

目录

    • 1. 项目结构设计
      • 📦 结构说明
    • 2. 项目文件内容
      • 2.1 顶层 `CMakeLists.txt`
      • 2.2 模块 `src/color/CMakeLists.txt` ✅【推荐写法】
      • ❓是否需要写 `project()`?
      • 2.3 模块头文件 `include/color.h`
      • 2.4 模块实现文件 `src/color/color.c`
      • 2.5 主程序 `src/main.c`
    • 3. 构建与运行步骤
      • ✅ 运行输出:
    • 4. 构建输出目录说明
    • 5. 跨平台构建支持(Windows / macOS / Linux)
      • 🧠 在 CMake 中检测平台
      • 🔧 跨平台构建命令
    • 6. 项目扩展建议
    • 7. 项目总结与回顾
    • 8. 最终项目结构(含构建结果)
    • ✅ 附录:子模块的 CMake 最佳写法模板
    • 9. 结束语
    • 相关文章:

CMake 是现代 C/C++ 项目中最主流的构建工具之一。它不仅可以帮助开发者组织源代码、管理依赖、构建库文件,还能提升项目的模块化程度和可维护性。

本文将以一个简单模块 color 为例,介绍如何使用 CMake:

  • 构建一个结构清晰的 C 项目;
  • 将模块编译为静态库;
  • 配置可执行程序链接库;
  • 自定义库输出路径;
  • 支持跨平台构建(Windows/macOS/Linux)。

1. 项目结构设计

我们采用模块化、分离构建思路组织项目结构:

your_project/
├── CMakeLists.txt           # 顶层 CMake 构建脚本
├── include/                 # 公共头文件目录
│   └── color.h
├── src/                     # 源文件目录
│   ├── main.c               # 主程序入口
│   └── color/               # color 模块目录
│       ├── color.c
│       └── CMakeLists.txt   # color 模块构建配置
└── build/                   # 构建输出目录(自动生成)

📦 结构说明

目录/文件说明
include/放置对外公开头文件,便于跨模块引用
src/color/独立模块,具备独立构建能力
build/构建输出与源代码分离,保持干净
CMakeLists.txt配置统一构建规则与链接流程

2. 项目文件内容

2.1 顶层 CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(ColorApp C)set(CMAKE_C_STANDARD 99)# 设置库和可执行文件的输出路径
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)# 添加头文件搜索路径
include_directories(include)# 添加 color 模块
add_subdirectory(src/color)# 添加主程序
add_executable(${PROJECT_NAME} src/main.c)# 链接 color 模块库
target_link_libraries(${PROJECT_NAME} color)

2.2 模块 src/color/CMakeLists.txt ✅【推荐写法】

# 可选但推荐:模块自身声明(便于大型项目调试)
project(ColorModule C)# 构建静态库 color
add_library(color STATIC color.c)# 添加头文件目录(可供外部 target 使用)
target_include_directories(color PUBLIC ${CMAKE_SOURCE_DIR}/include)

❓是否需要写 project()

  • 小项目中可省略
  • 推荐添加,可读性更强、利于 IDE 显示模块名、利于分组构建。
  • ❗不要写 cmake_minimum_required(),它只应在顶层写一次。

2.3 模块头文件 include/color.h

#ifndef COLOR_H
#define COLOR_Hvoid set_color(void);#endif

2.4 模块实现文件 src/color/color.c

#include <stdio.h>
#include "color.h"void set_color(void) {printf("Set color called!\n");
}

2.5 主程序 src/main.c

#include "color.h"int main() {set_color();return 0;
}

3. 构建与运行步骤

在项目根目录下执行以下命令进行构建:

mkdir build
cd build
cmake ..
make
./bin/ColorApp

✅ 运行输出:

Set color called!

4. 构建输出目录说明

借助 CMAKE_*_OUTPUT_DIRECTORY 变量,我们可以控制构建产物的输出位置:

变量名描述示例输出路径
CMAKE_ARCHIVE_OUTPUT_DIRECTORY静态库 .a 输出路径build/lib/libcolor.a
CMAKE_LIBRARY_OUTPUT_DIRECTORY动态库 .so 输出路径build/lib/libcolor.so
CMAKE_RUNTIME_OUTPUT_DIRECTORY可执行文件输出路径build/bin/ColorApp

5. 跨平台构建支持(Windows / macOS / Linux)

🧠 在 CMake 中检测平台

if(WIN32)message(STATUS "Compiling on Windows")add_definitions(-DPLATFORM_WINDOWS)
elseif(APPLE)message(STATUS "Compiling on macOS")add_definitions(-DPLATFORM_MACOS)
elseif(UNIX)message(STATUS "Compiling on Linux")add_definitions(-DPLATFORM_LINUX)
endif()

🔧 跨平台构建命令

平台构建命令
Linux/macOScmake .. && make
Windows MinGWcmake -G "MinGW Makefiles" .. && mingw32-make
Windows Visual Studiocmake -G "Visual Studio 17 2022" .. (生成 .sln)

6. 项目扩展建议

你可以基于此结构轻松扩展为多模块项目:

  • 新增模块如 art, password

    • 创建目录 src/art/,放入 art.c, art.h
    • 添加对应 CMakeLists.txt 和库配置;
  • 所有模块的头文件统一放入 include/

  • 在顶层 CMakeLists.txt 中添加子目录与链接即可;

  • 添加 tests/ 目录引入单元测试框架如 CTestGoogle Test


7. 项目总结与回顾

关键点内容
使用 add_library() 构建静态/动态库模块化构建
使用 target_link_libraries() 连接模块清晰解耦
使用输出变量设置生成目录可控构建产物结构
模块 + 主程序分离易于维护与扩展
支持跨平台平台适配Windows/macOS/Linux 构建

8. 最终项目结构(含构建结果)

your_project/
├── CMakeLists.txt                   # 顶层构建配置
├── include/
│   └── color.h                      # 模块头文件
├── src/
│   ├── main.c                       # 主程序
│   └── color/
│       ├── color.c                  # 模块实现
│       └── CMakeLists.txt           # 模块构建配置
├── build/
│   ├── lib/
│   │   └── libcolor.a              # 静态库输出
│   └── bin/
│       └── ColorApp                # 主程序输出

✅ 附录:子模块的 CMake 最佳写法模板

# src/color/CMakeLists.txt
project(ColorModule C)add_library(color STATIC color.c)target_include_directories(color PUBLIC ${CMAKE_SOURCE_DIR}/include)

9. 结束语

  1. 本节内容已经全部介绍完毕,希望通过这篇文章,大家对 CMake 有了更深入的理解和认识。
  2. 感谢各位的阅读和支持,如果觉得这篇文章对你有帮助,请不要吝惜你的点赞和评论,这对我们非常重要。再次感谢大家的关注和支持!点我关注❤️

相关文章:

  • 指针的神秘探险:从入门到精通的奇幻之旅 !

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/914708.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/914708.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从零开始的云计算生活——番外4,使用 Keepalived 实现 MySQL 高可用

目录 前言 一、架构原理​ ​Keepalived 作用​ ​MySQL 主从复制​ 二、环境准备​ 服务器要求​&#xff1a; 安装基础软件​ 三、配置 MySQL 主从复制 四、配置 Keepalived 主节点配置​&#xff08;/etc/keepalived/keepalived.conf&#xff09; 从节点配置 五、…

list类的常用接口实现及迭代器

目录 1. list类的介绍 2.list类的常用接口 2.1 list类的常用构造 2.2 list类对象的容量操作 2.3 list迭代器 2.4 list类的常用操作 3.list的模拟实现 1. list类的介绍 list代表的是双向链表&#xff0c;常见的有创建&#xff0c;增&#xff0c;删&#xff0c;改几个接口…

vscode Cline接入火山引擎的Deepseek R1

创建火山引擎Deepseek R1的API 在火山引擎管理控制台中创建Deepseek R1推理接入点&#xff08;大模型&#xff09;&#xff0c;创建成功后会看到下图效果。在操作中选择API调用&#xff0c;在页面中选择OpenAI SDK&#xff0c;按照步骤找到baseUrl地址和API_KEY&#xff0c;后续…

新手向:自动化图片格式转换工具

大家好&#xff01;今天我要分享一个非常实用的Python小工具——图片格式批量转换器。如果你经常需要处理大量不同格式的图片文件&#xff0c;或者需要统一图片格式以便于管理&#xff0c;那么这个工具将会成为你的得力助手&#xff01;一、为什么需要图片格式转换&#xff1f;…

CUDA中的内存管理、锁页内存、UVA统一虚拟地址、零拷贝、统一内存

文章目录0 前言1 swap内存跟锁页内存2 UVA(Unified Virtual Addressing)统一虚拟地址3 先看最普通的cuda内存分配、释放、传输4 申请锁页内存4.1 cudaHostAllocDefault4.2 cudaHostAllocPortable4.3 cudaHostAllocWriteCombined4.3 cudaHostAllocMapped4.4 几种锁页内存总结4.5…

微服务环境下的灰度发布与金丝雀发布实战经验分享

微服务环境下的灰度发布与金丝雀发布实战经验分享 在大规模微服务架构中&#xff0c;如何平滑安全地上线新功能是每个后端团队的痛点。本文将结合生产环境中的真实案例&#xff0c;分享灰度发布&#xff08;Gray Release&#xff09;与金丝雀发布&#xff08;Canary Release&am…

MEF 在 WPF 中的简单应用

MEF核心笔记MEF 的开发模式主要适用于插件化的业务场景中&#xff0c;C/S 和 B/S 中都有相应的使用场景&#xff0c;其中包括但不限于 ASP.NET MVC 、ASP WebForms、WPF、UWP 等开发框架。当然&#xff0c;DotNet Core 也是支持的。 以下是搜索到一些比较好的博文供参考&#…

Gitlab跑CICD的时候,maven镜像和pom.xml使用的maven版本冲突导致没办法build成功的解决方法

是这样的&#xff01;最近遇到一个非常棘手的难题&#xff0c;我搞了大概2周时间才把他弄出来&#xff0c;因为自己搭了个私服的maven仓库&#xff0c;他不像maven官方仓库一样&#xff0c;可以跟nginx一样转的&#xff0c;所以遇到好几个难点&#xff01;第一点&#xff1a;就…

Linux内核IPv4路由查找:LPC-Trie算法的深度实践

在互联网基础设施的核心领域,路由查找性能直接决定了网络转发效率。Linux内核作为现代网络系统的基石,其IPv4路由子系统采用了一种名为LPC-Trie(Level-Compressed Trie) 的创新数据结构,在net/ipv4/fib_trie.c文件中实现了高效的路由管理方案。本文将深入剖析这一机制的设…

【设计模式】装饰(器)模式 透明装饰模式与半透明装饰模式

装饰模式&#xff08;Decorator Pattern&#xff09;详解一、装饰模式简介 装饰模式&#xff08;Decorator Pattern&#xff09; 是一种 结构型设计模式&#xff0c;它允许你动态地给对象添加行为或职责&#xff0c;而无需修改其源代码&#xff0c;也不需要使用继承来扩展功能。…

NAT原理与实验指南:网络地址转换技术解析与实践

NAT实验 NAT&#xff08;Network Address Translation&#xff0c;网络地址转换&#xff09;&#xff1a; NAT技术的介绍&#xff1a; 随着Internet用户的快速增长&#xff0c;以及地址分配不均等因素&#xff0c;IPv4地址&#xff08;约40亿的空间地址&#xff09;已经陷入不…

设计模式之【观察者模式】

目录 观察者模式中的角色 通过一个简单案例来演示观察者模式 被观察者接口 事件类型 up主类作为被观察者 观察者接口 粉丝类作为观察者 测试 测试结果 观察者模式中的角色 被观察者(observable)观察者(observer) 通过一个简单案例来演示观察者模式 被观察者接口 /*…

Linux sudo host权限提升漏洞(CVE-2025-32462)复现与原理分析

免责声明 本文所述漏洞复现方法仅供安全研究及授权测试使用&#xff1b; 任何个人/组织须在合法合规前提下实施&#xff0c;严禁用于非法目的&#xff1b; 作者不对任何滥用行为及后果负责&#xff0c;如发现新漏洞请及时联系厂商并遵循漏洞披露规则。 漏洞简述 Linux sudo是l…

【uni-ui】hbuilderx的uniapp 配置 -小程序左滑出现删除等功能

1.网址&#xff1a;https://ext.dcloud.net.cn/plugin?id181](https://ext.dcloud.net.cn/plugin?id181) 2.csdn讲解&#xff1a;https://blog.csdn.net/qq_40323256/article/details/114337128 3.uni-ui git&#xff1a;https://github.com/dcloudio/uni-ui 4.官方网址文档&…

记一次POST请求中URL中文参数乱码问题的解决方案

POST请求中URL中文参数乱码前言&#xff1a;一个常见的开发痛点一、问题现象与原因深度解析1. 典型问题场景2. 根本原因分析URL编码规范问题&#xff1a;编码解码过程不一致&#xff1a;IE浏览器特殊行为&#xff1a;二、前端解决方案1. 手动编码URL参数&#xff08;推荐&#…

从存储热迁移流程了解 QEMU block layer

文章目录存储热迁移流程总体流程代码路径QEMU Block layer架构简述Block Job结构体设计状态转换Mirror block job拓扑结构构建过程数据结构存储热迁移流程 总体流程 Libvirt migrate 命令提供 copy-storage-all 选项支持存储热迁移&#xff0c;相应地&#xff0c;Libvirt 热迁…

【设计模式】命令模式 (动作(Action)模式或事务(Transaction)模式)宏命令

命令模式&#xff08;Command Pattern&#xff09;详解一、命令模式简介 命令模式&#xff08;Command Pattern&#xff09; 是一种 行为型设计模式&#xff08;对象行为型模式&#xff09;&#xff0c;它将一个请求封装为一个对象&#xff0c;从而使你可以用不同的请求对客户进…

HTML5智能排班日历:动态排班一目了然

这个日历将具备以下功能: 显示一个标准的月度日历视图。可以自由切换上一个月和下一个月。在日历的每一天自动显示当天值班的人员。您可以很方便地在文件中修改值班人员列表和排班的起始日期。包括:动态生成日历网格处理月份切换根据排班规则计算并显示每天的值班人员<!DO…

深度剖析C++生态系统:一门老牌语言如何在开源浪潮中焕发新生?

&#x1f4dd;个人主页&#x1f339;&#xff1a;慌ZHANG-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 一、前言&#xff1a;C的“长寿秘诀”是什么&#xff1f; C 诞生已超过 40 年。它经历了桌面应用、互联网爆发、移动时代&#xff0c;再…

60个功能OfficeBox 万彩办公大师:PDF 格式转换 OCR识别免费无广告

各位办公小能手们&#xff01;今天给大家介绍个超厉害的免费办公工具套装——OfficeBox万彩办公大师&#xff0c;是广州万彩科技整出来的。软件下载地址安装包 它里面有60多个没广告的绿色组件&#xff0c;简直像个百宝箱&#xff01;涵盖了PDF处理、格式转换、OCR识别、屏幕录…