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

往期回顾:通过git bisect快速定位大型工程中的问题

MacPorts 与 Homebrew

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

MacPorts 与 Homebrew 相比有什么优点呢?

首先,MacPorts 的包数量特别多

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

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

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

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

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

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

说了这么多,让我们回归正题介绍一下 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.gzrmd160: 94aa50f60099fdb001da4903bba2be538d109c15sha256: 5686e61100599c309ce03535f9899a5a3d94a82cc08d10718e2cd73ad3dc28afsize: 1075728https://getdnsapi.net/dist/getdns-1.5.1.tar.gzhttps://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打包过程简介

MacPorts打包过程简介相关推荐

  1. 游戏打包过程枯燥且繁琐,如何提升打包效率?

    简介:为了简化业务流程,实现高性能和成本优化,鲸旗游戏最终选择使用阿里云 Serverless 函数编排与函数计算的方式来执行打包操作,完美解决痛点. 作者:折松,阿里云解决方案架构师 深圳市鲸旗天下 ...

  2. Pyinstaller 详解多种打包过程(去坑,填坑)。

    前言 本篇文章,详细介绍pyinstaller多种打包过程.去坑,填坑. 一.安装Pyinstaller 1)使用下面的命令即可安装(win10) pip install pyinstaller 二. ...

  3. 【Java 虚拟机原理】动态字节码技术 | Dalvik ART 虚拟机 | Android 字节码打包过程

    文章目录 一.动态字节码技术 二.Dalvik & ART 虚拟机 三.Android 字节码打包过程 总结 一.动态字节码技术 动态字节码技术 就是在 运行时 , 动态修改 Class 字节 ...

  4. UA MATH565C 随机微分方程II Wiener过程简介

    UA MATH565C 随机微分方程II Wiener过程简介 Wiener过程的简单性质 Wiener过程的定义 在上一讲我们定义了WtW_tWt​: dWt=ηtdt⇔Wt=∫0tηsdsdW_t ...

  5. AI:基于计算机视觉和语音识别案例项目打包过程记录20181226-19

    AI:基于计算机视觉和语音识别案例项目打包过程记录20181226-19 基于计算机视觉和语音识别案例项目打包过程 521 INFO: PyInstaller: 3.3.1 521 INFO: Pyt ...

  6. MapxTreme2008的打包过程

    最近帮朋友做了个小的gis系统,用到了mapXtreme2008,当然是破解的.开发基本上没什么难度,只是打包时遇到了些问题.开始以为只要把破解的许可文件连同mapinfo的库文件一起打包就可以了,但 ...

  7. gradle编译打包过程 之 ProcessAndroidResources的源码分析

    首先,如何查看gradle源码,我们在项目里依赖com.android.tools.build:gradle即可,如下: compile gradleApi() compile 'com.androi ...

  8. webpack打包过程如何调试?

    本文适用于已经会使用webpack的前端开发人员,但是想进一步了解webpack细节和进阶. 首先请读者按照我前一篇文章 Webpack 10分钟入门介绍的步骤,在本地搭建一个webpack的hell ...

  9. Android APK 打包过程 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

最新文章

  1. 浅谈jsp的7个动作
  2. 测试人员:如何品味软件的品位
  3. linux设置账号权限设置,Linux账号管理与ACL权限设置
  4. class unity 定义类_Unity 游戏框架搭建 2019 (二十五) 类的第一个作用 与 Obselete 属性...
  5. 解决:Caused by: java.lang.UnsupportedOperationException: null
  6. 【转载保存】webCollector使用教程
  7. 风生水起:Linux的突破口在中国?
  8. JSON——入门语法、对象、数组
  9. 模板语法-插入文本//模板语法-插入标签//模板语法-双花括号//模板语法-向标签属性中插入数据
  10. Linux arm 下载程序,arm-linux—gcc如何下载安装
  11. CentOS6.5安装python2.7.6(慎重升级)
  12. Idea tomcat控制台日志乱码
  13. icd植入是大手术吗_手术达人|杨兵:ICD植入术一例
  14. 在Realview MDK中添加自己的FLASH编程算法
  15. 2021京东618活动脚本App和电脑版最新版(建议使用app版)
  16. 一个前端资源站 http://www.bootcss.com/
  17. html+js 简单静态网页设计
  18. 华农计算机软件就业,华农17届就业报告出炉!毕业生月薪集中在4-6k!
  19. 使用get-pip.py 安装python2 的pip
  20. Flink Asynchronous IO异步操作

热门文章

  1. python网络爬虫代理服务器_python爬虫如何抓取代理服务器
  2. 如何调试Android语音功能,Android如何添加语音功能
  3. 基于.net的ORM常用框架说明
  4. Load_balance函数情景分析
  5. getElementsByTagName的详解
  6. 钓鱼网站诈骗及其常见类型
  7. Human-level concept learning through probabilistic program induction
  8. Latex设置表格字体大小
  9. P5886 Hello, 2020!
  10. css zindex七阶,CSSz-index的层级关系优先级概念说明