什么是包管理器,C++ 有没有像 pip、npm、gem 一样的包管理工具?

2023-05-16

文章目录

    • 一、包管理器
      • 什么是包?
    • RPM包管理器
    • dpkg包管理器
    • 二、C++ 有没有像 pip、npm、gem 一样的包管理工具?
    • 三、C++包管理器有哪些
      • 1. [Conan](https://github.com/conan-io/conan)
      • 2. [Buckaroo](https://github.com/LoopPerfect/buckaroo)
      • 3. [vcpkg](https://github.com/microsoft/vcpkg)
      • 4. [clib](https://github.com/clibs/clib)
      • 5. [poac](https://github.com/poacpm/poac)

一、包管理器

按照惯例,先看百度百科的定义:

包管理器又称软件包管理系统,它是在电脑中自动安装、配制、卸载和升级软件包的工具组合,在各种系统软件和应用软件的安装管理中均有广泛应用。

什么是包?

一个“包package”(或“软件包”)通常指的是一个应用程序,它可以是一个 GUI 应用程序、命令行工具或(其他软件程序需要的)软件库。包本质上是一个存档文件,包含二进制可执行文件、配置文件,有时还包含依赖关系的信息。

在旧时代,软件曾经是从它的源代码安装的。你会参考一个文件(通常命名为 README),看看它需要什么软件组件、二进制文件的位置。它通常包括一个配置脚本或 Makefile。你必须自己编译该软件或自己处理所有的依赖关系(有些软件需要安装其他软件)。

为了摆脱这种复杂性,Linux 发行版创建了自己的打包格式,为终端用户提供随时可用的二进制文件(预编译软件),以便安装软件,同时提供一些元数据(版本号、描述)和依赖关系。

在Linux发行版中,几乎每一个发行版都有自己的包管理器。常见的有:

  • 管理deb软件包的dpkg以及它的前端apt(使用于Debian、Ubuntu)。
  • RPM包管理员以及它的前端dnf(使用于Fedora)、前端yum(使用于[Red Hat Enterprise Linux](https://baike.baidu.com/item/Red Hat Enterprise Linux))、前端ZYpp(使用于openSUSE)、前端urpmi(使用于[Mandriva Linux](https://baike.baidu.com/item/Mandriva Linux)、Mageia)等。使用包管理器将大大简化在Linux发行版中安装软件的过程。

RPM包管理器

RPM,全称为Redhat Package Manager,是由[Red Hat](https://baike.baidu.com/item/Red Hat)推出的包管理器,现在在各种发行版中普遍使用。

使用RPM的发行版

  • Fedora和[Red Hat Enterprise Linux](https://baike.baidu.com/item/Red Hat Enterprise Linux)
  • openSUSE和SUSE Linux Enterprise
  • [Mandriva Linux](https://baike.baidu.com/item/Mandriva Linux)和Mageia
  • PCLinuxOS

dpkg包管理器

dpkg是Debian Package的简写,由Debian发行版开发,用于安装、卸载和供给和deb软件包相关的信息。

使用dpkg的发行版

使用dpkg的发行版主要是Debian以及它的派生版如Ubuntu等。

二、C++ 有没有像 pip、npm、gem 一样的包管理工具?

转一个大佬的回答:
链接:https://www.zhihu.com/question/26117075/answer/86056267

此问题相当有价值,我认为我会持续更新。已经将不严谨的“二进制”和“源代码”更换为更为严谨的描述"as is"和"source"。

我欢迎各类程序员和我一起探讨这个问题。

先说结论:c/c++和其他语言不同,要管理c/c++的包,你需要管理的不是"as is",而是"source"写程序的人需要的包管理器,和管理系统的人需要的包管理器是不一样的

npm/apt/yum之类的包管理器的特点主要是"as is",也就是下载下来就可以用。这样子对于C++来说是非常非常难以做到的,比如:

  1. Windows下的MT/MTd/MD/MDd我无法解决。换言之,如果要通用,Windows 32bit就要至少提供四套binary。更加烦的是从Visual Studio 2012开始还需要指定XP兼容性。此外Debug Info指向的cpp文件是绝对路径,也就是换个电脑你只能手动指定源文件的位置。

  2. Linux下的binary也有区别,举个例子,有RTTI和没有RTTI的代码是没法链接在一起的。

如果我需要要做到"as is",我不单单需要为不同的系统、配置提供不同的binary,还需要为一些编译选项提供不同的binary。于是一个版本,我将提供几乎数不清的binary,因为不同的配置、系统、编译选项之间还可以做笛卡尔积。更何况,只有binary并不能调试,Debug Info通常占用的空间会比binary更加巨大,常常可以做到几个G,单单是压缩这些Debug Info就会耗费几十分钟的时间,对于包发布者来说,是个巨大的压力。

此外,C++由于其复杂的历史原因,造成了复杂的依赖项,有的依赖perl,有的依赖于python,。这些项目的历史悠久,有无数数不清的坑。想要做到"Modern",不是不想,而是实在是做不到。比如LLVM和Clang,已经算是这些项目中非常优秀的项目了,历史包袱也不是非常多,代码非常优秀,模块化,可是做了不知道多久还没有彻底从Autotools迁移到CMake。这些复杂的依赖项是没有办法说直接"as is"使用的,因为他们的目录的位置并不是遵循一个统一的标准,如果说有一个统一的标准,那么C++的包管理器会好做很多。

同样的问题,出现在同样历史悠久的PHP身上。PHP本身有非常多的坑,这个就不细说了,而Composer花费了近10年时间才逐渐将PHP变成了现在这个Modern的样子(当然还有PHP自己的努力)。

有C++包管理器尝试说要求每个添加进库的项目都必须是符合规定的,例如,比如使用CMake。很不幸,目前C++领域最多人用的包管理器是这个思路。CMake非常优秀,然而正如我上面所说。但逐一纠正每个包,几乎是不可能的。我认为更实际的做法是,为每个包写一个编译配置,只需要编译好的头文件和二进制符合规范即可。我们必须要兼顾到C/C++悠久的历史所导致的无数的编译环境,例如autotools, CMake, gyp, ninjia。

最近很火的Rust的包管理器Cargo,所使用的方法,如我所使用的一样,是将源代码包"as is"下载下来,在编译的时候,优先编译dependencies。我认为这是比较符合实际的做法,它避免了我所上面列举的一些问题:

  1. Binary的规则太细并不互相兼容:重新编译可以保证编译选项是兼容的。

  2. 所依赖的包太多历史包袱,无法兼容新的标准:即时编译以后将编译好的二进制和文件按照统一的规范存储到新的位置。

Rust的Cargo的一个问题是要求必须使用Rust的脚本编译,而不是Shell。这样子对于我们来说也许是坏消息。但对于Rust来说,可以避免其仓库被海量的C++代码库湮灭,也许是幸运。

就算是如我上面所说,还会有一些新的问题:

  1. 编译的时间太久:于是可以使用缓存的方法,将一个依赖项的某一个配置缓存起来。这对于其他语言来说可能不是刚需,但对于C++来说,简直太需要了。

  2. 为每个包写符合规范的配置选项,仍然会是一个很大的工作量。这一点我相信靠我们的努力,未来会做得更好。

三、C++包管理器有哪些

包管理器可以帮助你更方便地安装依赖关系,并决定所安装的版本,提高你的开发幸福感。许多语言都有自己的包管理器,像 Node.js 的 npm/yarn、Rust 的 Cargo、Python 的 pip 等等。当然,C/C++ 也有它自己的包管理器!下面我们就来感受下这些库的魅力和特点吧~

1. Conan

  • Star 数:3k
  • 文档:https://docs.conan.io/en/latest/

首先出场的是 Conan(注意,不是柯南!),一个用 Python 编写的 C/C++ 包管理器。它是完全分散的,你可以自己托管服务器中的包。它适用于所有平台,包括 Linux、OS X、Windows、Solaris、FreeBSD、嵌入式和交叉编译、docker、WSL。它可以与任何构建系统集成,为 CMake、MSBuild、Makefiles 等工具提供了经过测试的支持。除此之外,它还获得了奔驰、华为等大公司用户。你还可以在 Conan-Center 寻找或分享你的 C/C++ 包。

想要安装 Conan 也很简单:

$ pip install conan

2. Buckaroo

  • Star 数:600
  • 文档:https://github.com/LoopPerfect/buckaroo/wiki

这个 C++ 包管理器是使用 F# 语言开发的。它的独特之处就是直接从 GitHub、BitBucket、GitLab、托管的 Git 和 HTTP 中提取依赖项。同样的,它也是完全分散的,没有中央服务器。Buckaroo 使用 TOML 配置文件。

安装方法详见 Quick Install。

它的工作流大概是这样的:

# Create your project file
$ buckaroo init

# Install dependencies
$ buckaroo add github.com/buckaroo-pm/boost-thread@branch=master

# Run your code
$ buck run :my-app

3. vcpkg

  • GitHub 项目地址:
  • Star 数:6k
  • 文档:https://vcpkg.readthedocs.io/

vcpkg 是由微软爸爸开发的支持 Windows、Linux、Mac OS 的 C++ 库管理器,解决了 Windows 下常用依赖包的管理问题!它方便与 Visual Studio 集成,你可以使用 vcpkg search 搜索可用的包。它也可以从 Bitbucket、GitHub、GitLab 等获取包。

安装方法详见 Quick Start。

4. clib

  • Star 数:3k
  • 文档:https://github.com/clibs/clib/wiki

clib 是一个 C 包管理器(非 C++),使用起来较简单。同样的,它也可以直接从 GitHub 上安装库。类似于 Node.js,它也是用 package.json 管理的。下面是一个例子:

{
  "name": "term",
  "version": "0.0.1",
  "repo": "clibs/term",
  "description": "Terminal ansi escape goodies",
  "keywords": ["terminal", "term", "tty", "ansi", "escape", "colors", "console"],
  "license": "MIT",
  "src": ["src/term.c", "src/term.h"]
}

5. poac

  • Star 数:341
  • 文档:https://doc.poac.pm/en/

别看 poac 现在 stars 数量少,它其实很适合新手使用。它具有直观且易于使用的界面(像 npm 和 Cargo 一样)。独特的是,你可以在不了解 CMake 的情况下使用 poac 开发应用程序和库,专注于学习 C++ 而不会绊倒。作者还计划实现与其他构建系统和包管理器的集成,让你能够无缝切换。

安装也是一行命令搞定:

curl -fsSL https://sh.poac.pm | bash
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

什么是包管理器,C++ 有没有像 pip、npm、gem 一样的包管理工具? 的相关文章

随机推荐