MacPorts打包过程简介
本文主要为大家介绍一下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打包过程简介相关推荐
- 游戏打包过程枯燥且繁琐,如何提升打包效率?
简介:为了简化业务流程,实现高性能和成本优化,鲸旗游戏最终选择使用阿里云 Serverless 函数编排与函数计算的方式来执行打包操作,完美解决痛点. 作者:折松,阿里云解决方案架构师 深圳市鲸旗天下 ...
- Pyinstaller 详解多种打包过程(去坑,填坑)。
前言 本篇文章,详细介绍pyinstaller多种打包过程.去坑,填坑. 一.安装Pyinstaller 1)使用下面的命令即可安装(win10) pip install pyinstaller 二. ...
- 【Java 虚拟机原理】动态字节码技术 | Dalvik ART 虚拟机 | Android 字节码打包过程
文章目录 一.动态字节码技术 二.Dalvik & ART 虚拟机 三.Android 字节码打包过程 总结 一.动态字节码技术 动态字节码技术 就是在 运行时 , 动态修改 Class 字节 ...
- UA MATH565C 随机微分方程II Wiener过程简介
UA MATH565C 随机微分方程II Wiener过程简介 Wiener过程的简单性质 Wiener过程的定义 在上一讲我们定义了WtW_tWt: dWt=ηtdt⇔Wt=∫0tηsdsdW_t ...
- AI:基于计算机视觉和语音识别案例项目打包过程记录20181226-19
AI:基于计算机视觉和语音识别案例项目打包过程记录20181226-19 基于计算机视觉和语音识别案例项目打包过程 521 INFO: PyInstaller: 3.3.1 521 INFO: Pyt ...
- MapxTreme2008的打包过程
最近帮朋友做了个小的gis系统,用到了mapXtreme2008,当然是破解的.开发基本上没什么难度,只是打包时遇到了些问题.开始以为只要把破解的许可文件连同mapinfo的库文件一起打包就可以了,但 ...
- gradle编译打包过程 之 ProcessAndroidResources的源码分析
首先,如何查看gradle源码,我们在项目里依赖com.android.tools.build:gradle即可,如下: compile gradleApi() compile 'com.androi ...
- webpack打包过程如何调试?
本文适用于已经会使用webpack的前端开发人员,但是想进一步了解webpack细节和进阶. 首先请读者按照我前一篇文章 Webpack 10分钟入门介绍的步骤,在本地搭建一个webpack的hell ...
- Android APK 打包过程 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
最新文章
- 配置Haproxy增加日志记录功能
- 参观云栖小镇体会_我院留学生赴云栖小镇参观学习
- Python图像处理库PIL从入门到精通
- Spring配置汇总
- qt交叉编译环境搭建方法
- mk-parallel-dump 实验
- mac解压错误22无效的参数_看看PHP 7.3新版本中的JSON错误处理
- 计算器计算经纬距离_造价人如何熟练运用计算器来做题?
- Linux内核模块(一)
- 局域网或者本地开发https自签名证书解决办法
- Calendar根据日期获取年份和周、当前周的所有日期
- 轻松停车入位 淑女节女司机5大用车指南
- 还儿童一个健康上网环境,正式开启我的路由器URL网址白名单之旅
- 《R语言数据挖掘》读书笔记:三、分类
- Codeforces Round #571 (Div. 2)
- Vue2.0开发之——Vue基础用法-axios(29)
- QT的QTreeWidget节点触发事件(一)
- 小学阅读方法六种_小学写作手法六种
- 最全电商分类信息(06)
- JAVA压缩JS或CSS文件
热门文章
- LR多分类与softmax分类
- spca5xx-LE in S3C2410
- 阿贝云免费云服务器,云虚拟主机
- 阅读笔记:python 编程从入门到实践
- 串口调试助手源程序及编程详细过程
- 实战贴:GUI STemWin在小熊派上的移植(显示很漂亮、很细腻,棒!)
- 根据父母身高预测儿子身高C语言代码
- vue ui报错 Couldn‘t parse bundle asset “C:\Users\cqq\Desktop\vuex\vuex_demo\dist\js\chunk-vendors.js“.
- 利用sklearn计算决定系数R2
- 向mycat中插入数据的时候,一定要将字段写完整