Compilation with GHC was non-deterministic prior to version 8.0.2. Compiling with the same flags, sources, and environment could produce incompatible binary objects.
Non-deterministic compilation causes several problems. Non-deterministic interface files result in slower incremental builds because of unnecessary recompilation. Distributed build systems, such as Buck or Bazel, cannot reliably cache non-deterministic object files, negating the primary benefit of distributed compilation. Non-determinism results in unstable symbol names, making code hot-swapping difficult. Non-deterministic output forces packagers of binary distributions such as Debian to waste resources recompiling after a trivial change and also makes it impossible to verify if a binary was built from the given code.
During the past couple of months I tested GHC for non-determinism on itself and Stackage, developed a non-determinism test suite, and systematically audited GHC’s internals to ensure that compilation is deterministic in GHC 8.0.2. In this talk I will discuss the causes of non-determinism, how I addressed them, and how we can keep GHC deterministic going forward.