[CMake翻译]如何用CMake和VCPKG管理依赖关系。

3,921 阅读4分钟

原文地址:thatonegamedev.com/cpp/how-to-…

原文作者:thatonegamedev.com/

发布时间:2021-01-13

多年来,管理C++的依赖关系一直相当困难。C++是一门古老的语言,没有一些现代语言所拥有的概念,比如包管理器。包管理器通常会为你下载一些已经实现了你想要的功能的外部代码。比如在创建游戏的时候,raylib就是一个很好的库,它增加了很多编码功能,你就不用担心,直接使用就可以了。

在继续之前

为了完全理解本文的内容,你应该知道。

VCPKG

在为C++做包管理时,我选择的是VCPKG,它是微软创建的一个开源工具。它在直接用于Visual C++开发时(不使用CMake),可以很好地集成,也同样可以轻松地集成到CMake项目中。vcpkg工具会下载C++代码并将其编译成库,当我们构建项目时,会注意将需要的文件复制到我们的终端目录。听起来很神奇,那么让我们开始吧

安装VCPKG

要开始,你可以从它的github仓库下载vcpkg,这里github.com/microsoft/v… 。然后把它解压到一个名为 "vcpkg "的文件夹中,这样我们就会产生以下结构。

root
├── vcpkg/
│ └── ...extracted files...
├── src/
│ └── main.cpp
└── CMakeLists.txt

按照vcpkg github仓库中的说明,我们需要从项目的根部执行这个命令。

./vcpkg/bootstrap-vcpkg.bat

这将为我们安装所有需要的东西,以便在当前项目上开始为C++做包管理。

安装一个包

我将以raylib项目为例。要安装一个用于 cmake 的库,你需要从项目的根目录下运行以下命令。

./vcpkg/vcpkg.exe install raylib:x64-windows。

这将指示vcpkg搜索raylib并下载它。它还会设置使用x64处理器来编译它,并为windows编译。编译后的包将被放入".\vcpkg\installed\x64-window "中,并被分割到相关的目录中,用于包含、lib和其他文件。

在你的C/C++代码中使用软件包

为了能够在我们的C++代码中链接和使用raylib包,我们需要在CMakeLists.txt文件中添加以下几行。

# ...set this right below the cmake_minimum_required
set(CMAKE_TOOLCHAIN_FILE ./vcpkg/scripts/buildsystems/vcpkg.cmake)

# ...somewhere after the call to project

include_directories(./vcpkg/installed/x64-windows/include)
link_directories(./vcpkg/installed/x64-windows/lib)

# ...and after our target Main

target_link_libraries(Main PRIVATE raylib.lib)

我们还需要用VCPKG工具链生成cmake。要做到这一点,当执行 cmake 生成时,我们将通过添加以下标志来改变它。

cmake -B build -S .DDCMAKE_TOOLCHAIN_FILE=. -DCMAKE_TOOLCHAIN_FILE=./vcpkg/scripts/buildsystems/vcpkg.cmake

然后我从raylib网站上取了第一个例子,并把它放到Main.cpp文件中。你也可以在这个链接上玩玩其他所有的例子www.raylib.com/examples.ht…

/*******************************************************************************************
*
*   raylib [core] example - Basic window
*
*   Welcome to raylib!
*
*   To test examples in Notepad++, provided with default raylib installer package, 
*   just press F6 and run [raylib_compile_execute] script, it will compile and execute.
*   Note that compiled executable is placed in the same folder as .c file
*
*   You can find all basic examples on [C:\raylib\raylib\examples] directory and
*   raylib official webpage: [www.raylib.com]
*
*   Enjoy using raylib. :)
*
*   This example has been created using raylib 1.0 (www.raylib.com)
*   raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
*   Copyright (c) 2013-2020 Ramon Santamaria (@raysan5)
*
********************************************************************************************/

#include "raylib.h"

int main(void)
{
    // Initialization
    //--------------------------------------------------------------------------------------
    const int screenWidth = 800;
    const int screenHeight = 450;

    InitWindow(screenWidth, screenHeight, "raylib [core] example - basic window");

    SetTargetFPS(60);               // Set our game to run at 60 frames-per-second
    //--------------------------------------------------------------------------------------

    // Main game loop
    while (!WindowShouldClose())    // Detect window close button or ESC key
    {
        // Update
        //----------------------------------------------------------------------------------
        // TODO: Update your variables here
        //----------------------------------------------------------------------------------

        // Draw
        //----------------------------------------------------------------------------------
        BeginDrawing();

            ClearBackground(RAYWHITE);

            DrawText("Congrats! You created your first window!", 190, 200, 20, LIGHTGRAY);

        EndDrawing();
        //----------------------------------------------------------------------------------
    }

    // De-Initialization
    //--------------------------------------------------------------------------------------
    CloseWindow();        // Close window and OpenGL context
    //--------------------------------------------------------------------------------------

    return 0;
}

然后我们就像正常的构建和运行一样。vcpkg工具链将负责复制输出目录中的任何依赖文件,如.dll文件。

跨平台解决方案

一个更跨平台的解决方案是使用vcpkg工具链提供的find_package工具。要做到这一点,你需要在 CMakeLists.txt 文件中做如下修改。

# Remove these lines of code
#include_directories(./vcpkg/installed/x64-windows/include)
#link_directories(./vcpkg/installed/x64-windows/lib)
# ... so that we can replace them with:

find_package(raylib CONFIG REQUIRED)

# ...and after our target Main

target_include_directories(Main PRIVATE ${raylib_INCLUDE_DIRS})
target_link_libraries(Main PRIVATE ${raylib_LIBRARIES})

这些我都不是随便上来的。使用方法在软件包的下载目录中都有说明,一般在运行安装命令时都会打印出来。这应该是

./vcpkg/packages/raylib_x64-windows/share/raylib/usage。

骨架项目

你可以使用我的vcpkg骨架项目,它已经为CMake准备好了vcpkg,并设置了include目录。它几乎总结了本文到目前为止提供的所有内容。


通过www.DeepL.com/Translator(免费版)翻译