FreeBSD portsのStageDir

この記事はディストリビューション/パッケージマネージャー Advent Calendar 2013の7日目の記事です。

FreeBSDports maintainerの方向けの記事です。
最近、FreeBSDにStageDirというものが導入されました

これまでは、パッケージを作成する際には、いったん対象のportsをインストールしてからそのインストールされたものを元にパッケージを作成するという流れでした。

StageDir導入後はStageディレクトリにいったんインストールし、パッケージを作成してからそのパッケージをインストールする、という流れになります。

StageDir非対応のportsMakefileにはNO_STAGE=yesという行があります。

詳しくはhttps://wiki.freebsd.org/ports/StageDirを参照してください。(これ、wikiのトップページからたどれないんですよね、、、)

大方の人は、{pre,do,post}-installするときにStageDirにインストールする、つまり、${PREFIX}などの前に${STAGEDIR}を付ける、ということを覚えておけば良いと思います。

メリットとしては、(1)pkg-plistが作りやすくなる:

$ make makeplist

(2)既に作ったパッケージのpkg-plist漏れがチェックできる:

$ make check-orphans

あたりが挙げられるでしょうか(他にもあったら教えてください)。(一般ユーザでもパッケージが作れるようになりますが、これはメリットなのか?)

StageDir対応portsの作成テストは

$ make stage && make check-orphans && make package

で行います。

実際にStageDir対応したportsとして、ports/science/cdcl/Makefileのdiffを見てみましょう。

diff -urN cdcl.orig/Makefile cdcl/Makefile
--- cdcl.orig/Makefile	2013-10-28 16:54:55.462827000 +0900
+++ cdcl/Makefile	2013-11-29 00:26:57.613262652 +0900
@@ -2,7 +2,7 @@
 # $FreeBSD: head/science/cdcl/Makefile 327767 2013-09-20 22:48:30Z bapt $
 
 PORTNAME=	cdcl
-PORTVERSION=	5.4.7
+PORTVERSION=	5.4.8
 CATEGORIES=	science graphics
 MASTER_SITES=	http://www.gfd-dennou.org/arch/dcl/ \
 		http://dennou-h.gfd-dennou.org/arch/dcl/ \
@@ -13,17 +13,17 @@
 COMMENT=	Scientific graphic library for geoscience
 
 USES=		pkgconfig
-USE_GCC=	any
+#USE_GCC=	any
 USE_XORG=	x11 xext
 USE_GNOME=	gtk20 gdkpixbuf2
 GNU_CONFIGURE=	yes
-CONFIGURE_ARGS=	--prefix=${PREFIX} --exec-prefix=${PREFIX} --with-x --enable-shared
+GNU_CONFIGURE_PREFIX=	${STAGEDIR}${PREFIX}
+CONFIGURE_ARGS=	--with-x --enable-shared
 
 PLIST_SUB=	DCL_VERSION=${PORTVERSION:S/.//g}
 
 MAKE_JOBS_UNSAFE=	yes
 
-NO_STAGE=	yes
 .include <bsd.port.pre.mk>
 
 BINARIES=	cdclcmap cdclclr cdcldate cdcldbs cdclexec cdclfont \
@@ -38,16 +38,16 @@
 
 post-install:
 .for i in ${BINARIES}
-	${STRIP_CMD} ${PREFIX}/bin/${i}
+	${STRIP_CMD} ${STAGEDIR}${PREFIX}/bin/${i}
 .endfor
 .if !defined(NOPORTEXAMPLES)
-	@${MKDIR} ${EXAMPLESDIR}
-	(cd ${WRKSRC}/demo/ && ${COPYTREE_SHARE} \* ${EXAMPLESDIR})
+	@${MKDIR} ${STAGEDIR}${EXAMPLESDIR}
+	(cd ${WRKSRC}/demo/ && ${COPYTREE_SHARE} \* ${STAGEDIR}${EXAMPLESDIR})
 .endif
 .if !defined(NOPORTDOCS)
-	@${MKDIR} ${DOCSDIR}
+	@${MKDIR} ${STAGEDIR}${DOCSDIR}
 .for i in ${PORTDOCS}
-	${INSTALL_DATA} ${WRKSRC}/${i} ${DOCSDIR}/
+	${INSTALL_DATA} ${WRKSRC}/${i} ${STAGEDIR}${DOCSDIR}/
 .endfor
 .endif

こんな感じです。post-installの箇所に${STAGEDIR}が随所に加えられているのが見て取れるでしょうか。

ところで、GNU_CONFIGURE_PREFIXというのが加わっていますが、これはこれまでのメンテナのミスで(一体誰だ(私だ))、GNU configureで--prefix指定したい場合にはCONFIGURE_ARGSには書かずにGNU_CONFIGURE_PREFIXに書くべきだったのでした。

特に明示されてはいないようですが、今後はNO_STAGE=yesなportsは徐々に減らす意向と思われます。みなさんのメンテされているportsも徐々にStageDir対応していきましょう。