首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【CMake】使用 CMake 将单模块 C 项目构建为库并链接主程序

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

作者头像
LuckiBit
发布2025-07-18 14:29:21
发布2025-07-18 14:29:21
3120
举报
文章被收录于专栏:C语言C语言

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

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

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

1. 项目结构设计

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

代码语言:javascript
复制
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
代码语言:javascript
复制
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 ✅【推荐写法】
代码语言:javascript
复制
# 可选但推荐:模块自身声明(便于大型项目调试)
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
代码语言:javascript
复制
#ifndef COLOR_H
#define COLOR_H

void set_color(void);

#endif

2.4 模块实现文件 src/color/color.c
代码语言:javascript
复制
#include <stdio.h>
#include "color.h"

void set_color(void) {
    printf("Set color called!\n");
}

2.5 主程序 src/main.c
代码语言:javascript
复制
#include "color.h"

int main() {
    set_color();
    return 0;
}

3. 构建与运行步骤

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

代码语言:javascript
复制
mkdir build
cd build
cmake ..
make
./bin/ColorApp
✅ 运行输出:
代码语言:javascript
复制
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 中检测平台
代码语言:javascript
复制
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/macOS

cmake .. && make

Windows MinGW

cmake -G "MinGW Makefiles" .. && mingw32-make

Windows Visual Studio

cmake -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. 最终项目结构(含构建结果)

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

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

代码语言:javascript
复制
# 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. 感谢各位的阅读和支持,如果觉得这篇文章对你有帮助,请不要吝惜你的点赞和评论,这对我们非常重要。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-07-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 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. 结束语
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档