If building your software requires processing several inputs at once, make sure the order is stable across builds.
A typical example is creating an archive from the content of a directory. Most filesystems do not guarantee that listing files in a directory will always result in the same order.
Makefile will result in unreproducible
SRCS = $(wildcard *.c) tool: $(SRCS:.c=.o) $(CC) -o $@ $^
a) List all inputs explicitly and ensure they will be processed in that order.
SRCS = util.c helper.c main.c tool: $(SRCS:.c=.o) $(CC) -o $@ $^
b) Sort inputs:
SRCS = $(sort $(wildcard *.c)) tool: $(SRCS:.c=.o) $(CC) -o $@ $^
Watch out for locale-related issues
When sorting inputs, one must ensure that the sorting order is not affected by the system locale settings. Some locales will not distinguish between uppercase and lowercase characters.
tar will by default use the filesystem order when
$ tar -cf archive.tar src
A solution is to use
sort but the following might still
have differences when run under different locales:
$ find src -print0 | sort -z | tar --no-recursion --null -T - -cf archive.tar
The locale used to sort files must be specified to avoid any surprises:
$ find src -print0 | LC_ALL=C sort -z | tar --no-recursion --null -T - -cf archive.tar
This might not be the only change required for Tar and other archive formats as they usually embed more metadata problems.