• CMake基础


    CMake(Cross platform Make,在线帮助文档wikichs)是一个开源的跨平台自动化建构系统(目前仅支持C / C++ / Java语言),不依赖于某特定编译器,并可支持多层目录、多个应用程序与多个库。

    对于其他GNU Make ,QT的qmake ,微软的nmake等Make工具,如果要在不同平台上编译,就得为每一种标准写一次 Makefile,这将是一件让人抓狂的工作。

    CMake就是针对上面问题而设计的工具:它首先允许开发者编写一种平台无关的 CMakeLists.txt文件(注:名字大小写要完全一致)来定制整个编译流程,并不直接建构出最终的软件

    再根据目标用户的平台进一步生成所需的本地化Makefile(如:Unix的Makefile)或工程文件(如:Windows的Visual Studio 工程、MacOS的Xcode工程)。从而做到:Write once, run everywhere.

    在linux平台下使用CMake生成Makefile并编译的流程如下:

    ① 编写 CMake 配置文件 CMakeLists.txt 。
    ② 执行命令 cmake PATH 或者 ccmake PATH 生成 Makefile(注:ccmake 和 cmake 的区别在于前者提供了一个交互式的界面)。其中, PATH 是 CMakeLists.txt 所在的目录。
    ③ 使用 make 命令进行编译。

    linux平台默认就会安装CMake(没有装的话,通过yum install cmakeapt-get install cmake来安装)

    rpm包和deb包是Linux系统下最常见的两种安装包格式。
    rpm包用在RedHat系列(Redhat、Centos、Fedora等)的Linux系统上,使用yum来管理。
    deb包用于Debian系列(Debian、Ubuntu 等)的Linux系统上,使用apt-get来管理。

    MacOS平台可通过brew install cmake来安装。

    Windows平台可从官网下载最新版本进行安装。

    注:vs2019也内置了一份CMake:

    为了方便使用cmake,在windows可将cmake路径(E:\Program Files\CMake\bin)到PATH环境变量中。

    执行cmake.exe --version打印出cmake的版本 (如:cmake version 3.18.4),来确认cmake安装和环境是否配置成功。

    vscode插件CMake、CMakeTools

    CMake有如下主要功能:

    ① Colorization(着色)     

    ② Snippets & Completion Lists(自动完成)

    ③ Quick Help(快速帮助)

    CMakeTools有如下主要功能:

    ① Configure a project(配置一个项目)  注:使用CMake配置一个项目

    ② Build a project(编译一个项目) 注:CMake自身没有编译功能,它只是拉起相关编译器、链接器进行编译链接

    ② Debug a project(调试一个项目)  注:CMake自身没有调试功能,它只是拉起相关Debugger进行调试

    更多功能详见:github README

    CMakeTools相关设置见菜单“File” -- “Preferences” -- “Settings”面板中“Extensions” -- “CMake Tools”标签

    注1:User表示设置会保存在当前用户下,对当前用户下所有CMake都起作用

    注2:Workspace表示设置会保存在当前工作空间下,仅对当前工作空间CMake起作用

    项目示例

    CMakeLists.txt内容如下

    cmake_minimum_required(VERSION 3.10)
    
    project(Test1)
    
    add_executable(Test1 main.cpp)

    main.cpp内容如下:

    #include <iostream>
    
    int main()
    {
        std::cout << "Hello World!" << std::endl;
        return 0;
    }

    配置项目(Configure a project)

    点击vscode菜单View -- Command Palette...,输入:>CMake: Configure,在弹出的下拉框中选择对应的编译器(如下)

    注:CMakeTools重新Configure a project时,需要将当前工作目录改名(不换目录名的话,不会弹出上图编译器的选择下拉列表),然后执行CMake: Delete Cache and Reconfigure

    build目录中会生成vs2019相关工程

    也可通过命令行来Configure项目

    "E:\Program Files\CMake\bin\cmake.EXE" --no-warn-unused-cli -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -Sf:/cmakeTest/Test1 -Bf:/cmakeTest/Test1/build -G "Visual Studio 16 2019" -T host=x64 -A x64

    编译项目(Build a project)

    点击vscode菜单View -- Command Palette...,输入:>CMake: Build

    这个过程中cmake会拉起MSBuild.exe来编译ALL_BUILD.vcxproj项目

    注1:执行编译项目时,若之前未配置项目,会先进行配置,然后再编译

    注2:F7也可以编译项目

    也可通过命令行来Build项目

    "E:\Program Files\CMake\bin\cmake.EXE" --build f:/cmakeTest/Test1/build --config Debug --target ALL_BUILD -j 18 --

    build目录中会生成Test1.exe可执行文件

    调试项目(Debug a project)

    ① 双击Test1.sln,用vs2019打开该解决方案文件

    ② 将Test1项目设置为缺省,放置断点,按F5进行调试 

    手动下载、管理和引用第三方库

    ① 下载各个第三方库

    ② 逐个用cmake -S . -B build编译第三方库

    ③ 指定各个第三方库所在路径

    使用vcpkg下载、管理和引用第三方库

    vcpkggithub)是一个开源跨平台(支持Windows、 Linux 和 MacOS)的管理C / C++ 库的工具。

    安装和配置vcpkg

    ① 克隆下载vcpkg的工程

    git clone https://github.com/microsoft/vcpkg

    ② 执行工程中的bootstrap-vcpkg.bat脚本,下载vcpkg.exe

    ③ 创建环境变量VCPKG_ROOT,并设置为G:\svn\vcpkg

    ④ 将G:\svn\vcpkg添加到PATH环境变量中   注:方便在任何目录中使用vcpkg.exe

    ⑤  配置Using cached binary package第三方库的位置,更多信息详见:Binary Caching

         创建环境变量VCPKG_DEFAULT_BINARY_CACHE,并设置为F:\vcpkg\ThirdParty,使得vcpkg安装的第三方库存放到F:\vcpkg\ThirdParty目录中

         若不设置该环境变量时,vcpkg安装的第三方库会存放在C:\Users\<用户名>\AppData\Local\vcpkg\archives目录中

    vcpkg命令用法

    vcpkg --help  // 查看vcpkg帮助

    vcpkg install glfw3  // 编译并安装x86版本的glfw3库   注:缺省为x86

    vcpkg install glfw3:x64-windows  // 编译并安装x64版本的glfw3库

    vcpkg install glfw3 --triplet=x64-windows  // 功能同上

    vcpkg remove glfw3:x64-windows  // 删除x64版本的glfw3库

    vcpkg search glfw  // 查找glfw相关库的信息

    glfw3                    3.3.8            GLFW is a free, Open Source, multi-platform library for OpenGL, OpenGL ES ...
    imgui[glfw-binding]                       Make available GLFW binding
    libigl[glfw]                              Build with glfw
    magnum[glfwapplication]                   GlfwApplication library
    opensubdiv[glfw]                          Path to glfw
    The result may be outdated. Run `git pull` to get the latest results.
    If your port is not listed, please open an issue at and/or consider making a pull request.    -  https://github.com/Microsoft/vcpkg/issues

    在Visual Studio 中使用vcpkg管理的第三方库

    ① 执行命令:vcpkg integrate install

    ② 在此之后,在VS的项目中,所有已安装的库均可直接使用 #include头文件且无需额外配置

    在cmake中使用vcpkg管理的第三方库

    ① 在CMakeLists.txt文件中使用find_package来使用 vcpkg 中已安装的库

    find_package(glfw3 REQUIRED)

    ② 带上CMAKE_TOOLCHAIN_FILE来配置项目:cmake -B [build directory] -S . "-DCMAKE_TOOLCHAIN_FILE=G:/svn/vcpkg/scripts/buildsystems/vcpkg.cmake"

        在vscode中,可在workspace的settings.json文件cmake.configureSettings标签下,配置"CMAKE_TOOLCHAIN_FILE": "G:/svn/vcpkg/scripts/buildsystems/vcpkg.cmake"

        

    ③ 编译项目:cmake --build [build directory]

    在cmake中使用vcpkg来引用指定版本的第三方库

    vcpkg提供了versioning特性并默认开启,来解决指定版本的第三方库的引用。详见:Getting started with versioningVersioning

    ① 通过vcpkg.json来配置各个第三方库的版本信息

    {
        "name": "versions-test",
        "version": "1.0.0",
        "dependencies": [
          {
            "name": "zlib",
            "version>=": "1.2.11#12"
          },
          {
            "name": "glfw3",
            "version>=": "3.3.6"
          },
          "fmt"
        ],
        "builtin-baseline": "99dc49dae7e170c3be63dd097230007f3bb73c4f",
        "overrides": [
          {
              "name": "glfw3",
              "version": "3.3.3"
          }
        ]
    }

    vcpkg.json中配置了依赖的3个第三方库:zlib、glfw3、fmt。

    zlib的版本号1.2.11#12通过#分割,是由version和port-version两部分组成,version(1.2.11)是zlib的实际的版本号,port-version(12) 是这个版本在vcpkg中的补丁版本。两者组合可以获得该库在vcpkg中的具体版本。

    glfw3的version要求>=3.3.6,由于overrides中指定其版本号为3.3.3,因此glfw3最终使用3.3.3的版本。

    fmt没有设置版本信息,会使用builtin-baseline指定的版本,即:versions/baseline.json(commit id为99dc49dae7e170c3be63dd097230007f3bb73c4f)文件中配置的版本7.13

    git show 99dc49dae7e170c3be63dd097230007f3bb73c4f:versions/baseline.json // 查看G:/svn/vcpkg/versions/baseline.json的commit id为99dc49dae7e170c3be63dd097230007f3bb73c4f版本,其内容如下

    。。。 。。。
    
     "fmt": {
          "baseline": "7.1.3",
          "port-version": 0
        },
    
    。。。 。。。
    
    "glfw3": {
          "baseline": "3.3.2",
          "port-version": 1
        },
        
    。。。 。。。
    
    "zlib": {
          "baseline": "1.2.11",
          "port-version": 9
        },
    。。。 。。。

    注1:第三方库版本的确定顺序是overrides --》 dependencies version>=  --》builtin-baseline

    注2:dependencies version>= 主要用于表示需要使用的最低版本(保持最大程度的兼容)

    注3:如果在配置项目时,没有执行vcpkg install并报如下错误:CMake Error at E:/Program Files/CMake/share/cmake-3.18/Modules/FindPackageHandleStandardArgs.cmake

             可通过执行CMake: Delete Cache and Reconfigure来解决。

    CMakeLists.txt内容如下:

    cmake_minimum_required(VERSION 3.10)
    
    project(Test1)
    
    add_executable(Test1 main.cpp)
    
    find_package(ZLIB REQUIRED)
    find_package(fmt CONFIG REQUIRED)
    find_package(glfw3 CONFIG REQUIRED)
    target_link_libraries(Test1 PRIVATE ZLIB::ZLIB fmt::fmt glfw)

    main.cpp内容如下:

    #include <iostream>
    #include <fmt/core.h>
    #include <zlib.h>
    #include <GLFW/glfw3.h>
    
    int main()
    {        
        std::cout << "fmt version is " << FMT_VERSION << std::endl;
        std::cout << "zlib version is " << ZLIB_VERSION << std::endl;
        std::cout << "glfw3 version is " << GLFW_VERSION_MAJOR << "." << GLFW_VERSION_MINOR << "." << GLFW_VERSION_REVISION << std::endl;
        return 0;
    }

    第三方库编译出来的文件

    运行Test1.exe输出的结果

    fmt version is 70103
    zlib version is 1.2.11
    glfw3 version is 3.3.3

    参考

    软件构建: CMake 快速入门

    CMake 入门实战

    VCPKG 特性 - Versioning

  • 相关阅读:
    深入理解Nginx及使用Nginx实现负载均衡
    Linux内存管理之伙伴系统之伙伴系统概述
    TCP 协议如何解决粘包、半包问题
    Linux CPU亲缘性详解
    单实例
    关联容器和无序关联容器的区别
    基于范围的for循环
    vector讲一个容器的内容拷贝到另一个容器,容器的区间删除
    win32窗口添加按钮及按钮消息相应,动态显示时间
    判断是不是纯数字字符串
  • 原文地址:https://www.cnblogs.com/kekec/p/14223504.html
Copyright © 2020-2023  润新知