首页 > 编程语言 >c++ CMakeLists.txt详解

c++ CMakeLists.txt详解

时间:2024-12-11 23:01:27浏览次数:5  
标签:CMakeLists include int c++ add 模块 cpp txt

基本结构

  1. CMake 最低版本声明
    用于指定需要的最低 CMake 版本,确保兼容性。
cmake_minimum_required(VERSION 3.10)
  • 指定 CMake 的最低版本。
  • 确保用户的 CMake 版本符合项目需求,否则报错。
  • 版本选择建议根据项目使用的功能决定。例如,3.10 引入了 target_link_directories
  1. 项目名称和语言定义
    定义项目的名称及支持的编程语言。
project(ProjectName LANGUAGES C CXX)
  • ProjectName:项目名称,自动赋值给变量 ${PROJECT_NAME}
  • LANGUAGES:指定项目支持的语言,可以是 CCXX(C++)、Fortran 等。
  • 默认生成变量:
    • ${PROJECT_SOURCE_DIR}:项目根目录。
    • ${PROJECT_BINARY_DIR}:构建目录。
  1. 设置编译选项
    设置标准版本(如 C++17)或添加额外的编译器选项。
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
  • CMAKE_CXX_STANDARD:设置 C++ 标准(如 11、14、17、20)。
  • CMAKE_CXX_STANDARD_REQUIRED:强制使用指定版本。
  • CMAKE_CXX_EXTENSIONS:是否使用非标准扩展(如 -std=gnu++17)。
  1. 定义源文件和头文件路径
    将源代码组织到变量中,或直接指定路径。
set(SOURCES src/main.cpp src/foo.cpp)
set(INCLUDES include/)
  1. 生成可执行文件或库
    指定目标类型(可执行文件、静态库、动态库)。
# 添加可执行文件
add_executable(MyApp ${SOURCES})

# 添加静态库
add_library(MyStaticLib STATIC src/foo.cpp src/bar.cpp)

# 添加动态库
add_library(MySharedLib SHARED src/foo.cpp src/bar.cpp)
  1. 设置目标的头文件路径
    将头文件目录添加到目标的构建路径中。
target_include_directories(MyApp PRIVATE ${INCLUDES})
  1. 链接内部库
    链接外部依赖库或内部生成的库。
target_link_libraries(MyApp PRIVATE MyLib)
  1. 查找外部库(可选)
    查找并使用外部库(如 Boost 或 OpenCV)。
find_package(OpenCV REQUIRED)
target_link_libraries(MyApp PRIVATE ${OpenCV_LIBS})
  1. 安装规则
    指定生成的二进制文件、配置文件等的安装路径。
install(TARGETS MyApp DESTINATION bin)
install(FILES config/settings.conf DESTINATION etc)
  • install() 定义安装文件的位置。
  • 常见用途:
    • 安装可执行文件到 bin
    • 安装库到 lib
    • 安装配置文件到 etc
  1. 测试支持(可选)
    启用单元测试功能。
enable_testing()
add_test(NAME MyTest COMMAND MyApp --test)
  1. 子目录管理(可选)
    用于大型项目,将多个模块分割到不同的子目录。
add_subdirectory(src/module1)
  • 对于大型项目,将代码分割到子目录中,通过 add_subdirectory() 引入。

子模块的 CMakeLists.txt

add_library(Module1 STATIC module1.cpp)
target_include_directories(Module1 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
  1. 添加自定义命令和目标(可选)
  • 添加自定义命令
add_custom_command(
    OUTPUT generated.cpp
    COMMAND python generate.py > generated.cpp
    DEPENDS generate.py
)
  • 添加自定义目标
add_custom_target(GenerateCode ALL DEPENDS generated.cpp)
  1. 使用变量和条件(动态配置)
  • 条件语句
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
    message("Debug build")
endif()
  • 变量替换
set(VERSION "1.0.0")
message("Project version: ${VERSION}")

示例1:单模块(c++)

项目结构

MyProject/
├── CMakeLists.txt
├── src/
│   ├── main.cpp
│   ├── foo.cpp
├── include/
│   └── foo.h
└── config/
    └── settings.conf

代码文件

  • src/main.cpp:
#include <iostream>
#include "foo.h"

int main() {
    std::cout << "Sum of 3 and 5 is: " << add(3, 5) << std::endl;
    return 0;
}
  • src/foo.cpp:
#include "foo.h"

int add(int a, int b) {
    return a + b;
}
  • include/foo.h:
#ifndef FOO_H
#define FOO_H

int add(int a, int b);

#endif
  • config/settings.conf:
# This is a placeholder configuration file

CMakelist.txt

# 设置 CMake 最低版本
cmake_minimum_required(VERSION 3.10)

# 定义项目名称和语言
project(MyProject LANGUAGES CXX)

# 设置编译选项
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 定义源文件和头文件目录
set(SOURCES
    src/main.cpp
    src/foo.cpp
)

set(INCLUDES
    include/
)

# 添加可执行目标
add_executable(MyApp ${SOURCES})

# 配置头文件路径
target_include_directories(MyApp PRIVATE ${INCLUDES})

# 安装规则
install(TARGETS MyApp DESTINATION bin)
install(FILES config/settings.conf DESTINATION etc)

# 启用测试支持
enable_testing()
add_test(NAME RunTests COMMAND MyApp)

构建和运行

1. 创建构建目录

为了保持源文件清晰,推荐在源代码目录外创建构建目录:

mkdir build
cd build

2. 运行 CMake

使用 CMake 生成构建文件:

cmake ..

3. 编译项目

使用 CMake 的构建命令:

cmake --build .

4. 运行程序

./MyApp

5. 安装程序

将可执行文件和配置文件安装到指定目录:

cmake --install .

示例2:多模块(c++)

项目结构

MyProject/
├── CMakeLists.txt         # 顶层 CMakeLists.txt
├── module1/               # 模块1
│   ├── CMakeLists.txt     # 模块1的 CMakeLists.txt
│   ├── module1.cpp
│   └── module1.h
├── module2/               # 模块2
│   ├── CMakeLists.txt     # 模块2的 CMakeLists.txt
│   ├── module2.cpp
│   └── module2.h
├── app/                   # 主程序
│   ├── CMakeLists.txt     # 主程序的 CMakeLists.txt
│   ├── main.cpp
└── build/                 # 构建目录

顶层 CMakeLists.txt

顶层的 CMakeLists.txt 文件负责整体项目的配置,包括引入各个模块、设置编译选项以及定义最终的构建目标。

# 设置最低 CMake 版本
cmake_minimum_required(VERSION 3.10)

# 定义项目名称和语言
project(MyProject LANGUAGES CXX)

# 设置编译选项
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 添加子模块目录
add_subdirectory(module1)
add_subdirectory(module2)
add_subdirectory(app)

模块1的 CMakeLists.txt

模块1构建为一个静态库,提供对其他模块的功能支持。

# 定义模块1的库
add_library(Module1 STATIC module1.cpp)

# 指定模块1的头文件路径
target_include_directories(Module1 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

# 可选:设置特定的编译选项(如果模块需要)
target_compile_options(Module1 PRIVATE -Wall -Wextra)

模块2的 CMakeLists.txt

模块2构建为一个动态库,并依赖模块1。

# 定义模块2的库
add_library(Module2 SHARED module2.cpp)

# 指定模块2的头文件路径
target_include_directories(Module2 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

# 链接模块1
target_link_libraries(Module2 PUBLIC Module1)

主程序的 CMakeLists.txt

主程序依赖模块1和模块2,并最终生成可执行文件。

# 定义主程序的可执行目标
add_executable(MyApp main.cpp)

# 链接模块1和模块2
target_link_libraries(MyApp PRIVATE Module1 Module2)

# 指定主程序的头文件路径(如果需要)
target_include_directories(MyApp PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})

示例代码

  • module1/module1.h
#ifndef MODULE1_H
#define MODULE1_H

int add(int a, int b);

#endif
  • module1/module1.cpp
#include "module1.h"

int add(int a, int b) {
    return a + b;
}
  • module2/module2.h
#ifndef MODULE2_H
#define MODULE2_H

int multiply(int a, int b);

#endif
  • module2/module2.cpp
#include "module2.h"
#include "module1.h"

int multiply(int a, int b) {
    return a * add(a, b);  // 使用模块1的功能
}
  • app/main.cpp
#include <iostream>
#include "module1.h"
#include "module2.h"

int main() {
    int a = 3, b = 5;
    std::cout << "Add: " << add(a, b) << std::endl;
    std::cout << "Multiply: " << multiply(a, b) << std::endl;
    return 0;
}

功能扩展

  • 模块化管理: 将子模块组织到不同目录,并通过 add_subdirectory() 引入。

  • 外部库集成: 使用 find_package()target_link_libraries() 管理外部库。

  • 生成静态库: 使用 add_library() 定义静态库目标,并链接到其他可执行文件。

  • 跨平台支持: CMake 支持跨平台构建(如 Makefile、Visual Studio 项目文件等)。

标签:CMakeLists,include,int,c++,add,模块,cpp,txt
From: https://blog.csdn.net/www_dong/article/details/144412254

相关文章

  • 【2024年华为秋招-12月11日-第二题(200分)- 服务器训练任务调度】(题目+思路+Java&C++&Py
    题目内容团队申请了一组服务器,用于机器学习训练,为了充分利用资源,需要你来完成任务调度算法的实现。一台服务器同一时间只能执行一个训练任务,每个训练任务有训练时间和优先级。当空闲服务器不足时,优先执行高优先级的训练任务;如果多个训练任务的优先级相同,优先执行训练时......
  • C++学习笔记 循环结构
    学习编程语言语法是次要的,思维是主要的。如何把头脑中的想法变成简洁的代码,至关重要。——闫学灿学习循环语句只需要抓住一点——代码执行顺序!一、while循环可以简单理解为循环版的if语句。if语句是判断一次,如果条件成立,则执行后面的语句;while是每次判断,如果条件成立,则执行循......
  • C++游戏开发探秘【2】
    成长路上不孤单......
  • C++刷题笔记-括号生成
    一、题目描述正整数n代表生成括号的对数,请设计一个函数,用于能够生成所有可能且有效的括号组合。二、测试用例示例一:输入:n=3输出:["((()))","(()())","(())()","()(())","()()()"]示例二:输入:n=1输出:["()"]三、回溯法求解回溯算法会系统地探索所有可能的候选解,当确定......
  • C++学习笔记 printf语句与判断结构
    一、printf输出格式注意:使用printf时最好添加头文件`#include`。#include<iostream>#include<cstdio>usingnamespacestd;intmain(){printf("HelloWorld!");return0;}int、float、double、char等类型的输出格式:(1)int:%d(2)float:%f,默认保......
  • C++中的虚函数和纯虚函数
     在C++中,虚函数和纯虚函数都有助于实现多态性,但它们之间有几个重要的区别。 一、虚函数(VirtualFunction)1.定义:当你在基类中使用virtual关键字声明一个成员函数时,你就创建了一个虚函数。这意味着即使通过基类指针或引用调用了该函数,实际执行的可能是派生类中重写的......
  • C++学习笔记 入门及简单的顺序结构
    编写一个简单的C++程序——手速练习#include<iostream>usingnamespacestd;intmain(){cout<<"HelloWorld"<<endl;return0;}语法基础变量的定义变量必须先定义,才可以使用。不能重名。变量定义的方式:#include<iostream>usingnamespacestd;......
  • 《智领未来:C++ 与遗传算法在 AI 模型参数优化中的深度融合》
    在人工智能领域,模型的性能往往取决于众多参数的合理设置。而遗传算法,作为一种强大的优化工具,为寻找最优参数提供了一种高效且智能的途径。当我们将遗传算法与C++的高效性能相结合时,更能在人工智能模型参数优化中大展身手。本文将深入探讨在C++中实现遗传算法并应用于人工......
  • 《数据流驱动:C++构建 AI 模型持续学习新范式》
    在人工智能领域不断发展演进的浪潮中,数据的持续流入和模型的适应性学习成为了新的焦点。传统的人工智能模型训练往往基于固定的数据集,在模型训练完成后难以有效地处理新到达的数据并持续提升性能。而基于数据流的人工智能模型持续学习系统则能够打破这种局限,让模型在动态变......
  • 【最新原创毕设】基于SpringBoot的学生选课管理系统+56695(免费领源码)可做计算机毕业设
    基于Springboot和Vue的学生选课管理系统的设计与实现摘 要本文介绍了一种基于SpringBoot和Vue的学生选课管理系统的设计与实现。该系统旨在提供一个高效、可靠的选课平台,使学生和教职工能够方便地进行课程选择和管理。在系统设计上,我们采用了SpringBoot作为后端框架,利用......