CMake 入门实践

news2025/5/11 13:47:21

CMake 入门实践

    • 第一章 概念与基础项目
      • 1.1 CMake 基础认知
      • 1.2 最小 CMake 项目
      • 1.3 构建流程验证
    • 第二章 多文件项目管理
      • 2.1 项目结构
      • 2.2 源码示例
      • 2.3 CMake 配置
    • 第三章 库文件管理实战
      • 3.1 项目结构
      • 3.2 核心配置
      • 3.3 接口设计
    • 第四章 构建类型与编译优化
      • 4.1 构建类型配置
      • 4.2 构建验证
      • 4.3 不同构建方式
    • 第五章 实用的高级技巧
      • 5.1 变量与缓存机制
      • 5.2 条件控制语句
      • 5.3 自动查找依赖
    • 第六章 跨平台构建实战
      • 6.1 平台检测与处理
      • 6.2 安装规则

第一章 概念与基础项目

1.1 CMake 基础认知

  • 跨平台构建系统生成器:通过抽象生成 Makefile、Visual Studio 项目等
  • 声明式构建系统:描述【要构建什么】,而非【如何构建】
  • 核心文件:通过 CMakeLists.txt 描述项目结构关系

1.2 最小 CMake 项目

// main.cpp
#include <iostream>

int main() {
    std::cout << "Hello CMake! (v1.0)\n";
    return 0;
}
# CMakeLists.txt
cmake_minimum_required(VERSION 3.10)  # 最低版本保障
project(HelloCMake VERSION 1.0)       # 项目元数据

add_executable(hello main.cpp)       # 核心构建指令

1.3 构建流程验证

mkdir build && cd build       # 创建构建目录
cmake ..                     # 生成构建系统文件
cmake --build .              # 执行编译命令
./hello                     # 运行可执行文件

在这里插入图片描述

第二章 多文件项目管理

2.1 项目结构

multi_project/
├── CMakeLists.txt
├── src/
│   ├── main.cpp
│   ├── math.cpp
│   └── math.h

2.2 源码示例

// math.h
#pragma once
int square(int x);
// math.cpp
#include "math.h"

int square(int x) {
    return x * x;
}
// main.cpp
#include "math.h"
#include <iostream>

int main() {
    std::cout << "5² = " << square(5) << std::endl;
    return 0;
}

2.3 CMake 配置

cmake_minimum_required(VERSION 3.10)
project(MultiFileDemo)

# 设置C++标准
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 显式包含目录
include_directories(${PROJECT_SOURCE_DIR}/)

# 收集源文件
file(GLOB SOURCES "src/*.cpp")

# 创建可执行文件
add_executable(demo ${SOURCES})

在这里插入图片描述

第三章 库文件管理实战

3.1 项目结构

library_project/
├── CMakeLists.txt
├── include/
│   └── calculator.h
├── src/
│   ├── CMakeLists.txt
│   ├── main.cpp
└── lib/
    ├── CMakeLists.txt
    └── calculator.cpp

3.2 核心配置

# 根目录 CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(LibraryDemo)

add_subdirectory(lib)
add_subdirectory(src)
# lib/CMakeLists.txt
add_library(calc STATIC calculator.cpp)
target_include_directories(calc PUBLIC
    ${CMAKE_SOURCE_DIR}/include)
# src/CMakeLists.txt
add_executable(app main.cpp)
target_link_libraries(app PRIVATE calc)

3.3 接口设计

// calculator.h
#pragma once

class Calculator {
public:
    static double cube(double x);
};
// calculator.cpp
#include "calculator.h"

double Calculator::cube(double x) {
    return x * x * x;
}

int main(void)
{
    return 0;
}

在这里插入图片描述

第四章 构建类型与编译优化

4.1 构建类型配置

if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE "Debug" CACHE STRING
        "Choose build type" FORCE)
endif()

message("当前构建类型: ${CMAKE_BUILD_TYPE}")

string(TOUPPER "${CMAKE_BUILD_TYPE}" build_type)

if(build_type STREQUAL "DEBUG")
    add_compile_options(-g -O0 -Wall -Wpedantic)
else()
    add_compile_options(-O3 -DNDEBUG)
endif()

4.2 构建验证

#include <iostream>
#include <cassert>

int main() {
#ifdef NDEBUG
    std::cout << "Release 模式\n";
#else
    std::cout << "Debug 模式\n";
    assert(1 + 1 == 3);  // 测试断言
#endif
    return 0;
}

4.3 不同构建方式

# Debug 模式(默认)
cmake -DCMAKE_BUILD_TYPE=Debug ..
cmake --build .
./demo  # 触发断言错误

# Release 模式
cmake -DCMAKE_BUILD_TYPE=Release ..
cmake --build .
./demo  # 关闭断言

第五章 实用的高级技巧

5.1 变量与缓存机制

# 定义普通变量
set(MY_VAR "value")

# 缓存变量(用户可配置)
set(USE_FEATURE_X OFF CACHE BOOL "启用特性X")

# 环境变量
message("当前PATH: $ENV{PATH}")

5.2 条件控制语句

if(MSVC)
    add_definitions(-D_WIN32)
elseif(UNIX)
    add_definitions(-D_LINUX)
endif()

5.3 自动查找依赖

find_package(OpenCV REQUIRED)
if(OpenCV_FOUND)
    target_link_libraries(my_app PRIVATE ${OpenCV_LIBS})
endif()

第六章 跨平台构建实战

6.1 平台检测与处理

if(WIN32)
    # Windows特定设置
    add_definitions(-DWINDOWS_PLATFORM)
elseif(APPLE)
    # macOS特定设置
    add_definitions(-DMACOS)
else()
    # Linux设置
    add_definitions(-DLINUX)
endif()

6.2 安装规则

install(TARGETS demo
    RUNTIME DESTINATION bin
    LIBRARY DESTINATION lib
    ARCHIVE DESTINATION lib
)

install(DIRECTORY include/ DESTINATION include)

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

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

相关文章

异地多活单元化架构下的微服务体系

治理服务间的跨IDC调用&#xff0c;而数据库层面还是要跨IDC 服务注册中心拆开、 金融要求&#xff0c;距离太远&#xff0c;异地备库&#xff0c;如果延迟没读到数据就可能有资损&#xff0c;IDC3平时不能用&#xff0c;IDC1挂了还是有数据同步问题&#xff0c;IDC3日常维护…

HarmonyOS NEXT——DevEco Studio的使用(还没写完)

一、IDE环境的搭建 Windows环境 运行环境要求 为保证DevEco Studio正常运行&#xff0c;建议电脑配置满足如下要求&#xff1a; 操作系统&#xff1a;Windows10 64位、Windows11 64位 内存&#xff1a;16GB及以上 硬盘&#xff1a;100GB及以上 分辨率&#xff1a;1280*8…

Windows系统Jenkins企业级实战

目标 在Windows操作系统上使用Jenkins完成代码的自动拉取、编译、打包、发布工作。 实施 1.安装Java开发工具包&#xff08;JDK&#xff09; Jenkins是基于Java的应用程序&#xff0c;因此需要先安装JDK。可以从Oracle官网或OpenJDK下载适合的JDK版本。推荐java17版本&#x…

C# 方法(ref局部变量和ref返回)

>本章内容: 方法的结构 方法体内部的代码执行 局部变量 局部常量 控制流 方法调用 返回值 返回语句和void方法 局部函数 参数 值参数 引用参数 引用类型作为值参数和引用参数 输出参数 参数数组 参数类型总结 方法重载 命名参数 可选参数 栈帧 递归 ref局部变量和ref返回 …

滑动窗口,438找出字符串中所有字母的异位词

1.题目 2.解析 这道题我们用滑动窗口来实现&#xff0c;加上哈希表和vector容器的使用来实现这道题目&#xff0c;每次滑动之后我们都对其和答案进行比较&#xff0c;如果全部相等我们返回left&#xff0c;不相等继续滑动即可。 本质就是我们把p中相同数量的字母框起来&#…

「国产嵌入式仿真平台:高精度虚实融合如何终结Proteus时代?」——从教学实验到低空经济,揭秘新一代AI赋能的产业级教学工具

引言&#xff1a;从Proteus到国产平台的范式革新 在高校嵌入式实验教学中&#xff0c;仿真工具的选择直接影响学生的工程能力培养与创新思维发展。长期以来&#xff0c;Proteus作为经典工具占据主导地位&#xff0c;但其设计理念已难以满足现代复杂系统教学与国产化技术需求。…

《Python星球日记》 第52天:反向传播与优化器

名人说&#xff1a;路漫漫其修远兮&#xff0c;吾将上下而求索。—— 屈原《离骚》 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 一、引言二、反向传播算法原理简述1. 什么是反向传播&#xff1f;2. 从数学角度…

Java常用类概述

Java常用类概述 一、字符串三剑客1. String&#xff08;不可变字符串&#xff09;2. StringBuilder&#xff08;可变&#xff0c;线程不安全&#xff09;3. StringBuffer&#xff08;可变&#xff0c;线程安全&#xff09; 二、日期时间类&#xff08;重点掌握新版API&#xff…

C++STL——priority_queue

优先队列 前言优先队列仿函数头文件 前言 本篇主要讲解优先队列及其底层实现。 优先队列 优先队列的本质就是个堆&#xff0c;其与queue一样&#xff0c;都是容器适配器&#xff0c;不过优先队列是默认为vector实现的。priority_queue的接口优先队列默认为大根堆。 仿函数 …

深入解析WPF中的3D图形编程:材质与光照

引言 在Windows Presentation Foundation (WPF) 中创建三维(3D)图形是一项既有趣又具有挑战性的任务。为了帮助开发者更好地理解如何使用WPF进行3D图形的渲染&#xff0c;本文将深入探讨GeometryModel3D类及其相关的材质和光源设置。 1、GeometryModel3D类简介 GeometryMode…

SolidWork-2023 鼠標工程

地址 https://github.com/MartinxMax/SW2023-Project/tree/main/mouse 鼠標

vscode预览模式(点击文件时默认覆盖当前标签,标签名称显示为斜体,可通过双击该标签取消)覆盖标签、新窗打开

文章目录 VS Code 预览模式如何取消预览模式&#xff08;即“固定”标签页&#xff09;&#xff1f;预览模式有什么用&#xff1f; VS Code 预览模式 在 VS Code 中&#xff0c;当你单击文件浏览器&#xff08;例如&#xff0c;资源管理器侧边栏&#xff09;中的某个文件时&am…

记录踩过的坑-金蝶云苍穹平台-轻分析和轻报表(慢慢更新)

未发现AppIdName(qing rpt)服务或访问服务网络异常 前提是有许可和权限。 去console&#xff08;云基础平台控制台&#xff09;&#xff0c;点击服务管理&#xff0c;编辑mservice-更新升级-环境变量&#xff0c;在appIds里增加qing_rpt 查看数据库 如果是采用公共数据源连接…

每日一题洛谷T534125 合数c++

字符串输入&#xff0c;看所有位数加起来的数是不是3的倍数 是&#xff0c;直接输出&#xff0c;不是&#xff0c;删除1或2 特判全是1和全是2的情况 直接检测末尾数字可以特判2 特判1时&#xff0c;还要特判11和111&#xff0c;其他数字&#xff0c;k是奇数时是质数&#x…

数据链共享:从印巴空战到工业控制的跨越性应用

摘要 本文通过对印巴空战中数据链共享发挥关键作用的分析&#xff0c;引出数据链共享在工业控制领域同样具有重大价值的观点。深入阐述 DIOS 工业控制操作系统作为工业数据链共享基础技术的特点、架构及应用优势&#xff0c;对比空战场景与工业控制场景下数据链共享的相…

图解gpt之Seq2Seq架构与序列到序列模型

今天深入探讨如何构建更强大的序列到序列模型&#xff0c;特别是Seq2Seq架构。序列到序列模型&#xff0c;顾名思义&#xff0c;它的核心任务就是将一个序列映射到另一个序列。这个序列可以是文本&#xff0c;也可以是其他符号序列。最早&#xff0c;人们尝试用一个单一的RNN来…

Linux--JsonCpp

1.JsonCpp 简介 JsonCpp 是一个用于 C 的 JSON 解析和生成库&#xff0c;支持 JSON 数据的读写、解析和序列化。它提供了简单的 API 来操作 JSON 对象、数组、字符串、数字等类型&#xff0c;是 C 开发中处理 JSON 数据的常用工具。 核心功能与类 JsonCpp 主要包含以下核心类…

如何利用 QuickAPI 生成 PostgreSQL 样本测试数据:全面解析与实用指南

目录 一、什么是 QuickAPI&#xff1f; 二、为什么需要生成样本测试数据&#xff1f; 三、如何在 QuickAPI 中生成 PostgreSQL 样本测试数据&#xff1f; 1. 登录 QuickAPI 平台 2. 选择 PostgreSQL 数据库和目标表 3. 配置样本数据生成规则 4. 导出或直接插入数据 四、…

DeepSeek API接口调用示例(开发语言C#,替换其中key值为自己的key值即可)

示例&#xff1a; DeepSeek官方接口说明文档&#xff1a;对话补全 | DeepSeek API Docs 官网暂未提供C#代码实现&#xff1a;&#xff08;以下为根据CURL接口C#代码调用&#xff09; using System; using System.Collections.Generic; using System.Linq; using System.Text; …

远程调试---在电脑上devtools调试运行在手机上的应用

1、启动项目–以vite项目为例:先ipconfig查看ip地址 ,然后在vite中配置host为ip地址 2、手机上查看项目:保证手机和电脑在同一局域网, 在手机浏览器打开我们vite启动的项目地址, 3、使用chii进行远程调试 (1) 安装 npm install chii -g (2)启动 chii start -p 8080 (3)在…