Documentation index

入力データの順序を固定する(Stable order for inputs)

ソフトウェアをビルドするとき、複数の入力を同時に処理しなければならないとしたら、何回ビルドしてもその順番が同じになるようにしなければなりません。

例えば、あるディレクトリのコンテンツをまとめたアーカイブを作成する場合があるでしょう。 ほとんどのファイルシステムは、ディレクトリに含まれるファイルを列挙するとき、常に同じ順序になることを保証していません。

Makefile の場合

次の Makefile が生成する結果は再現性のないビルド1 です。

SRCS = $(wildcard *.c)
tool: $(SRCS:.c=.o)
	$(CC) -o $@ $^

解決方法は2つあります。

(a) 全ての入力ファイルを明示的に列挙して、同じ順番で処理されるようにする。

SRCS = util.c helper.c main.c
tool: $(SRCS:.c=.o)
	$(CC) -o $@ $^

(b) 入力ファイルを並び替える。

SRCS = $(sort $(wildcard *.c))
tool: $(SRCS:.c=.o)
	$(CC) -o $@ $^

ロケールに関連する問題

入力を並び替えるとしても、システムのロケールに依存しないようにしなければなりません。 ロケールによっては大文字と小文字を区別しない場合があるので難しい問題です。

例えば、tar はディレクトリを下に向かって降りていくとき、初期設定ではファイルシステムの返す順序に従うようになっています。

$ tar -cf archive.tar src

findsort を組み合わせればいいのですが、次のコード例ではまだロケールによる影響を取り除けていません。

$ find src -print0 | sort -z |
    tar --no-recursion --null -T - -cf archive.tar

並び順が変化して驚かされたくないなら、ファイルを並び替えるときにロケールを指定するようにします。

$ find src -print0 | LC_ALL=C sort -z |
    tar --no-recursion --null -T - -cf archive.tar

Tar などでアーカイブを作成する 場合だけでなく、メタデータを埋め込むような場合も変更が必要になります。

  1. GNU Make はバージョン 3.82 から ワイルドカード関数 の出力を並び替えるようになりました。 


Documentation index

Follow us on Twitter @ReproBuilds, Mastodon @reproducible_builds@fosstodon.org & Reddit and please consider making a donation. • Content licensed under CC BY-SA 4.0, style licensed under MIT. Templates and styles based on the Tor Styleguide. Logos and trademarks belong to their respective owners. • Patches welcome via our Git repository (instructions) or via our mailing list. • Full contact info