如果您不熟悉我们的C++库管理器VCPKG,欢迎!这篇文章涵盖了一个中级/高级的主题,因此您可能需要首先从中获得一个概述并尝试一些东西 vcpkg GitHub页面 或者一些 我们以前的博客 .
介绍
C++的一个最优点是它为每个特定的机器生成定制的、专用的代码,使您能够压缩每瓦特的每盎司性能。它使干净的抽象能够与底层特定于平台的位旋转和平共存。然而,这对于许多冒险超越自己机器的开发人员来说是有代价的:你必须为你的开发人员机器构建不同于你最终目标的二进制文件,不管是手机、云服务器还是嵌入式微控制器。
对于大多数中小型项目来说,这不是问题。您已经有了一个编译器、一个代码编辑器和一个构建系统,这足以生成大量令人难以置信的应用程序。然而,自古以来,有些开发人员就需要比编译器更大的灵活性、可扩展性和强大的功能;他们需要在构建时生成复杂的代码。也许是在计算 函数 在你已知的数据集上,可能是 表驱动解析器 或者是一堆 外部功能接口 嵌入脚本语言的样板文件。不管什么原因,你需要C++的灵活性 对于您的开发环境 除了最终的运行时目标。
在这篇博文中,我们将介绍新发布的vcpkg功能,该功能旨在支持所有这些场景以及更多: 主机依赖项 .
同步编译
如引言所述,因为C++一直沿用到金属,所以通常不能使用同一编译器和标志来同时针对最终运行时和开发人员机器。如果您使用的是多目标编译器(如Clang/LLVM),则至少需要不同的标志;如果您使用的是单一目标编译器(如GCC或MSVC),则需要完全不同的编译器。
如果幸运的话,您的构建系统有关于如何处理这种情况的特定文档。即使这样,有时也会非常微妙地确保事情连接正确:您是否意外地将目标的标志传递给开发人员机器构建?如果需要库来运行代码生成器呢?代码生成器如何为其他代码生成器生成代码?这是一个棘手的问题空间,对构建环境的各个方面都有影响。
三胞胎
在vcpkg中,我们将每个目标宇宙标记为一个单独的“三元组”。例如,x64windows桌面使用动态CRT和MSVC,但是构建静态库可能会被命名为 x64-windows-static-md
. 在该宇宙中构建的每个库都与来自该宇宙的其他库相链接,保持所有内容的超级一致性。我们在这个框中包含了许多三元组定义,但是您可以轻松地根据每个库调整编译器标志或设置(也许您希望Qt是动态构建的,但是JSON解析器是静态构建的)。
当然,您的开发人员环境也与这些领域中的一个相匹配。默认情况下,我们选择 x64-windows
, x64-linux
,或 x64-osx
但它在运行时可以通过 几种方法 .
主机依赖项
尽管vcpkg有一个与开发人员环境匹配的三元组,但是vcpkg没有库的语法来表示对为该环境构建的端口的依赖。我们已经在不完美的方法上取得了很大进展,比如动态地尝试从一组硬编码的回退三元组中使用库,但是这些方法总是达不到理想的效果,并且需要在不同端口之间复制不完美的代码。这些解决方法也完全没有问题 清单模式 ,这是专门设计用来防止这种“动态”访问出现的片状行为。当然,修复是一种自然而直接地表达对为开发人员环境构建的端口的需求的方法。
输入:主机依赖项。现在,端口和使用者可以声明对针对开发人员环境构建的其他端口的依赖关系。
激活它的语法只是设置 "host"
到 true
在清单依赖项对象中:
{ "dependencies": [ { "name": "contoso-cgen", "host": true } ] }
在执行期间,端口可以依赖已安装到的所有主机依赖项 CURRENT_HOST_INSTALLED_DIR
(模拟 CURRENT_INSTALLED_DIR
)他们可以通过 HOST_TRIPLET
(模拟 TARGET_TRIPLET
).
set(CGEN ${CURRENT_HOST_INSTALLED_DIR}/tools/contoso-cgen/cgen${VCPKG_HOST_EXECUTABLE_SUFFIX}) vcpkg_cmake_configure( SOURCE_PATH ${SOURCE_PATH} OPTIONS -DCODE_GENERATOR=${CGEN} )
对于嵌入了自己的代码生成器的项目,要求 你自己 为主机构建:
{ "name": "protobuf", "dependencies": [ { "name": "protobuf", "host": true } ] }
然后,端口可以通过比较三元组来确定它是跨建筑物还是本机建筑物:
if(HOST_TRIPLET STREQUAL TARGET_TRIPLET) # Native compilation, set build flags to build and install the code generator else() # Cross compilation, set build flags to consume the prebuilt code generator # from ${CURRENT_HOST_INSTALLED_DIR} endif()
给我们你的反馈!
通过访问我们的 GitHub回购 . 我们欢迎您对该工具和新功能的反馈 在我们的问题追踪器中 .
我们才刚刚开始将这个强大的新功能整合到现有的目录中,比如Boost.Build( vcpkg/vcpkg.json在master·microsoft/vcpkg(github.com) )和Protobuf( vcpkg/vcpkg.json在master·microsoft/vcpkg(github.com) ). 对于那些瞄准iOS、Android和Emscripten/WebAssembly等重要平台的vcpkg用户来说,这是一个巨大的进步。
关于主机依赖关系的最新文档可以在我们的GitHub上找到 vcpkg/host-dependencies.md位于master·microsoft/vcpkg(github.com) .