[求助] Linux 有什么好的引入 c++ 第三方库的方案 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zcion
V2EX    C++

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

  •  
  •   zcion 1 天前 1417 次点击

    问题

    之前用 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_libraryfind_path 引入库文件和头文件,但这样太麻烦了(例如要使用 ffmpeg ,那我得分别手动搜索 libavformat 、libavcodec 、libavutil 、libswscale 的头文件和库文件),用 find_package 倒是可以很方便解决,但 pacman 下载的依赖似乎没有提供相关的 .cmake 文件?

    so ?

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

    17 条回复    2025-11-24 09:47:11 +08:00
    w568w
        1
    w568w  
       1 天前   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
        2
    ysc3839  
       1 天前 via Android
    boost 的话直接用 cmake 的 find_package 就行了,不需要 pkg-config
    kekxv
        3
    kekxv  
       1 天前 via iPhone
    bwnjnOEI
        4
    bwnjnOEI  
       1 天前 via iPhone   1
    我用的 conan
    mz02005
        5
    mz02005  
       1 天前 via iPhone
    不是,你都用 vcpkg 了,还想如何?
    LindsayZhou
        6
    LindsayZhou  
       1 天前
    em... 我不了解 C 开发,不过 asio 是这东西吗?它好像和 boost 不是同一个包,它带了 .pc 文件:

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

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

    想要兼容更多的 Linux 发行版,你就要考虑编译环境的 glibc 版本(想要兼容更老的版本,就意味着不能使用 C++更新的标准)
    tinybaby365
        11
    tinybaby365  
       20 小时 28 分钟前
    @jsph bazel 是理想,小团队不现实
    shylockhg
        12
    shylockhg  
       18 小时 24 分钟前
    把所有 lib 放一个 cmake 工程用 external project 管理,编译安装 tar 打包,根据 libc 版本,区分不同 tar 包
    shylockhg
        13
    shylockhg  
       18 小时 22 分钟前
    @shylockhg 如何涉及到 c++98/11,libc++/libstdc++之类的还需要加上 abi 区分 tar 包
    shihira
        14
    shihira  
       10 小时 11 分钟前
    或许比较邪教的 flake.nix ?
    pluswu1986
        15
    pluswu1986  
       1 小时 2 分钟前
    conan
    Fenicesun
        16
    Fenicesun  
       54 分钟前
    我都是把所有的依赖库源码放在 third_party 和自己工程一起编译
    MrVito
        17
    MrVito  
       42 分钟前
    conan
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5790 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 21ms UTC 02:29 PVG 10:29 LAX 18:29 JFK 21:29
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86