Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The ghc-options are not passed to the linker #9589

Open
alt-romes opened this issue Jan 5, 2024 · 5 comments
Open

The ghc-options are not passed to the linker #9589

alt-romes opened this issue Jan 5, 2024 · 5 comments
Labels
needs triage re: dynamic-linking Concerning dynamic linking (e.g. flags "shared", "*-dynamic") type: bug

Comments

@alt-romes
Copy link
Collaborator

alt-romes commented Jan 5, 2024

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
Copy link
Collaborator Author

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!

@andreabedini
Copy link
Collaborator

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

@alt-romes
Copy link
Collaborator Author

alt-romes commented Jan 18, 2024

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

@andreabedini
Copy link
Collaborator

andreabedini commented Jan 22, 2024

You are right, I copied the wrong invocation ☺️
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.

@andreasabel andreasabel added the re: dynamic-linking Concerning dynamic linking (e.g. flags "shared", "*-dynamic") label Mar 6, 2024
@drone29a
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs triage re: dynamic-linking Concerning dynamic linking (e.g. flags "shared", "*-dynamic") type: bug
Projects
None yet
Development

No branches or pull requests

4 participants