MacPorts打包过程简介

本文主要为你们介绍一下MacPorts的打包过程。

MacPorts 与 Homebrew

Homebrew 相信不少人都据说过,它是 macOS 上用户最多的包管理软件。但 macOS 上的包管理软件并不是只有 Homebrew 一家,MacPorts、Nix 也是各有其独特之处的 macOS 包管理器。api

MacPorts 与 Homebrew 相比有什么优势呢?bash

首先,MacPorts 的包数量特别多微信

根据 repology 统计,Homebrew 的官方源大约有四千六百个包,与之相比 MacPorts 社区维护了足足一万一千多个官方包。不过因为包数量过多和缺乏维护者,MacPorts 在软件更新速度上要比 Homebrew 慢很多。框架

其次,MacPorts 对于老版本的 macOS 提供了良好的支持。运维

Homebrew 如今已经要求 macOS 10.12 及以上版本的系统才能够正常安装使用,而 MacPorts 在社区成员的支持下至今仍在提供低至 Mac OS X 10.5 系统的支持,不少经常使用的包例如 curl、perl 均可以直接安装二进制包。curl

最后,MacPorts 和传统包管理软件同样要求使用 root 权限执行包的安装、卸载等操做。工具

或许对于不少人来讲,每次安装包都要加上 sudo 并输一次密码比较繁琐,但只有这样才能确保 MacPorts 管理的文件只有 root 用户有权限修改。笔者认为,保护好包管理目录,对于管理大量 Mac 设备的系统管理员来讲十分重要。网站

若是任何程序都能随意在包管理的路径下建立、删除文件,就有可能因第三方程序的修改,出现包不可用或安装包时文件被覆盖的状况。ui

说了这么多,让咱们回归正题介绍一下 MacPorts 是怎么从源码编译出一个传统的使用 autoconf 的上游项目的吧。

包“配方”(Portfile)

在 MacPorts 每一个包都必须有一个对应的 Portfile 文件。这个文件说明了包的源码从哪里获取、编译须要哪些工具、依赖的库、编译参数等等。接下来我会以 getdns 这个包为例介绍一下从源码的下载到执行配置脚本、编译、打包和安装的全过程和对应的 Portfile 写法。

下载和解压源码

Portfile 只是一个配方,包的源码仍是须要从网上下载。下面这两行代码指定了包的主页和源码 tar 包的下载位置。

homepage            https://getdnsapi.net/master_sites        ${homepage}dist/复制代码

name                getdnsversion             1.5.1复制代码

MacPorts 默认会下载 ${name}-${version}.tar.gz 文件,包名和包版本由上面两行代码定义。使用 port distfiles getdns 命令能够查看要下载的文件名、保存路径、Portfile 中记录的哈希值、文件大小和下载文件的 URL。哈希值和文件大小是为了保证上游或第三方没有修改包的内容,这样能够避免网站被黑客攻击后文件被恶意替换的问题。

--->  Distfiles for getdns[getdns-1.5.1.tar.gz] /opt/local/var/macports/distfiles/getdns/getdns-1.5.1.tar.gz rmd160: 94aa50f60099fdb001da4903bba2be538d109c15 sha256: 5686e61100599c309ce03535f9899a5a3d94a82cc08d10718e2cd73ad3dc28af size: 1075728  https://getdnsapi.net/dist/getdns-1.5.1.tar.gz  https://distfiles.macports.org/getdns/getdns-1.5.1.tar.gz复制代码

以 getdns 为例,MacPorts 会从软件的官网或 MacPorts 的官方镜像(有两个在中国哦)下载这个 tar 包到 /opt/local/var/macports/distfiles/getdns/ 目录下。下载成功后会用 Portfile 中记录的 checksums 校验文件,经过后才会解压下载的 tar 包。解压成功的话进入下一步执行配置脚本。

checksums           rmd160  94aa50f60099fdb001da4903bba2be538d109c15 \                    sha256  5686e61100599c309ce03535f9899a5a3d94a82cc08d10718e2cd73ad3dc28af \                    size    1075728复制代码

使用了 autoconf 框架的软件在编译时须要运行 ./configure 命令才能开始用 make 编译。但 MacPorts 并无使用默认的 /usr/local 目录,而是为了和用户自行安装的软件隔离开使用了 /opt/local 前缀。因此 MacPorts 在执行这个脚本时会默认加上 --prefix=/opt/local 参数来调整安装目录。同时为了让编译器能找到依赖库的头文件和库文件,MacPorts 会配好 CPPFLAGS、LDFLAGS 等环境变量。最后,MacPorts 会将 Portfile 中指定的配置参数加到 --prefix 以后,这能够用来开启或关闭一些功能。

configure.args      --enable-stub-only \                    --with-libevent \                    --without-libidn复制代码

编译

编译在这个例子里很是简单,只要在源码目录下执行 make 命令,MacPorts 就会默认开启并行编译,即添加 -jN 参数,N 为 port 命令根据 CPU 和内存自动判断的并行任务数。

make -j2复制代码

打包与安装

编译成功后进入 destroot 阶段,这个阶段 MacPorts 仍然执行 make 命令,但带上了 install 和 DESTDIR 两个参数。make install 用于把编译好的文件安装到指定的目录。DESTDIR=... 则表示不要直接把文件安装到以前配置的 prefix 下,而是安装到 MacPorts 临时建立的目录下。

make -w install DESTDIR=/opt/local/var/macports/build/...复制代码

经过指定临时建立的 DESTDIR 目录,MacPorts 在“安装”成功后能够直接用 tar 命令把二进制包打到 /opt/local/var/macports/software/getdns/getdns-1.4.2_1.darwin_17.x86_64.tbz2 里。MacPorts 官方提供的二进制包就是用这种方式生成并在符合协议规范的前提下上传到镜像站上供用户下载的。

最后,MacPorts 会将打好的二进制包解压到 /opt/local 下,并清理打包过程当中产生的临时文件。这样就完成了 getdns 的安装。

—end—

排版/许晔

文/SRE

本文首发于小米运维微信公众号,原文请戳连接MacPorts打包过程简介

相关文章
相关标签/搜索