克隆回购并运行CMake+;vcpkg项目,不假设vcpkg存在?

克隆回购并运行CMake+;vcpkg项目,不假设vcpkg存在?,cmake,vcpkg,Cmake,Vcpkg,在我对CMake+vcpkg的理解中,我遗漏了一些东西,而且我也遗漏了搜索解决方案的适当关键字。(不幸的是,我对CMake和vcpkg都是新手。) 我想对一个C++项目进行公开的回购,它使用CMake作为其构建系统,VCPKG作为其包管理器。 在我目前的理解水平上,用户需要在键入CMake并构建回购之前安装CMake和vcpkg。我希望尽可能简单地建立回购协议,而不是在他能够建立之前就有一大堆指示告诉他如何建立回购协议 是这样吗 我想要一个一步解决方案:克隆repo用户类型后。。。某物回购协

在我对CMake+vcpkg的理解中,我遗漏了一些东西,而且我也遗漏了搜索解决方案的适当关键字。(不幸的是,我对CMake和vcpkg都是新手。)

我想对一个C++项目进行公开的回购,它使用CMake作为其构建系统,VCPKG作为其包管理器。 在我目前的理解水平上,用户需要在键入

CMake
并构建回购之前安装CMake和vcpkg。我希望尽可能简单地建立回购协议,而不是在他能够建立之前就有一大堆指示告诉他如何建立回购协议

  • 是这样吗
我想要一个一步解决方案:克隆repo用户类型后。。。某物回购协议得以建立

在这个时代,我愿意假设他已经安装了CMake。。。另外,它可以找到正确的工具链。所以他可能只需要输入“cmake”

  • 是否合理假设用户已使用其首选的工具链安装并配置了CMake
我不愿意假设他安装了vcpkg

  • 用户没有安装和配置vcpkg是否是合理的假设
(TBH,我甚至不知道是CMake还是vcpkg配置了工具链-我假设是CMake,但其中一个建议的问题表明是vcpkg…)


今天的合理假设是什么?最小步骤解决方案是什么?

假设用户安装了某些工具没有什么错

假设您正在开发依赖于
libbar
libfoo
,并且您希望让用户能够尽可能轻松地安装
libfoo

使用包管理器 如果
libfoo
libbar
可以通过同一个软件包管理器使用,那么用户需要做的就是:

vcpkg install libbar libfoo
您不必在
libfoo
中执行任何特殊操作,只需指示用户在自述文件中安装所有依赖项即可

使用什么包管理器并不重要

没有包管理器 您仍然希望让人们能够轻松地直接构建和安装您的项目。在项目的构建或配置阶段调用包管理器并解决所有依赖项似乎是用户友好的,因为用户不再需要处理安装这些依赖项的问题,但这不是出于以下原因:

  • 您或其他人可能希望将您的项目添加到另一个包管理器(例如,等等)
  • 有人可能想使用
    libfoo
    ,直接使用等
  • 有些人可能不是vcpkg的用户-如果可能的话,没有必要强迫他们使用它
  • 您可能需要添加另一个依赖项,
    libbaz
    ,该依赖项在
    vcpkg
  • 用户可能已经安装了正确版本的
    libbar
    (不一定通过
    vcpkg
这份清单并非详尽无遗。如果你不是在写一个库,有些观点并不适用

这意味着已经安装了所有依赖项的用户应该能够像这样使用
libfoo

git clone your-repo
cd your-repo
cmake -Bbuild
cmake --build build
cmake --install build
在没有包管理器的情况下解析依赖项 但是,可能需要自动解决依赖关系。如果您的依赖项正在使用CMake,那么最简单的方法就是使用。出于上述某些原因,您应该提供一个逃生舱口,以便人们仍然可以使用已经安装的依赖项。这可以用一个简单的方法来完成。例如,类似于
FOO\u的东西使用外部工具栏
。默认情况下,这可以设置为
yes
no
,没有正确答案。只要用户可以控制这个,我认为这并不重要。您应该为选项命名名称空间,以避免与其他项目使用的选项发生冲突

在这种情况下,构建脚本可以执行以下操作:

if (FOO_USE_EXTERNAL_BAR)
    find_package(bar REQUIRED)
else ()
    FetchContent_Declare(
        bar
        GIT_REPOSITORY bar-repo
        GIT_TAG        release-tag
    )
    FetchContent_MakeAvailable(bar)
endif ()

target_link_libraries(foo PRIVATE bar::bar)
根据libbar的CMakeLists.txt的编写和组织方式,if和else分支可能会变得更加复杂。有关详细信息和提示,请参阅

现在,当我配置项目时,我可以通过将
FOO\u USE\u EXTERNAL\u BAR
设置为
ON
来让
libfoo
解析
libbar
,也可以将其设置为
OFF
以更好地控制解析方式。我甚至可以使用
libfoo
作为已经依赖于
libbar
的项目的依赖项。如果你总是把它拉进来,我无法避免这种情况下的冲突

使用CMake更新依赖项 您可能仍然会发现,使用CMake更新项目的所有依赖项很容易,而无需通过
FetchContent
下载它们。虽然这可能会引起一些注意,但您可以添加一个自定义目标,以使用包管理器解决依赖关系。这也应该通过一个选项来控制。与上述情况不同,我强烈认为,如果您这样做,该选项应默认设置为off:

if (FOO_AUTO_USE_VCPKG)
    add_custom_target(
        update_deps
        COMMAND vcpkg install libbar
    )
    
    add_dependencies(foo update_deps)
endif ()
这将在每次构建foo时调用
vcpgg
,从而降低构建速度。如果删除
add_dependencies
调用,则需要时必须手动运行
update_deps
目标(无论如何不应该经常这样)

笔记 使用选项是为用户提供选项的好方法。应该注意的是,它们增加了认知负荷,因此选择强默认值可以帮助解决这一问题

FetchContent
是一种很好的方法,可以让用户不用担心,但同时,使用它的多个项目最终会一次又一次地重新下载相同的库。它仍然比在构建时调用包管理器更方便用户,并且只要用户能够禁用此行为,就不会有问题
@REM Bootstrap...
set VCKPG_PARENT_DIR=C:\Projects
set CMAKE_VERSION="3.20.2"

mkdir "%VCKPG_PARENT_DIR%"
pushd "%VCKPG_PARENT_DIR%"
git clone https://github.com/Microsoft/vcpkg.git
.\vcpkg\bootstrap-vcpkg.bat -disableMetrics
set PATH=%PATH%;%VCKPG_PARENT_DIR%\vcpkg\downloads\tools\cmake-%CMAKE_VERSION%-windows\cmake-%CMAKE_VERSION%-windows-i386\bin
set VCPKG_DEFAULT_TRIPLET=x64-windows
set PYTHONHOME=%VCKPG_PARENT_DIR%\vcpkg\packages\python3_x64-windows\tools\python3
popd

@REM Build the project...
cmake -B build -S .\engine\ -DCMAKE_TOOLCHAIN_FILE=%VCPKG_ROOT%\scripts\buildsystems\vcpkg.cmake -DCMAKE_BUILD_TYPE=Release -DUSE_PYTHON_3=ON
cmake --build .\build\ --config Release
mkdir bin
xcopy .\build\Release\*.* .\bin\
xcopy .\build\objconv\Release\*.* .\bin\
xcopy .\build\setup\Release\*.* .\bin\