parallel compilation creates different output binaries
Summary
Parallel compilation creates different output binaries. The output varies depending on the number of input files and the -j argument to ghc. In this test case ghc -j1 , -j2 and -j4 differ with multiple files, but do not differ with just one file. Build machines may have different number of CPUs, so for reproducible builds it is necessary to avoid the output depending on it.
Steps to reproduce
While verifying packages of the OpenSUSE distribution for reproducibility ( See https://reproducible-builds.org/ ), xmonad and texmath were found to have differences depending on the available CPUs. See https://rb.zq1.de/compare.factory-20230402/diffs/xmonad-compare.out and https://rb.zq1.de/compare.factory-20230402/diffs/texmath-compare.out for diffoscope output.
The following is a reduced testcase:
File: A.hs
module A where
a :: Int
a = 3
File: B.hs
module B where
b :: Int
b = 2
File: C.hs
module C where
c :: Int
c = 2
File: D.hs
module D where
d :: Int
d = 2
File: E.hs
module E where
e :: Int
e = 2
File: Main.hs
import A
import B
import C
import D
import E
main = print (a + b + c + d + e)
File: Single.hs
main = print (3 + 5)
> ghc -j1 Main.hs -o Main.1
[1 of 7] Compiling A ( A.hs, A.o ) [Missing object file]
[2 of 7] Compiling B ( B.hs, B.o ) [Missing object file]
[3 of 7] Compiling C ( C.hs, C.o ) [Missing object file]
[4 of 7] Compiling D ( D.hs, D.o ) [Missing object file]
[5 of 7] Compiling E ( E.hs, E.o ) [Missing object file]
[6 of 7] Compiling Main ( Main.hs, Main.o ) [Missing object file]
[7 of 7] Linking Main.1 [Objects changed]
> ghc -j2 Main.hs -o Main.2
[7 of 7] Linking Main.2 [Objects changed]
> ghc -j4 Main.hs -o Main.4
[7 of 7] Linking Main.4 [Objects changed]
> ghc -j1 Single.hs -o Single.1
[1 of 2] Compiling Main ( Single.hs, Single.o ) [Missing object file]
[2 of 2] Linking Single.4
> ghc -j4 Single.hs -o Single.4
[2 of 2] Linking Single.4
> diff -rs Single.1 Single.4
Files Single.1 and Single.4 are identical
> diff -rs Main.1 Main.4
Binary files Main.1 and Main.4 differ
> diff -rs Main.2 Main.4
Binary files Main.2 and Main.4 differ
> diffoscope Main.1 Main.4 >Main.diffoscope.txt
Expected behavior
The same output independent of the ghc -j argument.
Environment
- GHC version used: 9.4.5
Optional:
- Operating System: OpenSUSE Tumbleweed
- System Architecture: x86_64