The ghc-options are not passed to the linker
While fixing a bug that turned out to be another case of #7339, I realized that the ghc-options field is not being passed to a linker invocation of ghc after having compiled the haskell modules and extra build sources (see buildOrReplLib).
You can see that the linker options e.g. start from mempty instead of baseOpts (where baseOpts has already added to ghcOptExtra the ghc-options specified in the cabal file or flags). This happens for ghcSharedOpts, however, the ghcOptExtra seems to be added in that case. I haven't further diagnosed.
linkerOpts =
+ -- (Shouldn't this be `baseOpts` as well? If not,
+ -- then ghcOptsExtra is not being considered in the linker invocation.)
- mempty
+ baseOpts
{ ghcOptLinkOptions =
PD.ldOptions libBi
++ [ "-static"
| withFullyStaticExe lbi
The initial attempted fix (that turned out to be fixed by the patch that fixed #7339) was to add
ghc-options: -optc-Wl,-rpath,/path...
which did not work because, even though it gets passed to the ghc --make invocation that compiles haskell modules, it does not get passed on to the linker invocation that links them together.
Here is a reproducer:
cabal initto create alibrary- Add
ghc-options: -optl-Wl,-rpath,/something/silly cabal build -vto view the ghc invocation that creates the shared library (ghc -shared -dynamic ...)- Note that
-optl-Wl,-rpath,/something/sillyis not there!
Instead, you get
Running:
/Users/romes/.ghcup/bin/ghc
-shared
-dynamic
'-dynload
deploy'
-optl-Wl,-rpath,/Users/romes/.ghcup/ghc/9.8.1/lib/ghc-9.8.1/lib/aarch64-osx-ghc-9.8.1
-optl-Wl,-rpath,/Library/Developer/CommandLineTools/SDKs/MacOSX14.2.sdk/usr/lib
-this-unit-id
tmp-SFgKe25rIL-0.1.0.0-inplace
-hide-all-packages
-no-auto-link-packages
-no-user-package-db
-package-db
/Users/romes/.cabal/store/ghc-9.8.1/package.db
-package-db
/private/var/folders/tv/35hlch6s3y15hfvndc71l6d40000gn/T/tmp.SFgKe25rIL/dist-newstyle/packagedb/ghc-9.8.1
-package-db
/private/var/folders/tv/35hlch6s3y15hfvndc71l6d40000gn/T/tmp.SFgKe25rIL/dist-newstyle/build/aarch64-osx/ghc-9.8.1/tmp-SFgKe25rIL-0.1.0.0/package.conf.inplace
-package-id
base-4.19.0.0-e537
dist-newstyle/build/aarch64-osx/ghc-9.8.1/tmp-SFgKe25rIL-0.1.0.0/build/MyLib.dyn_o
-o
dist-newstyle/build/aarch64-osx/ghc-9.8.1/tmp-SFgKe25rIL-0.1.0.0/build/libHStmp-SFgKe25rIL-0.1.0.0-inplace-ghc9.8.1.dylib
-hide-all-packages
but nothing /something/silly!
I cannot reproduce with cabal 3.10.2.1 and ghc 9.6.3 (on linux/x86_64).
~/Scratchpad/cabal-9589
❯ cabal init --non-interactive --minimal --lib && cabal build --ghc-options="-optl-Wl,-rpath,/something/silly" -v
...
Running:
/home/andrea/.ghcup/bin/ghc
--make
-fbuilding-cabal-package
-O
-static
-dynamic-too
-dynosuf
dyn_o
-dynhisuf
dyn_hi
-outputdir
/home/andrea/Scratchpad/cabal-9589/dist-newstyle/build/x86_64-linux/ghc-9.6.3/cabal9589-0.1.0.0/build
-odir
/home/andrea/Scratchpad/cabal-9589/dist-newstyle/build/x86_64-linux/ghc-9.6.3/cabal9589-0.1.0.0/build
-hidir
/home/andrea/Scratchpad/cabal-9589/dist-newstyle/build/x86_64-linux/ghc-9.6.3/cabal9589-0.1.0.0/build
-stubdir
/home/andrea/Scratchpad/cabal-9589/dist-newstyle/build/x86_64-linux/ghc-9.6.3/cabal9589-0.1.0.0/build
-i
-i/home/andrea/Scratchpad/cabal-9589/dist-newstyle/build/x86_64-linux/ghc-9.6.3/cabal9589-0.1.0.0/build
-isrc
-i/home/andrea/Scratchpad/cabal-9589/dist-newstyle/build/x86_64-linux/ghc-9.6.3/cabal9589-0.1.0.0/build/autogen
-i/home/andrea/Scratchpad/cabal-9589/dist-newstyle/build/x86_64-linux/ghc-9.6.3/cabal9589-0.1.0.0/build/global-autogen
-I/home/andrea/Scratchpad/cabal-9589/dist-newstyle/build/x86_64-linux/ghc-9.6.3/cabal9589-0.1.0.0/build/autogen
-I/home/andrea/Scratchpad/cabal-9589/dist-newstyle/build/x86_64-linux/ghc-9.6.3/cabal9589-0.1.0.0/build/global-autogen
-I/home/andrea/Scratchpad/cabal-9589/dist-newstyle/build/x86_64-linux/ghc-9.6.3/cabal9589-0.1.0.0/build
-optP-include
-optP/home/andrea/Scratchpad/cabal-9589/dist-newstyle/build/x86_64-linux/ghc-9.6.3/cabal9589-0.1.0.0/build/autogen/cabal_macros.h
-this-unit-id
cabal9589-0.1.0.0-inplace
-hide-all-packages
-Wmissing-home-modules
-no-user-package-db
-package-db
/home/andrea/.cabal/store/ghc-9.6.3/package.db
-package-db
/home/andrea/Scratchpad/cabal-9589/dist-newstyle/packagedb/ghc-9.6.3
-package-db
/home/andrea/Scratchpad/cabal-9589/dist-newstyle/build/x86_64-linux/ghc-9.6.3/cabal9589-0.1.0.0/package.conf.inplace
-package-id
base-4.18.1.0
-XHaskell2010
MyLib
-Wall
-hide-all-packages
-optl-Wl,-rpath,/something/silly
[1 of 1] Compiling MyLib ( src/MyLib.hs, /home/andrea/Scratchpad/cabal-9589/dist-newstyle/build/x86_64-linux/ghc-9.6.3/cabal9589-0.1.0.0/build/MyLib.o, /home/andrea/Scratchpad/cabal-9589/dist-newstyle/build/x86_64-linux/ghc-9.6.3/cabal9589-0.1.0.0/build/MyLib.dyn_o )
Linking...
@andreabedini however, what I'm concerned about is that ghc-options are not passed to the linker invocations, which I don't think is what you pasted here.
I mean, for example, the invocation done after compiling the modules with --make that subsequently creates the library's shared object (the one with -shared).
You are right, I copied the wrong invocation :relaxed:
Adding -v to ghc-options I get this:
Running: /home/andrea/.ghcup/bin/ghc -shared -dynamic '-dynload deploy' -optl-Wl,-rpath,/home/andrea/.ghcup/ghc/9.6.3/lib64/ghc-9.6.3/lib/x86_64-linux-ghc-9.6.3 -this-unit-id cabal9589-0.1.0.0-inplace -hide-all-packages -no-auto-link-packages -no-user-package-db -package-db /home/andrea/.cabal/store/ghc-9.6.3/package.db -package-db /home/andrea/Scratchpad/cabal-9589/dist-newstyle/packagedb/ghc-9.6.3 -package-db /home/andrea/Scratchpad/cabal-9589/dist-newstyle/build/x86_64-linux/ghc-9.6.3/cabal9589-0.1.0.0/package.conf.inplace -package-id base-4.18.1.0 dist-newstyle/build/x86_64-linux/ghc-9.6.3/cabal9589-0.1.0.0/build/MyLib.dyn_o -o dist-newstyle/build/x86_64-linux/ghc-9.6.3/cabal9589-0.1.0.0/build/libHScabal9589-0.1.0.0-inplace-ghc9.6.3.so -hide-all-packages -v -optl-Wl,-rpath,/something/silly
Glasgow Haskell Compiler, Version 9.6.3, stage 2 booted by GHC version 9.2.2
*** systool:linker:
*** Linker:
gcc '-fuse-ld=lld' -Wl,--no-as-needed -lm -o dist-newstyle/build/x86_64-linux/ghc-9.6.3/cabal9589-0.1.0.0/build/libHScabal9589-0.1.0.0-inplace-ghc9.6.3.so -shared -Wl,-Bsymbolic -Wl,-h,libHScabal9589-0.1.0.0-inplace-ghc9.6.3.so dist-newstyle/build/x86_64-linux/ghc-9.6.3/cabal9589-0.1.0.0/build/MyLib.dyn_o -L/home/andrea/.ghcup/ghc/9.6.3/lib64/ghc-9.6.3/lib/../lib/x86_64-linux-ghc-9.6.3 -lHSbase-4.18.1.0-ghc9.6.3 -lHSghc-bignum-1.3-ghc9.6.3 -lHSghc-prim-0.10.0-ghc9.6.3 -lgmp -lc -lm -Wl,-rpath,/home/andrea/.ghcup/ghc/9.6.3/lib64/ghc-9.6.3/lib/x86_64-linux-ghc-9.6.3 -Wl,-rpath,/something/silly
Created temporary directory: /tmp/ghc5521_0
!!! systool:linker: finished in 1.88 milliseconds, allocated 1.228 megabytes
NOTE I had to do cabal clean because otherwise adding --ghc-options=-v would not trigger rebuild.
Any update on this issue? This is also causing problems for me where I need to pass an rpath directory to the linker when building a project that depends on the jni Haskell package. I'm glad to work on a patch if cabal maintainers agree it should be fixed.