CMake学习

server/2024/9/24 14:23:22/

Cmake

  • 工具链

    • 预处理器(宏替换)->编译器->汇编器(二进制文件.obj&&.0)->链接器->变成.exe
  • 单源文件可以直接命令生成.exe

    • 解决1:源文件多时要编写makefile,但编写makefile文件很麻烦
    • 解决2:使用cmake,跨平台,可以直接生成makefile
  • 命令行直接编译源文件

    • g++ *.cpp -o app
    • 会生成一个app.exe
    • ./app
  • 编写CMakelist.txt

    • # ======================================================================================
      # 指定cmake的最低版本
      cmake_minimum_required(VERSION 3.0.0)  
      # 指定工程名
      project(CALC) 
      # 生成可执行文件名app: add_executable(可执行程序名 源文件名称) 后面的源文件用空格or;
      # add_executable(app add.c div.c main.c mult.c sub.c) 
      # ======================================================================================
      # 设置变量值: set(变量名, 变量值) 后面的变量值用空格隔开  
      set(SRC_LIST add.c div.c main.c mult.c sub.c)
      # 取变量值
      add_executable(app ${SRC_LIST})
      # 设置c++版本为c++11
      set(CMAKE_CXX_STANDARD 11)
      # 设置app.exe的输出路径
      set(HOME /home/fyq/...)
      set(EXECUTABLE_OUTPUT_PATH ${HOME}/bin)
      # ======================================================================================
      # 搜索文件 
      # aux_source_directory(${PROJECT_SOURSE_DIR} SRC_LIST)
      # file(GLOB/GLOB_RECURSE SRC ${CMAKE_CURRENT_SOURSE_DIR}/*.cpp)
      # ======================================================================================
      
    • 执行cmake命令,cmake后面跟的目录是CMakelist.txt所在的目录,会生成一系列文件,一般是在build文件夹中执行,生成Makefile文件后执行make命令即可生成可执行文件

    • set命令

      • 设置变量值
        • set(SRC_LIST add.c div.c main.c mult.c sub.c):设置SRC_LIST的值为add.c ...
        • add_executable(app ${SRC_LIST}):取变量值用${}
      • 设置指定的c++版本: c++11c++14c++17默认是c++98
        • 方法一:g++ *.cpp -std=c++11 -o app
        • 方法二:在CMakelist.txt文件中指定 ,加入set(CMAKE_CXX_STANDARD 11)
      • 设置可执行文件的输出路径 建议使用绝对路径
        • set(HOME /home/fyq/...)
        • set(EXECUTABLE_OUTPUT PATH ${HOME}/bin)
    • set命令需要找到所有的文件,仍然很麻烦,因此有搜索文件命令

      • 方法一:aux_source_directory ${PROJECT_SOURSE_DIR}:CMakelist.txt所在目录路径
        • aux_source_directory(${PROJECT_SOURSE_DIR} SRC_LIST):找到源文件目录下的所有文件,并赋值给SRC_LIST
        • add_executable(app ${SRC_LIST})
      • 方法二:file命令 ${CMAKE_CURRENT_SOURSE_DIR}:CMakelist.txt所在目录路径
        • file(GLOB/GLOB_RECURSE SRC ${CMAKE_CURRENT_SOURSE_DIR}/*.cpp):递归搜索某目录文件搜索所有.cpp文件,将值赋给SRC变量
    • 指定头文件所在路径

      • include_directories(${CMAKE_CURRENT_SOURSE_DIR}/include)head.h/include目录下
    • 动态库和静态库

      • 注意:静态库会被加到生成文件中,因此应该在生成可执行文件即add_exectable()命令前运行,但是动态库不会被加,因此需要在生成可执行文件后执行,一般就是放在文件最末尾
      • 都由lib_xxx.xxx组成,第二个是xxx是后缀
        • 若是动态库 有可执行权限
          • windowslib_xxx.dll
          • linuxlib_xxx.so
        • 若是静态库 无可执行权限
          • windowslib_xxx.lib
          • linuxlib_xxx.a
      • 制作静态库:例如制作一个计算器,只需要add.c div.c ...不需要main.c
        • add_library(库名称 STATIC 源文件1 源文件2...)add_library(calc STATIC ${SRC})
      • 制作动态库
        • add_library(库名称 SHARED 源文件1 源文件2...):``add_library(calc SHARED ${SRC})`
      • 指定输出库的路径 设置宏${LIBRARY_OUTPUT_PATH}
        • set(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_SOURSE_DIR}/lib)
    • 有了静态库和动态库之后,之前的div.c add.c...就不需要了,只需要使用库文件就行

      • 链接静态库库文件
        • link_libraries(静态库名字1 名字2...)link_libraries(calc)
      • 对于自定义的库文件,还需要指定路径
        • link_directories(path)link_directories(${CMAKE_CURRENT_SOURSE_DIR}/lib)
      • 链接动态库文件 注意:链接动态库需要写在生成可执行文件之后(add_executable(…))
        • target_link_libraries(动态库名称)target_link_libraries(app calc) app是可执行文件,表示app要链接动态库,后面的calc是被链接的动态库名称
    • 日志

      • message(重要程度 消息):message(STATUS "message status") 默认重要
        • STATUS:非重要
        • WARNING:警告,继续执行
        • SEND_ERROR:继续执行,但是跳过所有生成步骤
        • FATAL_ERROR:cmake错误,终止所有
    • 变量操作

      • 字符串拼接:
        • list(APPEND 变量名 [子字符串])list(APPEND ${SRC} ${TEMP})TEMP的值追加到SRC
        • set(变量名 字符串1 字符串2 ..)set(tmp ${tmp1} ${tmp2})tmp1tmp2的内容拼接,放到tmp
      • 字符串删除:
        • list(REMOVE_ITEM 变量名 [子字符串])list(REMOVE_ITEM ${SRC} main.cpp)
      • list其他功能 list底层存储了很多的字符串,每个字符串通过;相隔
        • 获取长度:list(LENGTH 列表名字 输出变量)
        • 获取索引处值:list(GET 列表名字 索引位置)
          • 索引位置-1表示最后一个元素
        • 将列表中的元素连接成新字符串:list(JOIN 列表名字 指定连接字符串 输出变量)
        • 列表中是否存在指定元素:list(FINO 列表名字 搜索元素 输出变量)
          • 存在则返回索引,否则返回-1
        • 插入元素在指定位置:list(INSERT 列表名字 索引 插入元素1 插入元素2...)
        • 移除最后元素:list(POP_BACK 列表名字 存储弹出元素的变量:可省略)
        • 将指定索引删除:list(REMOVE_AT 列表名字 索引)
        • 删除重复元素:list(REMOVE_DUPLICATED 列表名字)
        • 列表反转:list(REVERSE 列表名字)
        • 列表排序:list(SORT 列表名字 COMPARE:... CASE:... ORDER:...)
          • COMPARE:指定排序方法
            • STRING:字母顺序,默认
            • FILE_BASENAME:若是一系列路径名,会使用basename排序
            • NATURAL:使用自然数顺序排序
          • CASE:是否大小写敏感
            • SENSITIVE:大小写敏感,默认
            • INSENSITIVE:大小写不敏感
          • ORDER:指定排序顺序
            • ASCENDING:升序排列,默认
            • DESCENDING:降序排序
    • 自定义宏 用来控制日志是否输出

      • add_definitions(-D宏名称)add_definitions(-DDEBUG) 定义了一个DEBUG宏
    • Cmake嵌套

      • 子节点可以使用父节点的变量值

      • $ tree
        .
        ├── build
        ├── calc
        │   ├── add.cpp
        │   ├── CMakeLists.txt
        │   ├── div.cpp
        │   ├── mult.cpp
        │   └── sub.cpp
        ├── CMakeLists.txt
        ├── include
        │   ├── calc.h
        │   └── sort.h
        ├── sort
        │   ├── CMakeLists.txt
        │   ├── insert.cpp
        │   └── select.cpp
        ├── test1
        │   ├── calc.cpp
        │   └── CMakeLists.txt
        └── test2├── CMakeLists.txt└── sort.cpp
        
      • 假如目录结构如上图所示,其中

        • include是头文件目录
        • calc对应加减乘除
        • sort对应两种排序
        • test1test2是计算器和排序的测试程序
      • 为了让test1test2能使用计算器和排序,因此需要将calcsort里的内容生成库文件,若源文件多,则生成动态库,否则生成静态库,因为生成静态库会将库文件放在输出的文件夹中

      • 添加子目录

        • add_subdirectory(子目录名)add_subdirectory(calc)
      • 示例

        • 根目录CMakelist.txt

          • # 最小版本
            cmake_minimum_required(VERSION 3.0)
            # 可执行文件名
            peoject(test)
            # 静态库输出路径
            set(LIBPATH ${CMAKE_CURRENT_SOURSE_DIR}/lib)
            # 头文件目录路径
            set(HEADPATH ${CMAKE_CURRENT_SOURSE_DIR}/lib)
            # 生成库文件名称
            set(CALCLIB calc)
            set(SORTLIB sort)
            # 可执行文件程序名
            set(APPNAME1 app1)
            set(APPNAME2 app2)# 给当前目录添加子节点
            add_subdirectory(calc)
            add_subdirectory(sort)
            add_subdirectory(test1)
            add_subdirectory(test2)
            
        • calc目录CMakelist.txt sort目录下的同理

          • # 最小版本
            cmake_minimum_required(VERSION 3.0)
            # 可执行文件名
            peoject(calc)
            # 搜索源文件 在./下搜索所有文件,放到SRC中
            aux_sourse_directory(./ SRC)
            # 添加头文件 因为calc用到了calc.h 
            include_directories(${HEADPATH}) # 子节点可以使用父节点的变量
            # 设置库文件输出位置	LIBRARY_OUTPUT_PATH是系统定义的宏
            set(LIBRARY_OUTPUT_PATH ${LIBPATH})
            # 生成静态库文件
            add_library(${CALCLIB} STATIC ${SRC})
            
        • test1目录CMakelist.txt test2目录同理

          • # 最小版本
            cmake_minimum_required(VERSION 3.0)
            # 可执行文件名
            peoject(test1)
            # 搜索文件
            aux_sourse_directory(./ SRC)
            # 添加头文件
            include_directories(${HEADPATH})
            # 指定静态库文件地址
            link_directories(${LIBPATH})
            # 链接静态库
            link_libraries(CALCLIB)
            # 设置可执行文件生成路径 EXECUTABLE_OUTPUT_PATH是系统定义的宏
            set(EXECUTABLE_OUTPUT_PATH ${EXECPATH})
            # 生成可执行文件
            add_executable(${APPNAME1} ${SRC})
            
    • 在静态库中链接静态库

      • 一样使用link_directorieslink_libraries
    • find_package():查找依赖包


http://www.ppmy.cn/server/110797.html

相关文章

OpenCV绘图函数(6)绘制椭圆函数ellipse()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 画出一个简单的或粗的椭圆弧或者填充一个椭圆扇形。 函数 cv::ellipse 使用更多的参数可以画出椭圆轮廓、填充的椭圆、椭圆弧或填充的椭圆扇形。…

Socket编程+操作系统入门小知识

Socket编程常用接口 socket NAME socket - create an endpoint for communication SYNOPSIS #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> int socket(int domain, int type, int protocol); domain&#x…

四个版本的双向链表(C++,C++ CLI, C#, Java)

原生C /******************************************************************************************* 文件名 &#xff1a; _List.h作者 &#xff1a; 李锋功能 &#xff1a; 链表手机 &#xff1a; 13828778863Email : ruizhilf139.com创建时间 &#xf…

[数据集][目标检测]电力场景输电线均压环歪斜检测数据集VOC+YOLO格式303张2类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;303 标注数量(xml文件个数)&#xff1a;303 标注数量(txt文件个数)&#xff1a;303 标注类别…

Java大文件下载方案(vue+饿了么):分片下载、断点续载!

前言 本篇文章是基于其他文章的基础上结合自己的理解写出来的,如果哪里有问题请指出! 详细教程 分片下载 1.什么是分片下载 分片下载是指将一个大的文件分成多个较小的部分&#xff08;分片或块&#xff09;&#xff0c;然后并行地从服务器下载这些部分到客户端的过程。 …

3.2 Browser -- useColorMode

3.2 Browser – useColorMode https://vueuse.org/core/useColorMode/ 作用 可以自动持久化的响应式颜色主题模式。 官方示例 import { useColorMode } from vueuse/coreconst mode useColorMode() // Ref<dark | light>默认情况下&#xff0c;它将使用usePreferre…

电子病历、开药发药、住院检查、会员管理,SaaS模式B/S架构的云医院管理系统源码,云计算技术的医疗信息化解决方案

云HIS系统&#xff0c;即云医院管理系统&#xff0c;是一种基于云计算技术的医疗信息化解决方案&#xff0c;它重新定义了传统的医院信息系统&#xff08;HIS&#xff09;&#xff0c;旨在实现医疗卫生信息化从局域网医院信息系统向广域网医疗卫生信息系统的转型。以下是云HIS系…

【功能自动化】使用HTMLTestRunner生成测试报告

配置环境&#xff1a; 部署webtours网站 准备数据 user.txt 操作步骤 要生成测试报告&#xff0c;可以使用HTMLTestRunner库。HTMLTestRunner是一个第三方库&#xff0c;需要先安装。 安装HTMLTestRunner使用以下命令&#xff1a; pip install HTMLTestRunner 使用HTMLTes…