当前位置: 首页 > news >正文

CMake入门

1.什么是CMake

        Makefile想必大家都不陌生吧,它能够解决我们的自动化编译问题,大多是IDE软件都集成了make,譬如 Visual C++的 nmake、linux 下的 GNU make、Qt 的 qmake 等等。

 不同的IDE所集成的make工具所遵循的规范和标准都不同,也就导致其语法、格式不同,也就不能很好的跨平台编译,会再次使得工作繁琐起来

        那么cmake为了解决这个问题而诞生了,其允许开发者指定整个工程的编译流程,在根据编译平台,生成本地化的Makefile和工程文件,最后用户只需make编译即可

        简而言之,可以把cmake看成一款自动生成 Makefile的工具,所以编译流程就变成了:cmake—>make–>用户代码–>可执行文件

2.CMakeflie的安装和版本的查看

首先我们需要安装我们的CMake

sudo yum install cmake

然后我们可以通过

cmake -version

 来查看自己的cmake的版本

3.几个简单示例 

事实上,cmake的用法特别简单

  1. 编写CMakeLists.txt
  2. 执行命令cmake .
  3. 执行命令make
  4. 运行执行程序

看几个例子来 

3.1.编译一个.cc文件

首先让我们从最简单的代码入手,先来体验下cmake是如何操作的。编写main.cc,如下,

#include <stdio.h>
 
int main(void)
{
	printf("Hello World\n");
 
	return 0;
}

    然后在main.cc相同目录下编写CMakeLists.txt,内容如下,

    cmake_minimum_required (VERSION 2.8)
     
    project (demo)
     
    add_executable(main main.cc)
    • 第一行意思是表示cmake的最低版本要求是2.8,我们安装的是3.20.2;
    • 第二行是表示本工程信息,也就是工程名叫demo;
    • 第三行比较关键,表示最终要生成的elf文件的名字叫main,使用的源文件是main.cc

    在终端下切到main.cc所在的目录下,然后输入以下命令运行下面这个命令

    cmake .

    执行之后,就会有下面这样子的情况发生 

    我们再看看当前目录下面 

    我们发现当前目录下面有Makefile了,我们打开看看

    好像不认识啊 ,这个我们不管,我们退出来make一下 

    完美啊!

    3.2.编译一个.hpp文件和一个.cc文件

    接下来我将编译一个.hpp文件和一个.cc文件

    method.hpp

    #pragma once
    #include<iostream>
     
    void Printf()
    {
        std::cout<<"hello world!"<<std::endl;
    }

    main.cc 

    #include"method.hpp"
     
    int main()
    {
        Printf();
    }

     CMakeLists.txt

    cmake_minimum_required(VERSION 2.8)  
      
    project(demo)  
      
    # 添加可执行文件,只需要列出源文件,头文件不需要列出  
    add_executable(main main.cc)  
      
    #  method.hpp 是 main.cc 依赖的头文件,确保它位于正确的路径下  
    # CMake 会自动处理包含路径(如果设置了正确的包含目录)  
    # 如果需要,可以使用 include_directories 来指定头文件搜索路径  
    # include_directories(path/to/headers)  
    # 但头文件和源文件在同一目录下,通常不需要这样做

     我们执行

    cmake .

    完美!

     3.3.编译一个.hpp文件和两个.cc文件

    接下来进入稍微复杂的例子:这次我们决定编译一个.h文件和两个.cc文件

    method.hpp

    #pragma once
    
    #include<iostream>
    
    
    void Printf();

    method.cc 

    #include"method.hpp"
     
    void Printf()
    {
        std::cout<<"hello world"<<std::endl;
    }

     main.cc

    #include"method.hpp"
     
    int main()
    {
        Printf();
    }

    我们现在就来编写CMakeLists.txt

    CMakeLists.txt

    cmake_minimum_required (VERSION 2.8)
     
    project (demo)
     
    add_executable(main main.cc method.cc)

     

    注意我这里只是在main.cc后面加路method.cc 

    我们使用一下

    cmake .

     

    完美啊!! 

    3.4.编译两个.hpp文件和一个.cc文件

    接下来我们将使用method.hpp,way.hpp,main.cc文件来编译

    way.hpp 

    #pragma once
    #include<iostream>
    void Printf1()
    {
        std::cout<<"Printf1"<<std::endl;
    }

    method.hpp  

    #pragma once
    #include<iostream>
    void Printf2()
    {
        std::cout<<"Printf2"<<std::endl;
    }

    main.cc

    #include"way.hpp"
    #include"method.hpp"
     
    int main()
    {
        Printf1();
        Printf2();
    }

      CMakeLists.txt

    cmake_minimum_required (VERSION 2.8)
     
    project (demo)
     
    add_executable(main main.cc)

     

    注意:因为我这里只有一个源文件,所以我们写一个main.cc就好

    我们执行

    cmake .

    完美! 

    4.CMakeLists.txt

            编写CMakeLists.txt最常用的功能就是调用其他的.h头文件和.so/.a库文件,将.cpp/.c/.cc文件编译成可执行文件或者新的库文件。

    4.1.CMakeLists.txt常用的几条指令

    CMakeLists.txt 文件使用一系列的 CMake 指令来描述构建过程。常见的指令包括:

    1、指定 CMake 的最低版本要求:

    cmake_minimum_required(VERSION <version>)

    例如:

    cmake_minimum_required(VERSION 3.10)

    2、定义项目的名称和使用的编程语言:

    project(<project_name> [<language>...])

    例如:

    project(MyProject CXX)

     

    3、指定要生成的可执行文件和其源文件:

    add_executable(<target> <source_files>...)

    例如:

    add_executable(MyExecutable main.cpp other_file.cpp)

    4、创建一个库(静态库或动态库)及其源文件:

    add_library(<target> <source_files>...)

    例如:

    add_library(MyLibrary STATIC library.cpp)

    5、链接目标文件与其他库:

    target_link_libraries(<target> <libraries>...)

    例如:

    target_link_libraries(MyExecutable MyLibrary)

    6、添加头文件搜索路径:

    include_directories(<dirs>...)

    例如:

    include_directories(${PROJECT_SOURCE_DIR}/include)

    7、设置变量的值:

    set(<variable> <value>...)

    例如:

    set(CMAKE_CXX_STANDARD 11)

    8、设置目标属性:

    target_include_directories(TARGET target_name
                              [BEFORE | AFTER]
                              [SYSTEM] [PUBLIC | PRIVATE | INTERFACE]
                              [items1...])

    例如:

    target_include_directories(MyExecutable PRIVATE ${PROJECT_SOURCE_DIR}/include)

    9、安装规则:

    install(TARGETS target1 [target2 ...]
            [RUNTIME DESTINATION dir]
            [LIBRARY DESTINATION dir]
            [ARCHIVE DESTINATION dir]
            [INCLUDES DESTINATION [dir ...]]
            [PRIVATE_HEADER DESTINATION dir]
            [PUBLIC_HEADER DESTINATION dir])

    例如:

    install(TARGETS MyExecutable RUNTIME DESTINATION bin)

    10、条件语句 (if, elseif, else, endif 命令)

    if(expression)
      # Commands
    elseif(expression)
      # Commands
    else()
      # Commands
    endif()

    例如:

    if(CMAKE_BUILD_TYPE STREQUAL "Debug")
      message("Debug build")
    endif()

    11、自定义命令 (add_custom_command 命令):

    add_custom_command(
       TARGET target
       PRE_BUILD | PRE_LINK | POST_BUILD
       COMMAND command1 [ARGS] [WORKING_DIRECTORY dir]
       [COMMAND command2 [ARGS]]
       [DEPENDS [depend1 [depend2 ...]]]
       [COMMENT comment]
       [VERBATIM]
    )

    例如:

    add_custom_command(
       TARGET MyExecutable POST_BUILD
       COMMAND ${CMAKE_COMMAND} -E echo "Build completed."
    )

    实例

    一个简单的 CMakeLists.txt 文件示例:

    cmake_minimum_required(VERSION 3.10)
    project(MyProject CXX)
     
    # 添加源文件
    add_executable(MyExecutable main.cpp)
     
    # 设置 C++ 标准
    set(CMAKE_CXX_STANDARD 11)

    4.2.变量和缓存

    CMake 使用变量来存储和传递信息,这些变量可以在 CMakeLists.txt 文件中定义和使用。

    变量可以分为普通变量和缓存变量。

    4.2.1.变量定义与使用

    定义变量:

    set(MY_VAR "Hello World")

    使用变量:

    message(STATUS "Variable MY_VAR is ${MY_VAR}")
    4.2.2.缓存变量

    缓存变量存储在 CMake 的缓存文件中,用户可以在 CMake 配置时修改这些值。缓存变量通常用于用户输入的设置,例如编译选项和路径。

    定义缓存变量:

    set(MY_CACHE_VAR "DefaultValue" CACHE STRING "A cache variable")

    使用缓存变量:

    message(STATUS "Cache variable MY_CACHE_VAR is ${MY_CACHE_VAR}")

     

    4.3.查找库和包

    CMake 可以通过 find_package() 指令自动检测和配置外部库和包。

    常用于查找系统安装的库或第三方库。

    4.3.1.find_package() 指令

    基本用法:

    find_package(Boost REQUIRED)

    指定版本:

    使用查找到的库:

    target_link_libraries(MyExecutable Boost::Boost)

    设置包含目录和链接目录:

    include_directories(${Boost_INCLUDE_DIRS})
    link_directories(${Boost_LIBRARY_DIRS})
    4.3.2.使用第三方库

    假设你想在项目中使用 Boost 库,CMakeLists.txt 文件可能如下所示:

    实例

    cmake_minimum_required(VERSION 3.10)
    project(MyProject CXX)
     
    # 查找 Boost 库
    find_package(Boost REQUIRED)
     
    # 添加源文件
    add_executable(MyExecutable main.cpp)
     
    # 链接 Boost 库
    target_link_libraries(MyExecutable Boost::Boost)

    通过上述内容,用户可以了解 CMakeLists.txt 文件的基本结构和常用指令,掌握如何定义和使用变量,查找和配置外部库,从而能够有效地使用 CMake 管理项目构建过程。

    相关文章:

  1. HDFS Java 客户端 API
  2. QML MouseArea 鼠标事件详解
  3. SQLMesh 系列教程8- 详解 seed 模型
  4. 每日一题——验证IP地址
  5. Docker教程(喂饭级!)
  6. 数字化电子(不动产经营租赁服务)发票版式文件说明
  7. 孜然单授权系统V2.0PHP授权系统
  8. List 接口中的 sort 和 forEach 方法
  9. Linux-GlusterFS进阶分布式卷
  10. python 虚拟机的使用方式
  11. 实验-安装Proteus
  12. 大模型监督微调(SFT)技术解析
  13. Open-WebUI前后端分离部署并基于DeepSeek实现智能问答
  14. 虚拟机从零实现机器人控制
  15. 安全面试2
  16. 被裁20240927 --- WSL-Ubuntu20.04安装cuda、cuDNN、tensorRT
  17. PHP post 数据丢失问题
  18. .NET MVC实现电影票管理
  19. 【NLP 31、预训练模型的发展过程】
  20. 游戏引擎学习第118天
  21. 母婴护理服务网站模板/电商网站建设公司哪家好
  22. 网站开发会什么/公司网站怎么注册
  23. 凤阳县建设局网站/谷歌seo是指什么意思
  24. 海淀区社区建设网站/网站建设详细方案模板
  25. 关于做公司官方网站域名申请/线上宣传推广方式
  26. 网站切换/常州谷歌推广