You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Fix compiler when using ERL_COMPILER_OPTIONS=deterministic #762
According to the Erlang docs, Using the deterministic options will:
Omit the options and source tuples in the list returned by Module:module_info(compile)
Currently, the Surface compiler uses module_info/1 to retrieve the related source file in order to generate JS hooks. Instead, we could add/retrieve this information directly to/from the beam chunks as an custom attribute so we're able to use deterministic.
The current approach assumes something more than not having ERL_COMPILER_OPTIONS=deterministic, namely that the source given by module_info still exists, which is not the case when building each mix app in ephemeral sandboxes like nix does by default.
See in nix the source is deterministically in /build/source/, but actually exists only during the build of the mix app:
So that by the time the dependency (Bonfire.UI.Me.Stickyheader) is used (through $ERL_LIBS), its /build/source/ is long gone (actually it's now the /build/source/ of the current mix app using that dependency).
When using nixpkgs's buildMix, a workaround is to build into $out/src/ instead of /build/source/, so that module_info returns a path inside $out, which, being the final output path of the package into the Nix store, still exists when building dependent packages:
buildMix{erlangDeterministicBuilds=false;# Explanation: sadly disabling erlangDeterministicBuilds is not enough# for `mix compile.surface` to work across packages, as it:# - needs to access the content of the source path of the dependencies,# - and, uses as source path the actual path where the dependencies were built.# Since buildMix's installPhase only copies $src into $out/src,# that is not enough: module_info/1 will return /build/source instead of $out/src,# so build into $out/src, which will remain reachable after the build.# Issue: https://github.com/surface-ui/surface/issues/762#issuecomment-3577030748postUnpack=previousArgs.postUnpackor""+'' mkdir -p $out mv $sourceRoot $out/src sourceRoot=$out/src src=$(mktemp -d) '';postInstall=previousArgs.postInstallor""+'' src=$out/src rm -rf _build '';[…snip…]}
Which now records an existing source:, enabling compile.surface to correctly generate all the .hooks.js of the dependencies:
Activity
ju1m commentedon Nov 25, 2025
The current approach assumes something more than not having
ERL_COMPILER_OPTIONS=deterministic, namely that thesourcegiven bymodule_infostill exists, which is not the case when building eachmixapp in ephemeral sandboxes likenixdoes by default.See in
nixthesourceis deterministically in/build/source/, but actually exists only during the build of themixapp:So that by the time the dependency (
Bonfire.UI.Me.Stickyheader) is used (through$ERL_LIBS), its/build/source/is long gone (actually it's now the/build/source/of the currentmixapp using that dependency).ju1m commentedon Nov 25, 2025
When using
nixpkgs'sbuildMix, a workaround is to build into$out/src/instead of/build/source/, so thatmodule_inforeturns a path inside$out, which, being the final output path of the package into the Nix store, still exists when building dependent packages:Which now records an existing
source:, enablingcompile.surfaceto correctly generate all the.hooks.jsof the dependencies:beamPackages: build in $out/src and disable erlangDeterministicBuilds…
beamPackages: build in $out/src and disable erlangDeterministicBuilds…
beamPackages: build in $out/src
beamPackages: build in $out/src
beamPackages: build in $out/src
beamPackages: build in $out/src
beamPackages: build in $out/src
beamPackages.buildMix: compile non-deterministic deps in $out/src