章 3. 打造 Port 快速上手篇

本節主要介紹如何來快速打造 port,然而實際應用時這快速方法可能不足,完整的 "慢速打造 Port" 的步驟在 Slow Porting 詳述。

首先取得該應用程式的原始程式碼壓縮檔(tarball),並把它放到 DISTDIR,預設路徑應該是 /usr/ports/distfiles.

這些步驟假設軟體可以直接編譯。也就是不需要任何修改就可以直接在 FreeBSD 上執行。如果需要修改,請參見Slow Porting

It is recommended to set the DEVELOPER make(1) variable in /etc/make.conf before getting into porting.

# echo DEVELOPER=yes >> /etc/make.conf

This setting enables the "developer mode" that displays deprecation warnings and activates some further quality checks on calling make.

3.1. 編寫 Makefile

最簡單的 Makefile 大概是像這樣:

# $FreeBSD: head/zh_TW.UTF-8/books/porters-handbook/book.xml 48496 2016-03-29 01:37:53Z kevlo $

MASTER_SITES=	ftp://ftp.cs.columbia.edu/archives/X11R5/contrib/

MAINTAINER=	youremail@example.com
COMMENT=	Cat chasing a mouse all over the screen

.include <bsd.port.mk>

In some cases, the Makefile of an existing port may contain additional lines in the header, such as the name of the port and the date it was created. This additional information has been declared obsolete, and is being phased out.

嗯,大致就是這樣,看看你已經領略多少了呢? 看到 $FreeBSD: head/zh_TW.UTF-8/books/porters-handbook/book.xml 48496 2016-03-29 01:37:53Z kevlo $ 這一行的話,別想太多 ,當該 port 正式進入 port tree 時, Subversion 就會自動轉換為相關字串囉。 有關這點的細節部份,可以參閱 sample Makefile 章節。

3.2. 撰寫說明檔

無論是否打算再加工做成 package,有兩個檔案是任何 port 都必須要具備的。 這兩個檔分別是 pkg-descrpkg-plist 。 他們檔名前面都有 pkg- 以跟其他檔案做區別。

3.2.1. pkg-descr

這是此 port 的詳細說明檔,請用一段或幾段文字來說明該 port 的作用

請注意,這檔_絕非_「該軟體的說明手冊」或是「如何編譯、使用該 port 的說明」! 若是從該軟體的 README 或 manpage 直接複製過來的話,請注意。他們常常不是正確的 port 描述或是格式並不適合。例如,manpage會對齊空白,這用monospace字型來看會特別糟糕。

A well-written pkg-descr describes the port completely enough that users would not have to consult the documentation or visit the website to understand what the software does, how it can be useful, or what particularly nice features it has. Mentioning certain requirements like a graphical toolkit, heavy dependencies, runtime environment, or implementation languages help users decide whether this port will work for them.

Include a URL to the official WWW homepage. Prepend one of the websites (pick the most common one) with WWW: (followed by single space) so that automated tools will work correctly. If the URI is the root of the website or directory, it must be terminated with a slash.

If the listed webpage for a port is not available, try to search the Internet first to see if the official site moved, was renamed, or is hosted elsewhere.

這是 pkg-descr 內容的例子 :

This is a port of oneko, in which a cat chases a poor mouse all over
the screen.

WWW: http://www.oneko.org/

3.2.2. pkg-plist

這是該 port 所會裝的所有檔案清單,另外因為 package 會由這清單所產生,因此也被稱為『"packing list (打包清單)"』。路徑是相對於安裝的 prefix (通常是 /usr/local )。



關於 packing list 方面,可以詳閱 pkg-create(8) manual page 。

建議清單內的檔名,依照字母順序作排序,那麼下次要升級時, 會比較清楚、方便來更新這份清單。

手動產生這份清單實在太苦了。尤其若該 port 會裝一大堆檔案的話, 請多善用 自動產生 packing list 會比較省時省力唷。

只有在一種情況下可以省略 pkg-plist 檔: 若安裝的 port 相當單純,只有裝一些檔案,那麼可以在 Makefile 內改用 PLIST_FILES 來取代。 比如,可以在上述的 oneko port 內不必附上 pkg-plist ,而只需在 Makefile 內加入下列幾行:

PLIST_FILES=	bin/oneko \
		man/man1/oneko.1.gz \
		lib/X11/app-defaults/Oneko \
		lib/X11/oneko/cat1.xpm \
		lib/X11/oneko/cat2.xpm \

Usage of PLIST_FILES should not be abused. When looking for the origin of a file, people usually try to grep through the pkg-plist files in the ports tree. Listing files in PLIST_FILES in the Makefile makes that search more difficult.

If a port needs to create an empty directory, or creates directories outside of ${PREFIX} during installation, refer to Cleaning Up Empty Directories for more information.

然而,使用這個方法列出 port 的檔案和目錄是必須付出代價: 不能使用 pkg-create(8)Expanding Package List with Keywords 描述的關鍵字。 因此,這招僅適用於較簡單的 port ,以及簡化該 port 的作法。 此外,這招還有一個好處:可以減少 ports collection 的整體檔案總數。 所以,在考慮是否要用 pkg-plist 之前, 可以先斟酌這個替代方案看看。

後面會介紹到如何運用 pkg-plistPLIST_FILES 這些技巧以因應更複雜的狀況

3.3. 產生 checksum 檔

只要打 make makesum 就好了, 接下來就會自動產生相對應的 distinfo 檔了唷 。

3.4. 測試 Port

接下來,必須檢驗是否有符合 port 的遊戲規則,包括打包該 port 為 package。 以下有幾個需要確認的重要地方:

  • 若該 port 沒裝的東西,不要列在 pkg-plist 內。

  • 若該 port 有裝的東西,請務必列在 pkg-plist 內。

  • The port can be installed using the install target. This verifies that the install script works correctly.

  • The port can be deinstalled properly using the deinstall target. This verifies that the deinstall script works correctly.

  • The port does not access network resources after the fetch target. This is important for package builders, such as ports-mgmt/poudriere.

  • Make sure that make package can be run as a normal user (that is, not as root). If that fails, NEED_ROOT=yes must be added to the port Makefile.

Procedure: 建議的測試順序

  1. make stage

  2. make check-orphans

  3. make package

  4. make install

  5. make deinstall

  6. pkg add package-filename

  7. make package (as user)


Thorough automated testing can be done with ports-mgmt/tinderbox or ports-mgmt/poudriere from the Ports Collection. These applications maintain jails where all of the steps shown above can be tested without affecting the state of the host system.

3.5. 以 portlint 來作檢查 Port

請用 portlint 來檢查該 port 是否有遵循我們的規則。 ports-mgmt/portlint 是 ports collection 的其中一個套件。 它主要可以用來檢驗 Makefile 內容是否正確以及 package 是否有正確命名。

3.6. 提交新的 Port

提交新的 Port 前,請閱讀 DOs and DON’Ts 章節。

現在你很高興終於打造出 port 來囉,唯一剩下要做的就是把它正式放到 FreeBSD ports tree 內,才能讓每個人都能分享使用這個 port。 我們不需要 work 目錄或是檔名像 pkgname.tgz 的 package ,請現在刪除他們。

Next, build the shar(1) file. Assuming the port is called oneko, cd to the directory above where the oneko directory is located, and then type: shar find oneko > oneko.shar

To submit oneko.shar, use the bug submit form (category Ports Tree). Add a short description of the program to the Description field of the PR (perhaps a short version of COMMENT), and do not forget to add oneko.shar as an attachment.

Giving a good description in the summary of the problem report makes the work of port committers a lot easier. We prefer something like "New port: category/portname__short description of the port" for new ports. Using this scheme makes it easier and faster to begin the work of committing the new port.

再次強調一點:不必附上原始 source 的 distfile ,也就是 work 目錄。 同時,也不必附上 make package 時產生的 package。新的 port 請使用 shar(1) ,不要用 diff(1)

送出 port 之後,請耐心等候佳音。 有時候可能需要等個幾天或幾個月時間,才會在 FreeBSD ports tree 上正式出現。 等待中的 port PR 清單可以在 http://www.FreeBSD.org/cgi/query-pr-summary.cgi?category=ports 查閱。

在看過新的 port 之後,如果需要的話,我們會回覆您,然後會將它提交到 port tree 。 您的大名會被列在 Additional FreeBSD Contributors 列表上,以及其他檔案中。

最後修改於: December 11, 2021 由 Sergio Carlavilla Delgado