漏了个 xmake 和 spack,前者内置了包管理,后者是个包管理工具。
CMake 你不能 cmake 两次用build-x86/, build-arm/ 来达到编译两次的操作?
你用 VCPkg 维护自己的 ports,那也可以考虑 Gentoo emerge 了,不比 vcpkg 更灵活!
【 在 snnn 的大作中提到: 】
: 标 题: 关于VCPKG的一些使用感受
: 发信站: 水木社区 (Wed Apr 23 14:31:28 2025), 站内
:
: C++是所有现代编程语言中极少见的没有标准化的包管理器的。我先后考察了如下解决方案:
:
:
: 1. Bazel
: 2. CMake + FetchContent
: 3. Conan
: 4. VCPKG
:
: 这其中毫无疑问Bazel是最强大的但是也是最难学的。可惜它的生态系统很差。大部分开源库并不支持Bazel。这就意味着使用者需要花大量精力做各种移植。
:
: CMake FetchContent在近2-3年有个很大的发展,可以说能满足我的绝大部分需求。
:
: Conan引起了我的注意是因为我的一个朋友,Python社区的Matthieu Darbois,是做这个的。
:
: 下面就具体说下VCPKG吧。
: VCPKG主要做一件事情:下载C/C++源代码、编译、安装到指定位置。然后我们就可以用Linux的pkg-config或者CMake的find_package找到已安装的软件库并集成进来。通常来说,做这件事情主要的挑战有:
: 1. 编译器版本及编译选项需要保持一致
: 2. 可重复性(reproducible build)
: 3. 解决版本冲突
: 4. 安装位置重定向(Relocatable package)
:
: 我比较欣赏的是vcpkg帮我解决了一个很大的痛点:跨平台编译。比如,我要在x86的系统上为树莓派编译一个软件,而该软件用到了protobuf,需要用protoc去生成一个C++源代码并编译。那么我就需要把protoc编译成x86。但是protoc本身又依赖于一些其它函数库。这就意味着某些函数库
: 枰槐嘁肓奖椋赫攵詘86以及arm。这个事情直接拿CMake是没法搞的。CMake没有把一个target用不同配置编译两遍这样的骚操作。
:
: vcpkg的另一个好处是: 使用者并不需要被vcpkg捆绑住。假如你现在有一个基于CMake的项目,你想用vcpkg去管理依赖。你并不需要修改你现在的项目代码或者cmake文件。你可以理解为vcpkg只是一个installer。你随时可以换成另一个工具来编译安装那些软件。
:
: vcpkg自从加了对binary cache的支持后,基本上就可以很大程度上替代dnf/apt-get等传统的包管理软件。因为cache server其实就是package repository。VCPKG并不是只用来管理C++库的。二进制文件可以用同样的方式管理。
:
: VCPKG虽然有一个官方的包集合(ports),但是我基本不用。你可以理解为:dpkg和apt-get的关系。我只用dpkg,所有包都自己打。于是debian/ubuntu的官方源就跟我没关系了。因为实际使用中我需要为这些软件库打自己的补丁,或者我需要自主的控制它们的版本(官方源里的版本太旧)
: 。
:
: 最痛苦的使用经历是:有时候需要自己给vcpkg写toolchain。这个事情非常的恶心在于整个系统有三种不同的toolchain.cmake存在:
: 官方的vcpkg的toolchain.cmake,这是主入口。在编译ports的时候必须用这个文件,不能自定义更改。
: 目标平台所提供的toolchain.cmake文件。比如Android有android的toolchain.cmake
: VCPKG自己的toolchain folder里面的文件:scripts/toolchains/*.cmake。
:
: 那么什么情况下需要这么做呢?比如:
: - 使用一个官方的build system不支持的平台,比如emscripten。
: - 使用一种不常见的编译器组合: 比如在Windows上用除了MSVC以外的任何C++编译器
: - 使用一些特殊的编译器flags,比如在Windows上禁用C++异常。很不幸,vcpkg官方的toolchain文件写死了启用异常。
:
: 与自定义toolchain.cmake相比,自定义triplet文件要容易的多。我为我的项目写了几千行python脚本专门用于生成各种不同的triplet文件。比如Linux with exception, Linux without exception, Linux with RTTI, Linux without RTTI, Linux clang, etc. 基本上稍微有一点点定制
: 托枰匆桓鰐riplet文件。而且这里最大的难点就是要细心检查以确保编译ports所用的C++ flags和编译项目主程序代码的flags是一致的。比如,如果要启用address sanitzier 那么两边都需要启用。我遇见的最大的坑是:我为emscripten生了一个triplet文件,在里面设置了VCPKG_C_F
: LAGS等等,但是实际编译的根本没起效。后来发现这些VCPKG_XXX flags是需要vcpkg里的toolchain文件来处理的,然而vcpkg并没有为emscripten(wasm)提供这样的支持。
: --
:
: ※ 来源:·水木社区
http://www.mysmth.net·[FROM: 110.242.67.*]
--
FROM 123.119.249.*