Ticket #600 (closed defect: fixed)

Opened 4 years ago

Last modified 18 months ago

Cabal should have an option to dynamically link executables

Reported by: juhp Owned by:
Priority: normal Milestone: Cabal-1.10
Component: Cabal library Version: HEAD
Severity: normal Keywords:
Cc: juhp@… Difficulty: very easy (<1 hour)
GHC Version: 6.12.3 Platform: Linux

Description

With ghc-6.12 --enable-shared now works well to create shared libraries, however executable binary programs generated with Cabal are always statically linked. When configuring with --enable-shared they should be dynamically linked if possible.

Here is a patch tested successfully with ghc-6.12 RC1 on Linux.

Attachments

ghc-6.12.0-exe-dynamic.patch Download (0.7 KB) - added by juhp 4 years ago.
patch to use -dynamic for exe linking when --enable-shared
add-dynamic-configure-option-for-dynamically-linking-executables.dpatch Download (121.3 KB) - added by juhp 2 years ago.
updated option name to "--enable-executable-dynamic"

Change History

Changed 4 years ago by juhp

patch to use -dynamic for exe linking when --enable-shared

follow-up: ↓ 2   Changed 4 years ago by juhp

Maybe runghc configure --ghc-opt=-dynamic is a workaround?

in reply to: ↑ 1   Changed 3 years ago by KrzysztofSkrzetnicki

Replying to juhp:

Maybe runghc configure --ghc-opt=-dynamic is a workaround?

It might work, but not when TH is used. For example it fails for me:

$ cabal install --ghc-option=-dynamic 
Resolving dependencies...
Configuring slayer-0.3.1...
Preprocessing library slayer-0.3.1...
Preprocessing executables for slayer-0.3.1...
Building slayer-0.3.1...
[ 1 of 32] Compiling Slayer.MultilineQQ ( src/Slayer/MultilineQQ.hs, dist/build/Slayer/MultilineQQ.o )
[ 2 of 32] Compiling Slayer.Network.EmailAddr ( src/Slayer/Network/EmailAddr.hs, dist/build/Slayer/Network/EmailAddr.o )
[ 3 of 32] Compiling Slayer.Network.Mail ( src/Slayer/Network/Mail.hs, dist/build/Slayer/Network/Mail.o )
Loading package ghc-prim ... linking ... done.
(... lots of packages ...)
Loading package ffi-1.0 ... linking ... done.
src/Slayer/Network/Mail.hs:1:0:
    Dynamic linking required, but this is a non-standard build (eg. prof).
    You need to build the program twice: once the normal way, and then
    in the desired way using -osuf to set the object file suffix.
cabal: Error: some packages failed to install:
slayer-0.3.1 failed during the building phase. The exception was:
ExitFailure 1

I have no idea if the patch specified above is going to work or not.

follow-up: ↓ 4   Changed 3 years ago by juhp

Krzysztof, which OS are you testing on? I admit I have not tested my patch further since ghc-6.12.1 was released. "--ghc-option=-dynamic" works ok on Linux ix86* for bin packages. And --enable-shared works ok on lib packages.

There is a conflict for binlib packages when configuring with "--ghc-option=-dynamic --enable-shared -p": the build fails complaining about missing dyn_prof files in ghc's libraries IIRC. This sounds pretty much what you are seeing. I think that cabal needs to support -dynamic itself to workaround this.

(Note also this bug was reported against Cabal not cabal-install.)

in reply to: ↑ 3   Changed 3 years ago by KrzysztofSkrzetnicki

Replying to juhp:

Krzysztof, which OS are you testing on? I admit I have not tested my patch further since ghc-6.12.1 was released. "--ghc-option=-dynamic" works ok on Linux ix86* for bin packages. And --enable-shared works ok on lib packages.

Here is my current configuration:

$ uname -a
Linux laptener 2.6.32-ARCH #1 SMP PREEMPT Tue Jan 19 06:08:04 UTC 2010 i686 Intel(R) Core(TM)2 Duo CPU T7500 @ 2.20GHz GenuineIntel GNU/Linux
$ ghc -V
The Glorious Glasgow Haskell Compilation System, version 6.12.1
$ cabal -V
cabal-install version 0.8.0
using version 1.8.0.2 of the Cabal library 

When I first replied to this ticket I was using cabal-install 0.6.2 with Cabal 1.6.0.2 (or 1.6.0.3, I'm not sure). I've upgraded hoping it'll solve the issue.

There is a conflict for binlib packages when configuring with "--ghc-option=-dynamic --enable-shared -p": the build fails complaining about missing dyn_prof files in ghc's libraries IIRC. This sounds pretty much what you are seeing. I think that cabal needs to support -dynamic itself to workaround this. (Note also this bug was reported against Cabal not cabal-install.)

Well, I missed that fact entirely. But I suspect that fixing #600 would solve the issue with cabal-install as well, right? (I have completely no idea how cabal-install works internally, so it's a wild guess.)

follow-up: ↓ 6   Changed 3 years ago by KrzysztofSkrzetnicki

It should also be noted that simply building with ghc --make -dynamic program.hs works correctly and so does cabal install --enable-shared with libraries. I can't do the former with my program since there is a lot of Cabal-related stuff (like Paths_ module or LANGUAGE extensions set in .cabal file).

OTOH I doesn't really need -dynamic executables, so it's definitely not a top priority for me.

in reply to: ↑ 5 ; follow-up: ↓ 7   Changed 3 years ago by juhp

Replying to KrzysztofSkrzetnicki:

But I suspect that fixing #600 would solve the issue with cabal-install as well, right?

I think so too.

Replying to KrzysztofSkrzetnicki:

It should also be noted that simply building with ghc --make -dynamic program.hs works correctly

Right but that does not give you dynamic linking to your library, I think?

and so does cabal install --enable-shared with libraries.

and no dynamic executable in this case.

Have you tried dynamic and shared without profiling?

(I guess the Cabal version metadata in trac needs updating I hope this can be fixed in 1.10.)

in reply to: ↑ 6 ; follow-up: ↓ 8   Changed 3 years ago by KrzysztofSkrzetnicki

Replying to juhp:

Replying to KrzysztofSkrzetnicki:

It should also be noted that simply building with ghc --make -dynamic program.hs works correctly

Right but that does not give you dynamic linking to your library, I think?

It does, actually. I've moved executable to a different directory to force GHC to use library installed in the system (instead of picking up modules from directory tree) and command ghc --make -dynamic fake_main.hs went successfully. The resulting executable uses shared libraries:

$ ghc --make -dynamic fake_main
[1 of 1] Compiling Main             ( fake_main.hs, fake_main.o )
Linking fake_main ...
$ ldd fake_main
	linux-gate.so.1 =>  (0xb7881000)
	libHSslayer-0.3.1-ghc6.12.1.so => /home/tener//lib/slayer-0.3.1/ghc-6.12.1/libHSslayer-0.3.1-ghc6.12.1.so (0xb7793000)
	libHStemplate-0.1.1.1-ghc6.12.1.so => /home/tener//lib/template-0.1.1.1/ghc-6.12.1/libHStemplate-0.1.1.1-ghc6.12.1.so 
(...)
	libgmp.so.3 => /usr/lib/libgmp.so.3 (0xb5c16000)
	libHSghc-prim-0.2.0.0-ghc6.12.1.so => /usr/lib/ghc-6.12.1/ghc-prim-0.2.0.0/libHSghc-prim-0.2.0.0-ghc6.12.1.so (0xb5ba3000)
	libHSrts-ghc6.12.1.so => /usr/lib/ghc-6.12.1/libHSrts-ghc6.12.1.so (0xb5b5e000)
	libm.so.6 => /lib/libm.so.6 (0xb5b37000)
	libHSffi-ghc6.12.1.so => /usr/lib/ghc-6.12.1/libHSffi-ghc6.12.1.so (0xb5b2e000)
	libc.so.6 => /lib/libc.so.6 (0xb59e7000)
	libpthread.so.0 => /lib/libpthread.so.0 (0xb59cd000)
	/lib/ld-linux.so.2 (0xb7882000)

There are 52 .so libs in total as opposed to 9 when linking statically.

and so does cabal install --enable-shared with libraries.

and no dynamic executable in this case. Have you tried dynamic and shared without profiling?

Here is the output:

$ cabal install --disable-library-profiling --enable-shared 
(...)
$ ldd dist/build/slayer/slayer | wc -l
9

It's definitely statical.

(I guess the Cabal version metadata in trac needs updating I hope this can be fixed in 1.10.)

It's not critical issue but I hope that too.

in reply to: ↑ 7   Changed 3 years ago by juhp

Replying to KrzysztofSkrzetnicki:

It does, actually. I've moved executable to a different directory to force GHC to use library installed in the system

Hehe, I think we agree on all points and facing the same problem: bin packages work but not binlib. :)

But that's a good workaround for forcing dynamic for binlib though - maybe I should use it in some fedora packages for now.

Have you tried dynamic and shared without profiling?

:

It's definitely statical.

I meant something like

cabal install --disable-library-profiling --enable-shared --ghc-option=-dynamic

for your binlib package - dunno if --disable-executable-profiling is needed too.

  Changed 3 years ago by KrzysztofSkrzetnicki

I made a small experiment. I've changed description field for executable. It used to be:

executable slayer
  executable: slayer
  hs-source-dirs: src
  ghc-options: -threaded
  main-is: fake_main.hs
  other-modules: Paths_slayer

  extensions: TemplateHaskell, MultiParamTypeClasses, FunctionalDependencies,
              ScopedTypeVariables, TypeSynonymInstances, ViewPatterns

Now it's this: (diff: src is exec)

executable slayer
  executable: slayer
  hs-source-dirs: exec
  ghc-options: -threaded
  main-is: fake_main.hs
  other-modules: Paths_slayer
--  build-depends: slayer

  extensions: TemplateHaskell, MultiParamTypeClasses, FunctionalDependencies,
              ScopedTypeVariables, TypeSynonymInstances, ViewPatterns

cabal-install complains now about missing library:

$ cabal install
Resolving dependencies...
Configuring slayer-0.3.1...
Preprocessing library slayer-0.3.1...
Preprocessing executables for slayer-0.3.1...
Building slayer-0.3.1...
Registering slayer-0.3.1...

exec/fake_main.hs:3:17:
    Could not find module `Slayer.Main':
      It is a member of the hidden package `slayer-0.3.1'.
      Perhaps you need to add `slayer' to the build-depends in your .cabal file.
      Use -v to see a list of the files searched for.
cabal: Error: some packages failed to install:
slayer-0.3.1 failed during the building phase. The exception was:
ExitFailure 1

However if I remove comments from build-depends field, I get another error:

$ cabal install
Resolving dependencies...
cabal: internal error: could not construct a valid install plan.
The proposed (invalid) plan contained the following problems:
The following packages are involved in a dependency cycle slayer-0.3.1

I think I saw the ticket about allowing this specific type of cycle to appear in .cabal files, but I'm not sure about the details.

I guess splitting library from executable would work (and specifying -dynamic afterwards too), but i'm not going to do this now. I'd rather see the bug fixed :-)

follow-up: ↓ 11   Changed 3 years ago by maltem

Since people seem to be unclear on how exactly --enable-shared should behave, would it make sense to provide --enable-shared-libraries and --enable-shared-executables? (I'm not sure about those names, they would be analogous to --enable-library-profiling and --enable-executable-profiling.)

in reply to: ↑ 10   Changed 3 years ago by juhp

  • summary changed from Cabal should use -dynamic linking for executable when package configured --enable-shared to Cabal should use support -dynamic linking of executable

Replying to maltem:

would it make sense to provide --enable-shared-libraries and --enable-shared-executables? (I'm not sure about those names, they would be analogous to --enable-library-profiling and --enable-executable-profiling.)

Yes, though I might favour using say --enable-dynamic for linking executables and then the current --enable-shared could still be used for generating shared libraries. (I hope before too long on Linux the default will be to create shared libs and dynamically linked binaries anyway.)

[Having said that I think there has been talk about changing or improving ghc's package system to support separately static(vanilla)/prof/dyn/etc flavours of library packages (though I am not sure yet if that is the way to go).]

  Changed 2 years ago by juhp

  • cc juhp@… added
  • difficulty changed from unknown to very easy (<1 hour)
  • ghcversion set to 6.12.3
  • milestone changed from Cabal-1.8 to Cabal-2.0

  Changed 2 years ago by juhp

  • summary changed from Cabal should use support -dynamic linking of executable to Cabal should have an option to dynamically link executables

  Changed 2 years ago by juhp

  • milestone changed from Cabal-2.0 to Cabal-1.10

  Changed 2 years ago by juhp

Mr Marlow suggested "--enable-dynamic-executable" I guess that is more clear and precise, though a little long (hope one day it will be default...).

  Changed 2 years ago by juhp

actually it was "--enable-executable-dynamic", which is consist with "--enable-executable-profiling".

Changed 2 years ago by juhp

updated option name to "--enable-executable-dynamic"

  Changed 2 years ago by duncan

Patch looks good, waiting for re-send of the patch to correct patch file corruption issues.

  Changed 2 years ago by juhp

Thanks, Duncan for applying the patch to HEAD.

  Changed 2 years ago by duncan

  • status changed from new to closed
  • resolution set to fixed
Sun Jan 30 11:02:06 GMT 2011  Jens Petersen <juhp@community.haskell.org>
  * add --enable-executable-dynamic option for dynamic linking of executables

  Changed 18 months ago by elga

  Changed 18 months ago by edouard

Vous pourrez vous procurer votre numero rio Orange, votre code rio SFR ou encore son code rio Bouygues en un clin d'oeil !  simyo

Note: See TracTickets for help on using tickets.