[C++][CMake][生成可执行文件][上]详细讲解

news/2024/7/8 1:47:58 标签: c++, 开发语言, make, makefile, CMake, 新手向, 详细讲解

目录

  • 0.准备工作
  • 1.添加CMakeLists.txt文件
  • 2.执行cmake命令
  • 3.变量定义
  • 4.指定使用的C++标准
  • 5.指定输出路径


0.准备工作

  • add.c
    #include <stdio.h>
    #include "head.h"
    
    int add(int a, int b)
    {
        return a+b;
    }
    
  • sub.c
    #include <stdio.h>
    #include "head.h"
    
    int subtract(int a, int b)
    {
        return a-b;
    }
    
  • mult.c
    #include <stdio.h>
    #include "head.h"
    
    int multiply(int a, int b)
    {
        return a*b;
    }
    
  • div.c
    #include <stdio.h>
    #include "head.h"
    
    double divide(int a, int b)
    {
        return (double)a/b;
    }
    
  • head.h
    // head.h
    #ifndef _HEAD_H
    #define _HEAD_H
    
    int add(int a, int b);
    int subtract(int a, int b);
    int multiply(int a, int b);
    double divide(int a, int b);
    
    #endif
    
  • main.c
    #include <stdio.h>
    #include "head.h"
    
    int main()
    {
        int a = 20;
        int b = 12;
        printf("a = %d, b = %d\n", a, b);
        printf("a + b = %d\n", add(a, b));
        printf("a - b = %d\n", subtract(a, b));
        printf("a * b = %d\n", multiply(a, b));
        printf("a / b = %f\n", divide(a, b));
        return 0;
    }
    

CMakeListstxt_77">1.添加CMakeLists.txt文件

  • 在上述源文件所在目录下添加一个新文件CMakeLists.txt
    make">cmake_minimum_required(VERSION 3.0)  
    project(CALC)  
    add_executable(app add.c div.c main.c mult.c sub.c)
    
  • cmake_minimum_require:指定使用的CMake最低版本
    • 可选,非必须,如果不加可能会有警告
  • project:定义工程名称
    • 并可指定工程的版本、工程描述、web主页地址、支持的语言(默认情况支持所有语言)
    • 如果不需要这些都是可以忽略的,只需要指定出工程名字即可
      make"># PROJECT 指令的语法是:  
      project(<PROJECT-NAME> [<language-name>...])  
      project(<PROJECT-NAME>  
             [VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]  
             [DESCRIPTION <project-description-string>]  
             [HOMEPAGE_URL <url-string>]  
             [LANGUAGES <language-name>...])
      
  • add_excutable:定义工程会生成一个可执行程序
    • 这里的可执行程序名和project中的项目名没有任何关系
      make">add_executable(可执行程序名 源文件名称)
      
    • 源文件名可以是一个,也可以是多个,如有多个可以用空格或;分隔
      make"># 样式1  
      add_executable(app add.c div.c main.c mult.c sub.c)  
      # 样式2  
      add_executable(app add.c;div.c;main.c;mult.c;sub.c)
      

make_113">2.执行cmake命令

  • CMakeLists.txt文件编辑好之后,就可以执行 cmake命令了
  • 语法cmake CMakeLists.txt文件所在路径
    • 在执行cmake命令之后,CMakeLists.txt中的命令就会被执行,所以一定要注意给cmake 命令指定路径的时候一定不能出错
    • 此时,对应目录下会生成一个makefile文件,此时再执行make命令,就可以对项目进行构建得到所需要的程序了
      .
      ├── CMakeCache.txt
      ├── CMakeFiles
      ├── Makefile
      └── cmake_install.cmake
      
  • 注意
    • 如果在CMakeLists.txt文件所在目录执行了cmake命令之后就会生成一些目录和文件(包括makefile文件)
    • 如果再基于makefile执行make命令,程序在编译过程中还会生成一些中间文件和一个可执行文件,这样会导致整个项目目录看起来很混乱,不太容易管理和维护
    • 此时可以把生成的这些与项目源码无关的文件统一放到一个对应的目录里边
      • 比如:将这个目录命名为build

3.变量定义

  • 在上面的例子中一共提供了5个源文件,假设这五个源文件需要反复被使用,每次都直接将它们的名字写出来确实是很麻烦,此时就需要定义一个变量,将文件名对应的字符串存储起来
  • CMake定义变量需要使用set
  • 语法[]中的参数为可选项,如不需要可以不写
    make">SET(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])
    
    # 方式1: 各个源文件之间使用空格间隔
    set(SRC_LIST add.c  div.c   main.c  mult.c  sub.c)
    
    # 方式2: 各个源文件之间使用;间隔
    set(SRC_LIST add.c;div.c;main.c;mult.c;sub.c)
    
    add_executable(app  ${SRC_LIST})
    

4.指定使用的C++标准

  • 在编写C++程序的时候,可能会用到C++11、C++14、C++17、C++20等新特性,那么就需要在编译的时候在编译命令中制定出要使用哪个标准
    g++ *.cpp -std=c++11 -o app
    
  • CMake中想要指定C++标准有两种方式
    • CMakeLists.txt中通过set命令指定
      make">set(CMAKE_CXX_STANDARD 11)
      
    • 在执行cmake命令的时候指定出这个宏的值
      cmake CMakeLists.txt文件路径 -DCMAKE_CXX_STANDARD=11
      

5.指定输出路径

  • CMake指定可执行程序输出的路径,也对应一个宏,叫做EXECUTABLE_OUTPUT_PATH,它的值还是通过set命令进行设置
    make">set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
    
  • 如果指定的目录不存在,会自动生成,无需自己手动创建
  • 注意
    • 由于可执行程序是基于cmake命令生成的makefile文件然后再执行make命令得到的
    • 如果此处指定可执行程序生成路径的时候使用的是相对路径./xxx/xxx那么此处的./对应的就是makefile文件所在的那个目录
  • PROJECT_SOURCE_DIR宏对应的值是在使用cmake命令时,后面紧跟的目录,一般是工程的根目录

http://www.niftyadmin.cn/n/5535976.html

相关文章

3-1 激活函数和神经网络思想

3-1 激活函数和神经网络思想 主目录点这里

Ubuntu / Openwrt使用lua发送http和https请求

Ubuntu / Openwrt使用lua发送http和https请求 1、Ubuntu配置以支持lua发送http和https请求1.1、配置apt镜像源1.2、安装相关lua关联包 2、Openwrt配置menuconfig支持lua发送http和https请求2.1、配置menuconfig 3、Ubuntu / Openwrt 使用lua发送http和https请求3.1、测试发送ht…

使用Java实现魔兽争霸3冰封王座联网

作者&#xff1a;cloudy491 顺便吆喝一声&#xff0c;如果你计算机、软件工程、电子等相关专业本科及以上学历&#xff0c;欢迎来共事。前端/后端/测试等均可投→技术大厂机会。 背景 自己实现搭建网络&#xff0c;在非同一个局域网下也可以玩魔兽争霸3冰封王座。一般我们是通…

C#——Path类详情

Path类 在C#中&#xff0c;文件和目录的操作是编程中常见的需求&#xff0c;而.NET Framework为我们提供了一个名为Path的类&#xff0c;用于进行文件的路径操作。 Path常用方法 相对路径转为绝对路径GetFullPath(string relativePath) string relativePath "..\\exam…

C++指针内存分配与释放

文章目录 指针分配与释放 &#xff1a;C new/delete VS C malloc/freeC new/deleteC malloc/free 指针销毁智能指针 指针分配与释放 &#xff1a;C new/delete VS C malloc/free new&#xff1a;分配内存、调用类的构造函数。delete&#xff1a;调用类的析构函数和释放内存&am…

xml_woarchive undefined symbol

最近在linux中编译一个自己写的老代码。是个C动态库。可以编译成功&#xff0c;但直到运行的时候才报 boost xml_woarchive undefined symbol. 解决的方法是在编译时要加上 wserialization 库。 注意&#xff0c;这个库有含 w 和不含 w 两个。在我这里需要使用含 w 的。 如果…

Rethinking Federated Learning with Domain Shift: A Prototype View

CVPR2023,针对分布式数据来自不同的域时,私有模型在其他域上表现出退化性能(具有域转移)的问题。提出用于域转移下联邦学习的联邦原型学习(FPL)。核心思想是构建集群原型和无偏原型,提供富有成效的领域知识和公平的收敛目标。将样本嵌入拉近到属于相同语义的集群原型,而…

8人团队历时半年打造开源版GPT-4o,零延迟演示引爆全网!人人可免费使用!

目录 01 Moshi 02 背后技术揭秘 GPT-4o可能要等到今年秋季才会公开。 然而&#xff0c;由法国8人团队开发的原生多模态Moshi&#xff0c;已经达到了接近GPT-4o的水平&#xff0c;现场演示几乎没有延迟&#xff0c;吸引了大量AI专家的关注。 令人惊讶的是&#xff0c;开源版的…