cabal icon indicating copy to clipboard operation
cabal copied to clipboard

The ghc-options are not passed to the linker

Open alt-romes opened this issue 1 year ago • 7 comments

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.

alt-romes avatar Jan 05 '24 20:01 alt-romes

Here is a reproducer:

  • cabal init to create a library
  • Add ghc-options: -optl-Wl,-rpath,/something/silly
  • cabal build -v to view the ghc invocation that creates the shared library (ghc -shared -dynamic ...)
  • Note that -optl-Wl,-rpath,/something/silly is 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!

alt-romes avatar Jan 05 '24 21:01 alt-romes

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 avatar Jan 18 '24 10:01 andreabedini

@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).

alt-romes avatar Jan 18 '24 14:01 alt-romes

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.

andreabedini avatar Jan 22 '24 03:01 andreabedini

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.

drone29a avatar May 19 '24 04:05 drone29a