CMAKE教程大全

介绍

CMake 是一个跨平台的自动化构建系统,它使用配置文件(称为 CMakeLists.txt)来生成标准的构建文件,如 Unix 的 Makefile 或 Windows 的 Visual Studio 工程文件。CMake 能够支持多种编程语言,尤其是 C 和 C++,并且可以与多种编译器和构建工具配合使用。

以下是 CMake 的一些关键特点:

  1. 跨平台支持: CMake 支持在 Windows、Linux、macOS 等多种操作系统上构建项目。

  2. 生成多种构建系统: CMake 可以生成多种构建系统的文件,包括 Make、Ninja、Xcode 和 Visual Studio 解决方案等。

  3. 模块化: CMake 提供了模块化的设计,允许开发者重用代码和设置。

  4. 自定义构建类型: CMake 允许定义不同的构建类型,如 Debug、Release 或自定义构建类型。

  5. 依赖管理: CMake 可以处理复杂的依赖关系,并自动下载和集成第三方库。

  6. 测试驱动开发(TDD): CMake 支持 CTest,这是一个测试驱动开发工具,可以轻松地集成到构建过程中。

  7. 安装和打包: CMake 提供了安装目标和打包支持,可以生成安装程序和软件包。

  8. 变量和条件逻辑: CMake 脚本使用变量和条件逻辑来控制构建过程,使得构建配置非常灵活。

  9. 查找和配置外部库: CMake 可以查找和配置外部库,使得集成第三方库变得简单。

  10. 多配置工具: CMake 支持多配置工具,这意味着它可以生成支持多个配置(如 Debug 和 Release)的构建系统。

  11. IDE 集成: CMake 可以生成 IDE 项目文件,如 Visual Studio 或 Xcode 项目,使得在这些环境中工作变得容易。

CMake 的基本工作流程包括:

  • 编写 CMakeLists.txt 文件,定义项目的构建规则和配置。
  • 运行 cmake 命令,指定源代码目录和构建目录,生成构建系统。
  • 使用生成的构建系统(如 Make 或 IDE)来编译和构建项目。

CMake 是许多开源项目和商业软件的首选构建系统,因为它的灵活性和强大的功能使得它能够适应各种复杂的构建需求。

外部构建

可能有人会问,它不能像Makefile一样直接make clean 或者make distclean清除编译的垃圾文件吗,我当时学的时候也谷歌过,但是,很遗憾没有,使用我才让它产生的垃圾文件放在build目录下,其实不能说是垃圾文件,只不过是一些中间文件,记录某些东西的,我用不上它,所以认为是垃圾…仅此而已。

对此官方的解释是:

CMakeLists.txt 可以执行脚本并通过脚本生成一些临时文件,但是却没有办法来跟踪这些临时文件到底是哪些,因此,没有办法提供一个可靠的 clean 方案。

CMAKE常用示例

链接多个动态库示例

set(LIBRARY_NAMES pub jsoncpp )
set(LIBRARIES)

foreach(LIBRARY_NAME ${LIBRARY_NAMES})
    #清除旧缓存,强制重新查找
    unset(LIBRARY_PATH CACHE)

    find_library(LIBRARY_PATH ${LIBRARY_NAME} ${LIBDIR} )
    if(NOT LIBRARY_PATH)
        message(FATAL_ERROR "Could not find library ${LIBRARY_NAME}")
    endif()
    message(" find library ${LIBRARY_NAME} ${LIBRARY_PATH}")

    list(APPEND LIBRARIES  ${LIBRARY_PATH})
    message(" LIBRARIES ${LIBRARIES} ")

endforeach()

target_link_libraries(relay_ticket_check_server ${LIBS}   ${LIBRARIES}) #链接可执行程序

指定编译选项


set(CMAKE_CXX_STANDARD 11) #测试不会生效
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)  #禁用编译器特有的扩展(可选,推荐)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w -std=c++11 ")  #启动c++11和忽略警告

set(EXECUTABLE_OUTPUT_PATH $ENV{HOME}/bin ) #设置输出路径

常用的命令

指定最低版本:cmake_minium_required

指定使用的cmake最低版本

定义工程名称:protect

定义工程名称

 生成可执行程序:add_executable

定义工程会生成一个可执行程序,生成的程序,和项目名没有关系。

 

执行cmake生成形式

执行版本为 Debug还是Release,有时候构建报错::-1: error: No "Debug" CMake configuration found. Available configuration: "".
Make sure that CMAKE_BUILD_TYPE variable matches the "Build type" field. 就需要添加这个参数

执行cmake

注意 

 在Windows下使用cmake ..  会生成vs的项目架构。不会生成MakeFile文件,如果windows下想要生成MakeFile需要输入命令  cmake ../ -G "Unix Makefiles"。来生成,最后执行make命令进行项目的编译。

这里有些人使用  cmake ../ -G "Unix Makefiles会报错:

要保证 MinGW 的 bin 目录(例如 C:\MinGW\bin)已经添加到系统的 PATH 环境变量中。

配置完成后,关闭终端在尝试,即可正常使用。

这里要是失败,可以使用 cmake .. -G "MinGW Makefiles"  代替,编译完成后使用mingw32-make.exe进程构建。

cmake的环境变量设置为:D:\C++\Qt\Tools\mingw810_64\bin

先输入cmake ../ -G "MinGW Makefiles" 然后输入mingw32-make

先输入cmake ../ -G "Unix Makefiles" 然后输入make

先输入cmake ..生成vs项目然后使用vs构建。

私人定制

定义变量:set

 指定使用的C++标准:CMAKE_CXX_STANDARD

指定输出路径:EXECUTABLE_OUTPUT_PATH

如果指定的路径不存在,那么cmake会自动创建多层级的目录。

 搜索文件

方式一:aux_source_directory

PROJECT_SOURCE_DIR:搜索cmake 执行后后面指定路径的当前源文件路径下的文件.c .cpp ,添加到SRC_LISTS中
 

 方式二:file

CMAKE_CURRENT_SOURCE_DIR: CMAKE文件所对应的路径  经过本人亲测:file只搜索cpp文件,也是可以编译通过的。file 可以作拷贝的功能。

包含头文件路径:include_directories

        

或者写入绝对路径:绝对路径使用“”包含,路径中使用/进行链接,不能使用\。

link_directories

链接动态库的目录,看起来不能够生效。。。

 通过CMAKE制作库文件add_library

 静态库就是STATIC,动态库就是SHARED。

 指定动态库的输出路径

链接静态库 :link_libraries

链接动态库:target_link_libraries

 

如果程序中要使用多条这样的句子,那么必须保证,每种都指定权限。否则,会报错。

target_link_libraries(simple1 PUBLIC ${VTKLIBS} ) #当target_link_libraries出现多次时,需要明确指出用public
 

打印日志

CMake构建的时候,你可能不知道某些变量是啥内容,那么就在终端打印出来看看就好了,这根我们写代码中的printf函数差不多,给直接打一串字符串出来瞧瞧…

file(GLOB VTKLIBS E:/VTK/vs_install/lib/*.lib)
message(VTKLIBS = ${VTKLIBS})

这个还可以用于拷贝:file(COPY ${ASSETS} DESTINATION ${CMAKE_BINARY_DIR} )

 添加子目录

add_subdirectory(wrapper)    wrapper为子目录名称
在子目录里可以链接静态库,使用add_library(wrapper    ${WRAPPER})

将所有cpp文件链接到这个wrapper lib库中。 默认生成静态库,动态库编译不过去
 

 宏定义:add_definitions

在 CMake 中,add_definitions 命令用于向编译器添加宏定义。这在你需要在编译时定义一些预处理器宏时非常有用。add_definitions 是 CMake 的一个函数,它允许你指定一组宏定义,这些宏定义会在编译时被添加到编译器的命令行中。

以下是如何使用 add_definitions 的基本语法:

add_definitions(-DMY_MACRO)

在这个例子中,-DMY_MACRO 会被添加到编译器的命令行中,这样在编译过程中 MY_MACRO 就会被定义。

使用 target_compile_definitions 添加特定目标的宏定义

如果你只想为某个特定目标添加宏定义,可以使用 target_compile_definitions 函数。这允许你为特定的目标(例如可执行文件或库)指定一组宏定义。

add_executable(my_executable source1.cpp source2.cpp)
target_compile_definitions(my_executable PRIVATE -DMY_MACRO)

使用 target_compile_definitions 添加多个宏定义

你可以一次性添加多个宏定义:

target_compile_definitions(my_executable PRIVATE
    -DMY_MACRO
    -DOTHER_MACRO=value
)

这会在编译 my_executable 时定义 MY_MACROOTHER_MACRO

在 CMakeLists.txt 中使用

CMakeLists.txt 文件中使用 add_definitions 通常是为了全局地添加宏定义,影响所有的目标。例如:

cmake_minimum_required(VERSION 3.1)
project(MyProject)

add_definitions(-DMY_MACRO)

add_executable(my_executable source1.cpp source2.cpp)

在这个例子中,MY_MACRO 会被定义在所有的目标中。

注意事项

  • 宏定义的值:如果宏定义需要一个值,确保在宏名称和值之间有空格,或者使用 $<value> 语法。

  • 条件编译:如果你只想在特定条件下添加宏定义,可以使用 if 语句来控制。

  • 清理:在某些情况下,你可能需要在清理构建目录时删除由宏定义生成的文件。

通过使用 add_definitionstarget_compile_definitions,你可以灵活地控制编译时的宏定义,从而影响编译行为。这对于调试、特性切换或平台特定的编译非常有用。

使用cmake命令行构建MSVC编译器项目。

我们在Qtcreator中可以直接在界面上点击构建就可以生成项目,但是如何用命令行进行构建呢?如何目录向Qtcreator一样清晰呢?

在 Windows 上使用 CMake 命令行指定使用 MSVC(Microsoft Visual C++)编译器进行编译,可以通过以下步骤实现:

1. 确保安装了必要的工具

  • 安装 Visual Studio:确保安装了 Visual Studio,并且安装了 C++ 开发工具集。可以通过 Visual Studio 安装程序来安装。

  • 安装 CMake:确保安装了 CMake,并且将其添加到系统的 PATH 环境变量中,这样可以在命令行中直接使用 cmake 命令。

2. 打开命令提示符或终端

打开命令提示符(CMD)或 PowerShell。

3. 使用 CMake 指定编译器

在命令行中,进入你的项目目录,然后使用以下命令来指定使用 MSVC 编译器。

方法一:指定生成器

CMake 允许通过 -G 参数指定生成器。对于 MSVC,可以指定为 Visual Studio,并指定版本号和平台。例如:

cmake -G "Visual Studio 17 2022" -A x64 ..
  • -G "Visual Studio 17 2022":指定使用 Visual Studio 2022 作为生成器。17 是 Visual Studio 2022 的内部版本号。

  • -A x64:指定目标平台为 64 位。如果你的目标平台是 32 位,可以使用 -A Win32

  • 通过cmake -h 查看手册

方法二:设置环境变量

如果不想在命令行中每次都指定生成器,可以通过设置环境变量来指定编译器。在命令行中运行以下命令:

set CC=cl
set CXX=cl
cmake ..
  • set CC=cl:设置 C 编译器为 MSVC 的 cl.exe

  • set CXX=cl:设置 C++ 编译器为 MSVC 的 cl.exe

  • cmake ..:运行 CMake 配置命令。

4. 构建项目

配置完成后,可以使用以下命令来构建项目:

cmake --build . --config Release
  • --build .:指定构建目录为当前目录。

  • --config Release:指定构建配置为 Release。如果需要构建 Debug 版本,可以将 Release 替换为 Debug

5. 示例

假设你的项目目录结构如下:

复制

my_project/
├── CMakeLists.txt
├── src/
│   └── main.cpp

my_project 目录下创建一个 build 目录,然后进入该目录:

cd my_project
mkdir build
cd build

运行以下命令来配置和构建项目:

cmake -G "Visual Studio 17 2022" -A x64 ..
cmake --build . --config Release

注意事项

  • 确保 Visual Studio 的安装路径已添加到系统的 PATH 环境变量中,否则可能找不到 cl.exe

  • 如果使用的是较旧版本的 Visual Studio,需要将生成器名称和版本号替换为对应的值。例如,对于 Visual Studio 2019,可以使用 -G "Visual Studio 16 2019"

  • 如果项目中使用了特定的工具链文件,可以在 CMake 命令中通过 -DCMAKE_TOOLCHAIN_FILE=<path> 参数指定工具链文件路径。

通过以上步骤,你就可以在 Windows 上使用 CMake 命令行指定使用 MSVC 编译器来编译项目了。

但是这样生成的build目录还会残留VS的一些配置,后续在看看有什么办法可以给他去掉???(cmake使用MSVC构建应该是使用的Ninja。使用的是cl.exe)安装位置在:D:\software\Microsoft Visual Studio\2019\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja/ninja.exe

文章参考:【cmake】关于cmake构建系统Ninja_cmake ninja-CSDN博客

不过要注意:需要将ninja路径配置到环境变量里,不然会报错:

这将生成一个Ninja构建文件(build.ninja)并配置项目。然后输入ninja

但是这边好像有个坑,这样默认使用MinGW编译的。。。期待来个大佬给指点指定。

CMake 是一个跨平台的开源构建系统,用于管理软件构建过程。它能够生成标准的构建文件(如 Makefile 或者 Visual Studio 项目文件),并且支持多种编译器和操作系统。CMake 通过 `CMakeLists.txt` 文件来描述项目的构建结构,这使得项目可以轻松地在不同的平台上进行构建。 ### 基本概念 - **CMakeLists.txt**: 每个 CMake 项目都需要至少一个 `CMakeLists.txt` 文件,该文件定义了项目的源代码、目标文件以及依赖关系。 - **构建目录**: 推荐创建一个独立的构建目录(例如 `build`),与源代码分离,以便清理或重新构建。 - **配置步骤**: 使用 `cmake` 命令从 `CMakeLists.txt` 生成构建文件。 - **构建步骤**: 使用平台相关的构建工具(如 `make`)来编译项目。 ### 安装 CMake 确保你的系统上已经安装了 CMake。可以通过包管理器安装,或者从官方网站下载最新版本。对于 Linux 用户,通常可以使用如下命令安装: ```bash sudo apt-get install cmake ``` 对于 macOS 用户,可以使用 Homebrew: ```bash brew install cmake ``` Windows 用户可以从 CMake 官网下载安装程序。 ### 创建一个简单的 CMake 项目 假设你有一个简单的 C++ 项目,结构如下: ``` my_project/ ├── CMakeLists.txt └── src/ └── main.cpp ``` #### 编写 CMakeLists.txt 在项目根目录下创建 `CMakeLists.txt` 文件,并添加以下内容: ```cmake # 指定所需的最低版本 cmake_minimum_required(VERSION 3.10) # 定义项目名称 project(MyProject) # 添加可执行文件 add_executable(MyExecutable src/main.cpp) ``` #### 构建项目 进入项目根目录,创建并进入构建目录: ```bash mkdir build && cd build ``` 运行 CMake 配置和生成构建文件: ```bash cmake .. ``` 然后使用构建工具编译项目: ```bash make ``` 编译完成后,可以在 `build` 目录中找到生成的可执行文件。 ### 高级技巧 - **多目录项目**: 对于更复杂的项目,可能需要将源代码组织到多个子目录中。每个子目录都可以有其自己的 `CMakeLists.txt` 文件,使用 `add_subdirectory()` 来包含这些子目录。 - **自定义编译选项**: 可以通过 `option()` 命令在 CMake 中添加自定义的编译选项。 - **查找库**: CMake 提供了 `find_package()` 命令来查找外部库。 - **预处理宏**: 在 CMake 中可以设置预处理宏,用于条件编译。 - **安装规则**: 使用 `install()` 命令来定义安装规则,便于部署应用程序。 ### 示例:多目录项目 如果项目结构如下: ``` my_project/ ├── CMakeLists.txt ├── src/ │ ├── CMakeLists.txt │ └── main.cpp └── lib/ ├── CMakeLists.txt └── mylib.cpp ``` 主 `CMakeLists.txt` 应该包含: ```cmake cmake_minimum_required(VERSION 3.10) project(MyProject) # 添加子目录 add_subdirectory(src) add_subdirectory(lib) ``` 在 `src/CMakeLists.txt` 中: ```cmake # 添加可执行文件,并链接库 add_executable(MyExecutable main.cpp) target_link_libraries(MyExecutable PRIVATE MyLibrary) ``` 而在 `lib/CMakeLists.txt` 中: ```cmake # 创建库 add_library(MyLibrary mylib.cpp) ``` 这样,当构建时,CMake 将会正确地处理所有依赖关系。 ### 学习资源 为了进一步学习 CMake,你可以参考官方文档,或者在线教程,比如《从零开始详细介绍CMake》这样的入门教程,它涵盖了从基础概念到高级技巧的全方位指导[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

only-lucky

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值