🛒

Guixのパッケージを作ってみる

2021/07/21に公開

はじめに

最近Guixを使っています。
Packageの作り方が、少し(ほんと少し)わかったので作り方を記載します。

参考にしたドキュメントは以下

つくるパッケージについて

最初なので、単純なものを作ります。
やりたいことは以下。

  1. guix-hello-packageからコードをclone
  2. ローカルで作ったpatchを当てて、ビルド

guix-hello-packageに置いたコード(hello.c,Makefile)は以下です。

hello.c
#include <stdio.h>

int main(void){
	puts("hello");
	return 0;
}
Makefile
hello: hello.c
	gcc -o hello hello.c

DESTDIR:=
PREFIX:=out
bindir:=$(DESTDIR)$(PREFIX)/bin
.PHONY: install
install: hello
	mkdir -p $(bindir)
	cp $^ $(bindir)

スクリプトの作成

以下のようにhello.scmを作成しました。
2.1.1 A “Hello World” packageに記載されているものと結構似ています。

hello.scm
(use-modules 
             (guix packages)
             (guix download)
             (guix utils)
             (guix git-download)
             (guix build-system gnu)
             (gnu packages)
             (guix licenses))

(package
  (name "hello")
  (version "0.01")
  (source (origin
            (method git-fetch) ;; Note 1
	    (uri (git-reference
		   (url "https://github.com/SaitoYutaka/guix-hello-package.git")
		   (commit "cdcee718e3d614744b16717b8b1120eff9a6fc25")))
            (sha256
             (base32
	       "0bnci0jgncasr7d7lx8m52nbz49scb7lhr5gf5xddrrz9ywfnqsz"))
	    (patches (search-patches
		      "hellopatch.patch")) ;; Note 2
	    ))
  (build-system gnu-build-system)
  (arguments
    `(#:make-flags (list (string-append "PREFIX=" (assoc-ref %outputs "out")))
      #:phases (modify-phases %standard-phases
      (delete 'configure)
      (delete 'check) ;; Note 3
)))
  (synopsis "Hello sample")
  (description
    "sample")
  (home-page "https://github.com/SaitoYutaka/guix-hello-package")
  (license gpl3+))

上記スクリプトのコメントで書いたNote1,Note2,Note3について
以下に説明を記載します。

Note1 git-fetch

  (source (origin
            (method git-fetch) ;; Note 1
	    (uri (git-reference
		   (url "https://github.com/SaitoYutaka/guix-hello-package.git")
		   (commit "cdcee718e3d614744b16717b8b1120eff9a6fc25")))

今回はgithubからコードをcloneしたかったので
git-fetchを使いました。

Note2 git-fetch

	    (patches (search-patches
		      "hellopatch.patch")) ;; Note 2
	    ))

git clone後にパッチを当てます。
パッチは以下のようなものを用意しました。

hellopatch.patch
diff --git a/hello.c b/hello.c
index 9346c53..abc5226 100644
--- a/hello.c
+++ b/hello.c
@@ -1,7 +1,7 @@
 #include <stdio.h>
 
 int main(void){
-	puts("hello");
+	puts("hello guix.");
 	return 0;
 }

Note3 ビルドシーケンスの修正

  (build-system gnu-build-system)
  (arguments
    `(#:make-flags (list (string-append "PREFIX=" (assoc-ref %outputs "out")))
      #:phases (modify-phases %standard-phases
      (delete 'configure)
      (delete 'check) ;; Note 3

ビルドシーケンスを修正しまします。
詳細はここ

gnu-build-systemをデフォルトのまま使用すると以下のコマンドを実行するようです。

# gnu-build-systemは以下の順で実行する
$ ./configure
$ make
$ make check
$ make install

guix-hello-packageを見ると
わかるのですが、この中にはconfigureスクリプトはありません。また、
Makefileの中にcheckターゲットも記載していません。
なので、configure, make checkを実行しないようにします。

      (delete 'configure)
      (delete 'check) ;; Note 3

ここでもう一度Makefileを確認します。
この中で、インストール先が$(DESTDIR)$(PREFIX)/binとなっています。

Makefile
hello: hello.c
	gcc -o hello hello.c

DESTDIR:=
PREFIX:=out
bindir:=$(DESTDIR)$(PREFIX)/bin
.PHONY: install
install: hello
	mkdir -p $(bindir)
	cp $^ $(bindir)

Makefile内で定義している変数PREFIXを以下で変更します。

    `(#:make-flags (list (string-append "PREFIX=" (assoc-ref %outputs "out")))

詳細は2.1.3.5 Build system arguments

このようにすると、以下のようにコマンドが実行されます。

# ./configure は実行されない
$ make
# make check は実行されない
$ make PREFIX=/....../out  install # .....のフルパス名は謎

パッケージのインストール

適当なフォルダにhello.scmhellopatch.patchを置きます。
ここでは /home/yutaka/temp/sampleに置きます。

$ pwd
/home/yutaka/temp/sample
$ ls
hello.scm hellopatch.patch

環境変数 GUIX_PACKAGE_PATHにここのパスを設定します。
ドキュメントGUIX_PACKAGE_PATH

$ export GUIX_PACKAGE_PATH=/home/yutaka/temp/sample

hello.scmの中に以下の記載がありますが、
ここでhellopatch.patchを探す場所が、環境変数
GUIX_PACKAGE_PATHに記載されたパスになります。

	    (patches (search-patches
		      "hellopatch.patch")) ;; Note 2
	    ))

これで準備が整ったのでインストールを実行します。
コマンドはguix package -f [ファイル名]です。

$ guix package  -f hello.scm
The following package will be installed:
   hello 0.01

substitute: updating substitutes from 'https://ci.guix.gnu.org'... 100.0%
The following derivations will be built:
   /gnu/store/7rnbpdv39509f5dsz6g6lz2ykpq9fpry-profile.drv
   /gnu/store/n21yz8rs68x0vwqa516xnd7snxi67wsm-hello-0.01.drv
   /gnu/store/nlwbnd5wsxfyxn2b0iq7zvlb039d73ax-git.tar.xz.drv

building /gnu/store/nlwbnd5wsxfyxn2b0iq7zvlb039d73ax-git.tar.xz.drv...
building /gnu/store/n21yz8rs68x0vwqa516xnd7snxi67wsm-hello-0.01.drv...
building CA certificate bundle...
listing Emacs sub-directories...
building fonts directory...
generating GLib schema cache...
creating GTK+ icon theme cache...
building cache files for GTK+ input methods...
building directory of Info manuals...
building database for manual pages...
building XDG desktop file cache...
building XDG MIME database...
building profile with 18 packages...

実行してみます。
ちゃんとパッチが適用されています。

$ hello 
hello guix.
$ 

まとめ

Guixをさわりはじめて、そんなに長くないですが、
意外とドキュメントがしっかりしている印象です。
下記ドキュメントを探したらなんとかなります。

Discussion