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打包過程簡介

相關文章
相關標籤/搜索