(我主要写 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 。