-
-
Notifications
You must be signed in to change notification settings - Fork 18.1k
Description
Describe the bug
When cross-compiling haskell packages custom ghc-options are not passed to the compiler. This includes those passed in:
nixpkgs/pkgs/development/haskell-modules/generic-builder.nix
Lines 232 to 235 in 4ec0020
| (optionalString (enableSharedExecutables && stdenv.isLinux) "--ghc-option=-optl=-Wl,-rpath=$out/${ghcLibdir}/${pname}-${version}") | |
| (optionalString (enableSharedExecutables && stdenv.isDarwin) "--ghc-option=-optl=-Wl,-headerpad_max_install_names") | |
| (optionalString enableParallelBuilding "--ghc-options=${parallelBuildingFlags}") | |
| (optionalString useCpphs "--with-cpphs=${cpphs}/bin/cpphs --ghc-options=-cpp --ghc-options=-pgmP${cpphs}/bin/cpphs --ghc-options=-optP--cpp") |
nixpkgs/pkgs/development/haskell-modules/generic-builder.nix
Lines 248 to 249 in 4ec0020
| ] ++ optionals (enableDeadCodeElimination && (lib.versionOlder "8.0.1" ghc.version)) [ | |
| "--ghc-option=-split-sections" |
nixpkgs/pkgs/development/haskell-modules/generic-builder.nix
Lines 260 to 261 in 4ec0020
| ] ++ optionals (doHaddockInterfaces && isLibrary) [ | |
| "--ghc-options=-haddock" |
Steps To Reproduce
Run the following to see the invocation of GHC when cross-compiling to musl64:
nix-build -E 'with import ./default.nix {}; haskell.lib.overrideCabal pkgsCross.musl64.haskellPackages.hello { buildFlags = [ "-v" ]; }'
The configureFlags line will look like this:
configureFlags: --verbose --prefix=/nix/store/ddsc15fcakx45v3c86cx9xrdwlclhb7g-hello-x86_64-unknown-linux-musl-1.0.0.2
--libdir=$prefix/lib/$compiler/lib --libsubdir=$abi/$libname --with-gcc=x86_64-unknown-linux-musl-gcc
--package-db=/build/tmp.W3Zovu64mu/package.conf.d --ghc-options=-j16 +RTS -A64M -RTS --disable-split-objs
--enable-library-profiling --profiling-detail=exported-functions --disable-profiling --enable-shared --disable-coverage
--enable-static --disable-executable-dynamic --disable-tests --disable-benchmarks --enable-library-vanilla --disable-library-for-ghci
--ghc-option=-split-sections --configure-option=--host=x86_64-unknown-linux-musl --with-ghc=x86_64-unknown-linux-musl-ghc
--with-ghc-pkg=x86_64-unknown-linux-musl-ghc-pkg --with-gcc=x86_64-unknown-linux-musl-gcc
--with-ld=x86_64-unknown-linux-musl-ld --with-ar=x86_64-unknown-linux-musl-ar
--with-hsc2hs=x86_64-unknown-linux-musl-hsc2hs --with-strip=x86_64-unknown-linux-musl-strip
--hsc2hs-option=--cross-compile
--extra-lib-dirs=/nix/store/1v2iayibpfkyq4gk9vwz5l19m599n9vd-ncurses-x86_64-unknown-linux-musl-6.4/lib
--extra-lib-dirs=/nix/store/lc6kgi9shf14lgxj08cwbzxfqfl3wlgb-libffi-x86_64-unknown-linux-musl-3.4.4/lib
--extra-lib-dirs=/nix/store/wgzbmp2xfs5rfmdbqa4xjz860276027v-elfutils-x86_64-unknown-linux-musl-0.190/lib
--extra-lib-dirs=/nix/store/1f5r748az7lsd4fdgbrf7z4qw93rx916-gmp-with-cxx-x86_64-unknown-linux-musl-6.3.0/lib
--extra-include-dirs=/nix/store/dkv5hjqr1v3ff3rwr00bmb0q5xzfj3bd-musl-iconv-1.2.3/include
Note the --ghc-options=-j16 and --ghc-option=-split-sections.
The call to GHC:
Running: /nix/store/pzpcvgfj7hagiwfdb5ckyp299vmh68p3-x86_64-unknown-linux-musl-ghc-9.6.4/bin/x86_64-unknown-linux-musl-ghc
--make -no-link -fbuilding-cabal-package -O -static -outputdir dist/build/hello/hello-tmp -odir dist/build/hello/hello-tmp
-hidir dist/build/hello/hello-tmp -stubdir dist/build/hello/hello-tmp -i -idist/build/hello/hello-tmp -isrc -idist/build/hello/autogen
-idist/build/global-autogen -Idist/build/hello/autogen -Idist/build/global-autogen -Idist/build/hello/hello-tmp
-I/nix/store/dkv5hjqr1v3ff3rwr00bmb0q5xzfj3bd-musl-iconv-1.2.3/include -optP-include
-optPdist/build/hello/autogen/cabal_macros.h -hide-all-packages -Wmissing-home-modules -no-user-package-db
-package-db /build/tmp.W3Zovu64mu/package.conf.d -package-db dist/package.conf.inplace -package-id base-4.18.2.0
-XHaskell98 src/hello.hs
None of the two options are passed to GHC.
Expected behavior
Run the same without cross-compiling for pkgsMusl:
nix-build -E 'with import ./default.nix {}; haskell.lib.overrideCabal pkgsMusl.haskellPackages.hello { buildFlags = [ "-v" ]; }'
The configure flags are similar, but the GHC invocation looks like this:
Running: /nix/store/pp40hbfhzcy6cf4lrcg2jyyj3m05hgzp-ghc-musl-9.6.4/bin/ghc --make -no-link -fbuilding-cabal-package
-O -static -outputdir dist/build/hello/hello-tmp -odir dist/build/hello/hello-tmp -hidir dist/build/hello/hello-tmp
-stubdir dist/build/hello/hello-tmp -i -idist/build/hello/hello-tmp -isrc -idist/build/hello/autogen -idist/build/global-autogen
-Idist/build/hello/autogen -Idist/build/global-autogen -Idist/build/hello/hello-tmp
-I/nix/store/vjc0iaa0wa4dbza5vp9dwiv8hn40g81c-musl-iconv-1.2.3/include -optP-include
-optPdist/build/hello/autogen/cabal_macros.h -hide-all-packages -Wmissing-home-modules -no-user-package-db
-package-db /build/tmp.FCMFDXPgoS/package.conf.d -package-db dist/package.conf.inplace -package-id base-4.18.2.0
-XHaskell98 src/hello.hs -j16 -split-sections
Note the -j16 -split-sections at the end.
Additional context
I assume this is a bug in cabal somehow, but I was not able to reproduce this with plain cabal outside nixpkgs, yet. I tried many variations of configureFlags, but the only thing that actually made a difference is pkgsCross / pkgsStatic.
This affects pkgsStatic and results in all statically built haskell executables being larger than they should be, because dead code elimination is not happening. This was already observed in static-haskell-nix (@nh2):
It also means that static executables can't strip auto-generated Paths_xxx modules, which are never required at run-time, I think. But they contain references to /nix/store/... paths of their own module. When trying to create a minimal docker image, with just a single static executable, this will then pull in all of those modules and their dependencies, resulting in a huge image. This was observed after switching PostgREST's build from static-haskell-nix to pkgsStatic.
Dead code elimination / -split-sections can be worked around by passing --enable-split-sections to cabal instead. This will pass on -split-sections correctly, even when cross compiling. However, that doesn't solve the problem for other ghc options.
Notify maintainers
@cdepillabout @expipiplus1 @maralorn @ncfavier @sternenseemann
Add a 👍 reaction to issues you find important.