2026/4/18 11:04:58
网站建设
项目流程
郑州制作网站ihanshi,阿里云快速建站教程,网页制作教程课件,给个网址你知道的#【CMake】在CMake项目中#xff0c;Vcpkg、Conan或Spack用于C依赖
我最近用过一点 Vcpkg#xff0c;也在更好地了解它。我也看过 Conan#xff0c;但最近没怎么深入研究 Spack。我从开发者的角度来看#xff0c;想改进第三方依赖的处理。这并不是要穷尽一切#xff0c;而…#【CMake】在CMake项目中Vcpkg、Conan或Spack用于C依赖我最近用过一点 Vcpkg也在更好地了解它。我也看过 Conan但最近没怎么深入研究 Spack。我从开发者的角度来看想改进第三方依赖的处理。这并不是要穷尽一切而是想探讨我最感兴趣的一个具体用例在某些依赖关系很大需要缓存的情况下我能以最优雅的方式处理我的项目依赖。Conan一开始让我却步的是 Python 的要求这意味着我需要很大程度上依赖所有依赖。话虽如此安装过程相当简单mkvirtualenv conan pipinstallconan --upgradeArch Linux 上还有一个 AUR 包。有了之后你需要创建一个包含依赖的conanfile.txt以及使用conan 配置文件 detect --force 的 Conan配置文件。配置文件包含了可以使用的 C 标准和构建模式。所以你需要创建一个配置文件用于调试、发布等。我喜欢默认依赖指定方式的一点是规范中使用了版本。以下是我添加到 angohr 仓库以满足相同 vcpkg 依赖的内容[requires]fmt/10.2.1gtest/1.14.0spdlog/1.13.0[generators]CMakeDepsCMakeToolchain然后使用配置文件安装这些依赖conaninstall.--output-folderbuild-release --buildmissing一旦完成这些作命令会自动CMakeUserPresets.json添加该目录中的文件这意味着我现有的预设不容易被重用。为了测试我选择了以下几种CCclangCXXclang cmake -G Ninja --preset conan-release -DDuckDB_DIR/home/marcus/src/duckdb/build完成这些并修复了 CMake 代码中的一个 bug 后我就能成功编译项目并运行测试。这个提交显示了依赖文件的添加以及它发现的实际查找和使用spdlog的修复方法。SpackSpack 也有类似的依赖这让我对 Conan 有兴趣因为它基于 Python意味着我的依赖构建依赖相当大。我知道我们通常都有 Python 可用所以绝不是致命缺点。它还提供克隆或 Arch Linux 的 AUR 包。我试过用这个包但每次运行时都会被要求权限提升我在这种情况下可不想要所以克隆的方法是gitclone -c feature.manyFilestrue https://github.com/spack/spack.git.spack/share/spack/setup-env.sh这提供了一个不试图获得更多权限的安装接下来是如何指定我的项目依赖。文档内容详尽仔细阅读后环境大概是我在这个语境下想要的。spackenvcreate angohr spackenvactivate angohr然后您向环境添加规格有点奇怪spackaddfmtspackaddgoogletest spackaddspdlog spackinstall这导致我安装了三个包管理器中最多的一组像autotools、gcc、cmake和 perl 这样的工具在屏幕上闪烁。它可能是最自成一体的但这并不是我特别需要的。安装这三个软件包后结果是$ spackfindIn environment angohrRoot specsfmtgoogletest spdlogInstalled packages -- linux-archrolling-zen4 / gcc13.2.1 -------------------------- berkeley-db18.1.40 diffutils3.9 googletest1.14.0 perl5.38.0 bzip21.0.8 fmt10.2.1 libiconv1.17 pkgconf1.9.5 ca-certificates-mozilla2023-05-30 gcc-runtime13.2.1 ncurses6.4 readline8.2 cmake3.27.9 gdbm1.23 nghttp21.57.0 spdlog1.12.0 curl8.6.0 gmake4.4.1 openssl3.2.1 zlib-ng2.1.520installed packages对于一个相对较小的轻量级库来说这感觉有点多。CCclangCXXclang cmake -B build -S.-G Ninja -DDuckDB_DIR/home/marcus/src/duckdb/build cmake --build build这个配置是完成的但编译失败了因为看起来 spdlog 使用了内置的 fmt 副本。我相信这确实是可以修复的问题但开箱即用的体验令人失望。总的来说最符合环境创建体验的方法是你可以在代码目录里创建一个 YAML 文件来指定依赖这个文件在环境部分稍后一些。Vcpkg我觉得 Vcpkg 在很多方面学习曲线最陡峭需要学习第三方指定构建参数、用 git magic 创建使用 git trees 的端口以及指定预设。一旦做到这一点它还提供了一个依赖最少且与 CMake 集成最紧密的构建环境。以下内容将构建一个项目cmake --preset default -DDuckDB_DIR/home/marcus/src/duckdb/build cmake --build build依赖的规范是最简单的只需在源树中添加 vcpkg.json{dependencies:[fmt,gtest,spdlog]}我不喜欢的一点也成了巨大优势它与 git 深度集成我可以指定我想用的注册表的基础 SHA。这会锁定所有依赖直到该 SHA 更新{default-registry:{kind:git,repository:https://github.com/microsoft/vcpkg,baseline:80403036a665cb8fcc1a1b3e17593d20b03b2489}}我不太喜欢但后来接受的是使用配置步骤让所有这些都用预设实现这让一切变得简单添加以下条目后预设会使用 vcpkgCMAKE_TOOLCHAIN_FILE:{type:PATH,value:$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake},VCPKG_TARGET_TRIPLET:{type:STRING,value:x64-linux-dynamic}上游显然不认为我们应该在 Linux 上使用动态库我强烈不同意但他们也提供了多种机制来利用这些库。我认为另一个缺点是默认为每个包构建调试和发布版本这需要两倍时间而且通常不需要。你可以用一些技巧来避免这种情况但默认的姿势令人恼火。CMake 包管理器我提到 CMake 包管理器我会把它归为与上述三个不同的类别因为它不支持依赖解决或缓存二进制文件。拉入小型依赖非常方便你可以从 Git 仓库抓取它们轻松配置和构建。我建议在你选择的上述方法之上叠加针对那些使用 CMake 的小依赖。它是纯粹的 CMake 实现几乎没有额外的依赖只有一些 CMake 代码而且有不少不错的例子可以找到。其他包管理器都提供添加自己包的方式但没有哪个能比得上它的简单。它与 CMake 集成得非常好你的项目可以非常无缝地使用但对于配置和构建需要超过 20-30 秒的项目我可能会选择上述三种方案中的一个。结论这三种变体都使用外部构建的 DuckDB 进行比较。这三家公司都提供了三个依赖而我几乎不费力地提供了他们已有的软件包。它们在指定依赖内容时会有细微差异比如使用 INI 风格文件、YAML 或 JSON但转换起来很方便。更大的区别在于它们如何让这些依赖可用以及它们与 CMake 的集成程度。说实话我刚刚花了半小时甚至更久浏览了这三款的文档还有那个额外的文档。我更广泛地使用了 Vcpkg 和 CMake Package Manager所以上面提到的情况可能被花在它们上的时间太多而有所偏颇。我也从我能提供的最简单开发者体验的角度仔细审视过这个问题。我还考虑过 CMake 预设与 VS Code 等 IDE 的集成改进。我只认为 Vcpkg 和 CMake Package Manager 能为开发者提供一个很棒的“开箱即用”体验用户可以选择一个预设导入包管理器并构建所有依赖然后再构建项目。维护代码时Vcpkg 还会更新对新源代码重建的依赖这非常有优势。Conan 和 Spack 似乎有分离构建树的问题你也可以用 Vcpkg如果我漏掉了两个模式都能这样作我会感兴趣。我觉得 Vcpkg 的版本规格令人失望只能要求 但他们也提供了覆盖功能可以精确指定。在 Vcpkg 中更深入地使用 git 让我更有信心可以选择何时更新依赖并且能在仓库中以原子的方式完成。讨论的四个选项都比我以前编写的“超级构建”更优越满足了我们当时想要的软件包重复使用需求。参考https://cryos.net/2024/03/vcpkg-conan-or-spack-for-c-dependencies-in-a-cmake-project/