zcion
V2EX  ›  C++

[求助] Linux 有什么好的引入 c++ 第三方库的方案

  •  1
     
  •   zcion · Nov 22, 2025 · 5632 views
    This topic created in 349 days ago, the information mentioned may be changed or developed.

    问题

    之前用 windows 开发,为了统一使用第三方库行为,我习惯 cmake + vcpkg 这套,直接用上 vcpkg.cmake 后在 cmake 中 find_package 就行。

    而 linux 已经有自己的包管理器了,我直接 pacman 可以很方便的下载第三方库。但问题是有哪些统一行为能够在 cmake 引入 pacman 下载的内容(头文件+库文件)?

    我的一些想法

    我能想到的是通过 pkg-config 去统一管理,在 cmake 中 find_package(PkgConfig),然后用 pkg-config 的东西去引入。

    但当我通过 pacman 下载 boost 时( boost 和 boost-libs ),用 pkg-config 找不到对应的文件(例如我想引入 asio 库,但 pkg-config --list-all | grep asio 找不到相关的内容)。通过 pacman 下载的 boost 似乎没有提供 .pc 文件,导致 pkg-config 不知道这么个东西。

    另外我能想到的是,手动的在 cmake 中 find_library 和 find_path 引入库文件和头文件,但这样太麻烦了(例如要使用 ffmpeg ,那我得分别手动搜索 libavformat 、libavcodec 、libavutil 、libswscale 的头文件和库文件),用 find_package 倒是可以很方便解决,但 pacman 下载的依赖似乎没有提供相关的 .cmake 文件?

    so ?

    似乎 pkg-config 不是终极解决方案,所以有什么方案能够统一引入依赖的行为。难道还要继续使用 vcpkg 吗?(确实好用,但看一些人的说法是 linux 上建议使用自带的包管理器)

    21 replies  •  2025-12-04 10:20:22 +08:00
    w568w
    w568w
    Nov 22, 2025❤️2
    1
    (我主要写 C ,没写过 C++,所以下面一部分说法可能不准确。)

    这个问题其实有系统级和语言级的两层,一是 Linux 对 C/C++ 依赖的管理没有明确的定义,各个发行版自立山头;二是 C/C++ 的包管理本身确实很乱。

    1. 对于前者,可以认为在依赖管理这件事上,Linux 没有规定什么做法是标准的,所以「每个系的发行版都是完全独立的体系」,不应该像 Windows 7/8/10/11 那样当成同一血脉的系统来看待。

    尽管大家可以找出一些最大公约数(比如大多遵循 FHS 、使用 pkg-config 和 gcc ),但在实现上会有非常多细微的差别。大部分差别在开发过程中可以消解掉(例如使用 CMake 的 find_library/package 过程)但不是全部,而在打包和分发过程中则完全需要各个区别对待(比如 Debian 系、Gentoo 系和 Redhat 系,在分割软件包的粒度和指定依赖的方式上,做法都完全不同)。

    此外,Linux 本身又是极度依赖 source-driven 的,需要时刻考虑用户利用现有环境进行开发的可能性。这就是为什么 Linux 下很难有 vcpkg 这样一个独立的、和系统无关的 C/C++ 包管理器。或者说即使有了,也不会好用,因为你最终还是要为每个发行版、编译器和依赖组合付出额外的成本去适配。

    2. 对于后者,你的例子其实就是很好的典型。「通过 pacman 下载的 boost 似乎没有提供 .pc 文件」,是因为 boost 这个库本身只提供了 CMake 模块。你用 pacman -Ql boost 就能看到,boost 提供的是 /usr/lib/cmake/Boost-xxx/BoostConfig.cmake 配置文件,而不是 pkg-config 文件。

    这种四世同堂的局面很多,不是每个包都会提供 pkg-config 来兜底(从功能性上来说,CMake Modules 无疑是更先进的)。这其实也是生态碎片化的体现:开发中的选择一旦多起来,开源作者都会习惯性选择自己最习惯的,而不是兼容性最好的。你问「有没有办法用统一的方式导入」,其实就和前端问「有没有办法在我的 React 项目里导入其他 UI 框架的控件」是一样的。当然这边的问题至少理论上是 solvable 的。

    ----


    所以我能给的建议是什么呢?

    1. 如果你专为某个发行版开发程序:完全本土化。使用那个发行版和系统包管理器,完全遵循那个发行版的逻辑。系统提供什么就使用什么方式引入;

    2. 如果你为所有发行版开发程序:防御性编程,减少假设。同上,但是尽可能不要依赖某些假设(例如「一定有 pkg-config 」)。CMake 的 https://cmake.org/cmake/help/latest/guide/using-dependencies/index.html 介绍了通用的建议,主要是 尽可能使用 find_package 来引入依赖、使用 FetchContent 来从源码编译依赖 及 不要使用 FindPkgConfig 。
    ysc3839
    ysc3839
    Nov 22, 2025 via Android
    2
    boost 的话直接用 cmake 的 find_package 就行了,不需要 pkg-config
    kekxv
    kekxv
    Nov 23, 2025 via iPhone
    3
    bwnjnOEI
    bwnjnOEI
    Nov 23, 2025 via iPhone❤️1
    4
    我用的 conan
    mz02005
    mz02005
    Nov 23, 2025 via iPhone
    5
    不是,你都用 vcpkg 了,还想如何?
    LindsayZhou
    LindsayZhou
    Nov 23, 2025
    6
    em... 我不了解 C 开发,不过 asio 是这东西吗?它好像和 boost 不是同一个包,它带了 .pc 文件:

    https://archlinux.org/packages/extra/any/asio/
    sir283
    sir283
    Nov 23, 2025
    7
    手动找,或者自己拉源码 rebuild 一遍,生成 pkg-config ,就这样,下一个问题。
    jsph
    jsph
    Nov 23, 2025
    8
    bazel
    bigtan
    bigtan
    Nov 23, 2025
    9
    vcpkg 在 Linux 一样可以用啊 cmake 不都跨平台吗
    tinybaby365
    tinybaby365
    Nov 23, 2025
    10
    依然使用 cmake + vcpkg ,也可以 cmake + ExternalProject_Add

    如果你想要你的程序不只是兼容特定的 Linux 发行版,你就不要使用 Linux 包管理器安装的-dev 或-devel 包。这一点上商业软件为了维护更少的包,基本上会采取这种做法,和 Linux 发行版里面自带软件的做法相反。

    想要兼容更多的 Linux 发行版,你就要考虑编译环境的 glibc 版本(想要兼容更老的版本,就意味着不能使用 C++更新的标准)
    tinybaby365
    tinybaby365
    Nov 23, 2025
    11
    @jsph bazel 是理想,小团队不现实
    shylockhg
    shylockhg
    Nov 23, 2025
    12
    把所有 lib 放一个 cmake 工程用 external project 管理,编译安装 tar 打包,根据 libc 版本,区分不同 tar 包
    shylockhg
    shylockhg
    Nov 23, 2025
    13
    @shylockhg 如何涉及到 c++98/11,libc++/libstdc++之类的还需要加上 abi 区分 tar 包
    shihira
    shihira
    Nov 24, 2025
    14
    或许比较邪教的 flake.nix ?
    pluswu1986
    pluswu1986
    Nov 24, 2025
    15
    conan
    Fenicesun
    Fenicesun
    Nov 24, 2025
    16
    我都是把所有的依赖库源码放在 third_party 和自己工程一起编译
    MrVito
    MrVito
    Nov 24, 2025
    17
    conan
    ink19
    ink19
    Nov 24, 2025
    18
    如果是自己的项目,我建议 xmake
    nno
    nno
    Nov 24, 2025
    19
    vcpkg 在 linux 下经常编译失败;但 conan 不会,而且 conan 可以生成各种各样的构建文件
    heyzenxu
    heyzenxu
    Nov 25, 2025
    20
    conda 生态的 [pixi]( https://pixi.sh) 了解下, 开发体验类似 rust + cargo
    jianglibo
    jianglibo
    PRO
    Dec 4, 2025
    21
    继续用 cmake+vcpkg 啊,我的项目在 windows ,macos ,linux(suse,rocky,ubuntu,apline),freebsd 都可以编译发布啊,现在有了 AI 几乎不用学 cmake 配置。使用 vcpkg 需要科学上网而已。可以参考我的开源项目,https://github.com/coderealm-atlas/cert-ctrl ,时间允许的话我会编译到 openwrt 试试看。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1908 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 55ms · UTC 08:51 · PVG 16:51 · LAX 00:51 · JFK 03:51
    ♥ Do have faith in what you're doing.