Skip to content

Can't use system GHC without static libraries at all #3409

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

Open
nponeccop opened this issue Sep 2, 2017 · 16 comments
Open

Can't use system GHC without static libraries at all #3409

nponeccop opened this issue Sep 2, 2017 · 16 comments

Comments

@nponeccop
Copy link

General summary/comments

Recent ArchLinux ships system GHC without static libraries at all. Even without static versions of ghc builtin libraries.

Can I use this ghc with Stack?

The problem is that even Setup.hs needs -dynamic.

Steps to reproduce

  1. Run stack new simple
  2. Add -dynamic to the simple-exe target
  3. Run stack build

Expected

  • Setup executable is dynamically linked to libHSCabal-1.24.2.0-ghc8.0.2.so and so on.
  • simple-exe executable is dynamically linked to libHSsimple-0.1.0.0-5DX8evVT2MQPefjCl7ERW-ghc8.0.2.so

Actual

stack build fails at setup-exe-cache linker stage, unable to find dynamic libraries:

[foo@arch stack-test]$  ~/.local/bin/stack build --verbose
Version 1.5.1, Git revision 600c1f01435a10d127938709556c1682ecfd694e (4861 commits) i386 hpack-0.17.1
2017-09-02 23:02:00.449671: [debug] Checking for project config at: /home/foo/dev/stack-test/stack.yaml
@(Stack/Config.hs:974:9)
2017-09-02 23:02:00.450138: [debug] Loading project config file stack.yaml
@(Stack/Config.hs:999:13)
2017-09-02 23:02:00.456979: [debug] Trying to decode /home/foo/.stack/build-plan-cache/i386-linux/lts-9.2.cache
@(Data/Store/VersionTagged.hs:72:5)
2017-09-02 23:02:00.480637: [debug] Success decoding /home/foo/.stack/build-plan-cache/i386-linux/lts-9.2.cache
@(Data/Store/VersionTagged.hs:76:13)
2017-09-02 23:02:00.481557: [debug] Getting system compiler version
@(Stack/Setup.hs:379:17)
2017-09-02 23:02:00.482149: [debug] Run process: /usr/bin/ghc --info
@(System/Process/Read.hs:306:3)
2017-09-02 23:02:00.560287: [debug] Process finished in 77ms: /usr/bin/ghc --info
@(System/Process/Read.hs:306:3)
2017-09-02 23:02:00.570574: [debug] Getting global package database location
@(Stack/GhcPkg.hs:55:5)
2017-09-02 23:02:00.571133: [debug] Asking GHC for its version
@(Stack/Setup/Installed.hs:103:13)
2017-09-02 23:02:00.571526: [debug] Getting Cabal package version
@(Stack/GhcPkg.hs:189:5)
2017-09-02 23:02:00.571778: [debug] Run process: /usr/bin/ghc-pkg --no-user-package-db list --global
@(System/Process/Read.hs:306:3)
2017-09-02 23:02:00.572470: [debug] Run process: /usr/bin/ghc --numeric-version
@(System/Process/Read.hs:306:3)
2017-09-02 23:02:00.573957: [debug] Run process: /usr/bin/ghc-pkg --no-user-package-db field --simple-output Cabal version
@(System/Process/Read.hs:306:3)
2017-09-02 23:02:00.650533: [debug] Process finished in 76ms: /usr/bin/ghc --numeric-version
@(System/Process/Read.hs:306:3)
2017-09-02 23:02:00.670339: [debug] Process finished in 98ms: /usr/bin/ghc-pkg --no-user-package-db list --global
@(System/Process/Read.hs:306:3)
2017-09-02 23:02:00.703184: [debug] Process finished in 128ms: /usr/bin/ghc-pkg --no-user-package-db field --simple-output Cabal version
@(System/Process/Read.hs:306:3)
2017-09-02 23:02:00.703547: [debug] Resolving package entries
@(Stack/Setup.hs:260:5)
2017-09-02 23:02:00.704146: [debug] Starting to execute command inside EnvConfig
@(Stack/Runners.hs:175:18)
2017-09-02 23:02:00.704362: [debug] Parsing the cabal files of the local packages
@(Stack/Build/Source.hs:328:5)
2017-09-02 23:02:00.706213: [debug] Parsing the targets
@(Stack/Build/Source.hs:265:5)
2017-09-02 23:02:00.706585: [debug] Exception ignored when attempting to load /home/foo/dev/stack-test/.stack-work/dist/i386-linux/Cabal-1.24.2.0/stack-build-cache: /home/foo/dev/stack-test/.stack-work/dist/i386-linux/Cabal-1.24.2.0/stack-build-cache: openBinaryFile: does not exist (No such file or directory)
@(Data/Store/VersionTagged.hs:90:9)
2017-09-02 23:02:00.706917: [debug] Start: getPackageFiles /home/foo/dev/stack-test/setup-depends.cabal
@(Stack/Package.hs:259:21)
2017-09-02 23:02:00.709374: [debug] Finished in 2ms: getPackageFiles /home/foo/dev/stack-test/setup-depends.cabal
@(Stack/Package.hs:259:21)
2017-09-02 23:02:00.710438: [debug] Finding out which packages are already installed
@(Stack/Build/Installed.hs:69:5)
2017-09-02 23:02:00.710864: [debug] Run process: /usr/bin/ghc-pkg --global --no-user-package-db dump --expand-pkgroot
@(System/Process/Read.hs:306:3)
2017-09-02 23:02:00.820944: [debug] Process finished in 109ms: /usr/bin/ghc-pkg --global --no-user-package-db dump --expand-pkgroot
@(System/Process/Read.hs:306:3)
2017-09-02 23:02:00.846849: [debug] Ignoring package haskeline due to wanting version 0.7.4.0 instead of 0.7.3.0
@(Stack/Build/Installed.hs:199:5)
2017-09-02 23:02:00.847374: [debug] Ignoring package xhtml due to wanting version 3000.2.2 instead of 3000.2.1
@(Stack/Build/Installed.hs:199:5)
2017-09-02 23:02:00.847687: [debug] Ignoring package terminfo due to wanting version 0.4.1.0 instead of 0.4.0.2
@(Stack/Build/Installed.hs:199:5)
2017-09-02 23:02:00.848002: [debug] Run process: /usr/bin/ghc-pkg --user --no-user-package-db --package-db /home/foo/.stack/snapshots/i386-linux/lts-9.2/8.0.2/pkgdb dump --expand-pkgroot
@(System/Process/Read.hs:306:3)
2017-09-02 23:02:00.937985: [debug] Process finished in 89ms: /usr/bin/ghc-pkg --user --no-user-package-db --package-db /home/foo/.stack/snapshots/i386-linux/lts-9.2/8.0.2/pkgdb dump --expand-pkgroot
@(System/Process/Read.hs:306:3)
2017-09-02 23:02:00.938420: [debug] Run process: /usr/bin/ghc-pkg --user --no-user-package-db --package-db /home/foo/dev/stack-test/.stack-work/install/i386-linux/lts-9.2/8.0.2/pkgdb dump --expand-pkgroot
@(System/Process/Read.hs:306:3)
2017-09-02 23:02:01.030095: [debug] Process finished in 91ms: /usr/bin/ghc-pkg --user --no-user-package-db --package-db /home/foo/dev/stack-test/.stack-work/install/i386-linux/lts-9.2/8.0.2/pkgdb dump --expand-pkgroot
@(System/Process/Read.hs:306:3)
2017-09-02 23:02:01.030953: [debug] Trying to decode /home/foo/.stack/indices/Hackage/01-index.cache
@(Data/Store/VersionTagged.hs:72:5)
2017-09-02 23:02:01.351467: [debug] Success decoding /home/foo/.stack/indices/Hackage/01-index.cache
@(Data/Store/VersionTagged.hs:76:13)
2017-09-02 23:02:01.379778: [debug] Constructing the build plan
@(Stack/Build/ConstructPlan.hs:188:5)
2017-09-02 23:02:01.387945: [debug] Checking if we are going to build multiple executables with the same name
@(Stack/Build.hs:210:5)
2017-09-02 23:02:01.388381: [debug] Executing the build plan
@(Stack/Build/Execute.hs:478:5)
2017-09-02 23:02:01.390216: [debug] Creating process: /usr/bin/ghc -rtsopts -threaded -clear-package-db -global-package-db -hide-all-packages -package base -main-is StackSetupShim.mainOverride -package Cabal-1.24.2.0 /home/foo/.stack/setup-exe-src/setup-mPHDZzAJ.hs /home/foo/.stack/setup-exe-src/setup-shim-mPHDZzAJ.hs -o /home/foo/.stack/setup-exe-cache/i386-linux/tmp-Cabal-simple_mPHDZzAJ_1.24.2.0_ghc-8.0.2
@(System/Process/Run.hs:102:5)
Linking /home/foo/.stack/setup-exe-cache/i386-linux/tmp-Cabal-simple_mPHDZzAJ_1.24.2.0_ghc-8.0.2 ...
/usr/bin/ld: cannot find -lHSCabal-1.24.2.0
/usr/bin/ld: cannot find -lHSprocess-1.4.3.0
/usr/bin/ld: cannot find -lHSpretty-1.1.3.3
/usr/bin/ld: cannot find -lHSdirectory-1.3.0.0
/usr/bin/ld: cannot find -lHSunix-2.7.2.1
/usr/bin/ld: cannot find -lHStime-1.6.0.1
/usr/bin/ld: cannot find -lHSfilepath-1.4.1.1
/usr/bin/ld: cannot find -lHSbinary-0.8.3.0
/usr/bin/ld: cannot find -lHScontainers-0.5.7.1
/usr/bin/ld: cannot find -lHSbytestring-0.10.8.1
/usr/bin/ld: cannot find -lHSdeepseq-1.4.2.0
/usr/bin/ld: cannot find -lHSarray-0.5.1.1
/usr/bin/ld: cannot find -lHSbase-4.9.1.0
/usr/bin/ld: cannot find -lHSinteger-gmp-1.0.0.1
/usr/bin/ld: cannot find -lHSghc-prim-0.5.0.0
/usr/bin/ld: cannot find -lHSrts_thr
collect2: error: ld returned 1 exit status
`gcc' failed in phase `Linker'. (Exit code: 1)
2017-09-02 23:02:01.940916: [error] Exit code ExitFailure 1 while running ["ghc","-rtsopts","-threaded","-clear-package-db","-global-package-db","-hide-all-packages","-package","base","-main-is","StackSetupShim.mainOverride","-package","Cabal-1.24.2.0","/home/foo/.stack/setup-exe-src/setup-mPHDZzAJ.hs","/home/foo/.stack/setup-exe-src/setup-shim-mPHDZzAJ.hs","-o","/home/foo/.stack/setup-exe-cache/i386-linux/tmp-Cabal-simple_mPHDZzAJ_1.24.2.0_ghc-8.0.2"] in /tmp/stack7830/
@(System/Process/Run.hs:70:13)

Note that I can copy the long command line from Creating process: log line and create a dynamically linked Setup by appending -dynamic option.

And in case of the simple project I can then use Setup build to build a dynamically linked simple-exe.

But in case of more complex projects it obviously doesn't work as Setup build doesn't install dependencies.

Stack version

$ ~/.local/bin/stack --version
Version 1.5.1, Git revision 600c1f01435a10d127938709556c1682ecfd694e (4861 commits) i386 hpack-0.17.1

Method of installation

  • Official binary, downloaded from stackage.org or fpcomplete's package repository (upgraded by an older version to .local/bin)
@mgsloan
Copy link
Contributor

mgsloan commented Sep 3, 2017

Hmm, sounds like a deficiency in the arch distribution of ghc. I recommend using stack to install ghc via stack setup.

Is there anything stack can do here? Only thing I can think of is maybe detecting the condition and telling the user what to do about it.

@nponeccop
Copy link
Author

nponeccop commented Sep 3, 2017

Is there anything stack can do here?

Implement an ability to build Setup with ghc Setup.hs -dynamic for the main target and its dependencies.

cabal-install just works out of the box in this configuration btw

@mgsloan
Copy link
Contributor

mgsloan commented Sep 4, 2017

Perhaps it makes sense to always build Setup.hs with -dynamic. Hmm.

Strange that arch would break this, I wonder what the justification is.

@nponeccop
Copy link
Author

nponeccop commented Sep 7, 2017

Perhaps it makes sense to always build Setup.hs with -dynamic. Hmm.

Two reasons not to:

  1. Packages with setup-depends should avoid building the same code twice. See for example https://hackage.haskell.org/package/gi-gtk-3.0.17/gi-gtk.cabal where haskell-gi is both a normal dependency and a setup dependency. If I want a static gi-gtk I'd like to avoid building dynamic haskell-gi. If I want a dynamic gi-gtk, I'd like to avoid building the static haskell-gi. Think of docker-style clean builds.

  2. Dynamic linking is not supported on Windows since 7.8.x (but they are going to fix it in 8.4.x)

I'm not sure how cabal-install solves this problem.

Strange that arch would break this, I wonder what the justification is.

As shown above the problem is not specific to GHC without static libraries. Arch just exposed an obscure scenario of dynamic linking which is supported by other tools but not by stack.

In general, if I want a static result - then a need to build dynamic versions of dependencies only extends build time.

@nponeccop
Copy link
Author

Note that if I do stack install gi-gtk in the project folder of my original example, I get the following error even with "normal" ghc binary from stack:

    [1 of 2] Compiling Main             ( /tmp/stack25442/gi-cairo-1.0.14/Setup.hs, /tmp/stack25442/gi-cairo-1.0.14/.stack-work/dist/i386-linux-nopie/Cabal-1.24.2.0/setup/Main.o )

    /tmp/stack25442/gi-cairo-1.0.14/Setup.hs:3:1: error:
        Bad interface file: /home/foo/.stack/snapshots/i386-linux-nopie/lts-9.2/8.0.2/lib/i386-linux-ghc-8.0.2/haskell-gi-0.20.3-9nwXY1I1260GlS1AHBdPUX/Data/GI/CodeGen/CabalHooks.hi
            mismatched interface file ways (wanted "", got "dyn")

@23Skidoo
Copy link

23Skidoo commented Sep 8, 2017

If I understand correctly (I don't use Arch) Arch's GHC doesn't work with cabal-install either. See haskell/cabal#4748. Looks like Arch's maintainers are to blame here.

@nponeccop
Copy link
Author

nponeccop commented Sep 8, 2017

So the dynamic-only scenario seems supported fully neither by stack nor by cabal-install.

I also tried to build a dynamically-linked executable (a GTK hello word using gi-gtk) using a "normal" GHC. And both static and dynamic versions of each dependency are built. So I have some 200 MB of *.so and some 600MB of *.a files in ~/.stack. Is it good behaviour? Some extra work is performed.

What do you think?

Also, static-only compilation works fine (e.g. on Windows where there are no dynamic support since 7.8.x until 8.4.x). Is such asymmetry ok?

I'm sort of trying to understand which combinations of linking are supported by design and which are not, and why it is so. Should I discuss this somewhere upstream? With GHC guys or with Cabal guys?

@23Skidoo
Copy link

23Skidoo commented Sep 8, 2017

I do not fully understand all the intricacies of this issue and why stuff breaks, but in principle I think that having dynamic-only compilation work out of the box with our standard tools is a desirable goal. If someone would investigate and fix the relevant issues in the Cabal library, Stack would most likely "just work" too.

@felixonmars
Copy link
Contributor

FYI, there is a ghc-static package in Arch that contains static libraries for GHC boot libraries. An alternative package db is also provided so you can avoid any other installed haskell-* packages causing confusion to Cabal. An example of how this would work:

$ cabal sandbox init
$ cabal install --ghc-pkg-option="--global-package-db=/usr/lib/ghc-8.0.2/static-package.conf.d" alex

GHC itself cannot be built in dynamic only yet (the "vanilla" way must be present), but it's really nice to have that and also tools like cabal-install and stack supporting this setup in the future.

There is also an ArchHaskell repository that contains all static libraries, which should be more suited for Haskell developers using Arch. The dynamic-only haskell-* libraries in [community] are present to support generic tools like pandoc, git-annex, and so on.

@nponeccop
Copy link
Author

nponeccop commented Sep 9, 2017

In other words, both [community] and [archhaskell-core] binary GHC on Arch are useless for now:

  • the former is dynamic-only which is not fully supported by available tools yet,
  • the latter is x86_64 only

Stack-shipped ghc works, but Stack builds both static and dynamic versions (still lacks a feature).

BTW, it's possible to build alex (or projects depending on it) with static-only GHC by passing --ghc-options=-dynamic to cabal:

cabal sandbox init
cabal install alex --ghc-options=-dynamic

The problem here is that cabal-install always links Setup.hs statically, so its disable-library-vanilla option doesn't really work yet.

For Stack I think the situation is even more complex. As Stack wants to share packages, it will have to track which packages have which linking, or even to have 2 separate caches for static and for dynamic versions.

I wonder what is the situation with profiling libraries in this regard?

I also found some work on making dynamic-only setup working upstream at GHC Trac:

So it seems that dynamic-only is an officially a supported configuration, and we can elevate the issue to upstream. So far only cabal-install Setup.hs linking seems broken.

@felixonmars
Copy link
Contributor

Profiling libraries for the boot libraries are included in the ghc-static package.

Also you may want to know that all the official Arch repositories will not support i686 soon: https://www.archlinux.org/news/phasing-out-i686-support/

@nponeccop
Copy link
Author

nponeccop commented Sep 9, 2017

Ok, there exists an upstream bug in Cabal since 2014:

haskell/cabal#1720

@23Skidoo
Copy link

23Skidoo commented Sep 9, 2017

@nponeccop Thanks, this is helpful. If haskell/cabal#1720 is the only issue that needs to be fixed, it should be quite easy to implement. I can look into it once I'm back from ICFP.

@nponeccop
Copy link
Author

@23Skidoo any progress?

@devurandom
Copy link

devurandom commented Sep 4, 2018

I just ran into the same issue. It appears to be impossible to make Stack build a Hakyll site, even when sticking

system-ghc: true
ghc-options:
  "$everything": -dynamic
apply-ghc-options: everything
rebuild-ghc-options: true

into ~/.stack.config.yaml and

library-vanilla: False
shared: True
executable-dynamic: True
ghc-options: -dynamic

into ~/.cabal/config I still see

$ stack build -v
Version 1.7.1 x86_64     
[...]
2018-09-04 08:33:28.163216: [debug] Run process within /tmp/stack-2f30f4e00b8f8cc3/: /usr/bin/ghc -rtsopts -threaded -clear-package-db -global-package-db -hide-all-packages -package base -main-is StackSetupShim.mainOverride -package Cabal-2.2.0.1 ....stack/setup-exe-src/setup-mPHDZzAJ.hs .../.stack/setup-exe-src/setup-shim-mPHDZzAJ.hs -o .../.stack/setup-exe-cache/x86_64-linux/tmp-Cabal-simple_mPHDZzAJ_2.2.0.1_ghc-8.4.3                                                                                     
[1 of 2] Compiling Main             ( .../.stack/setup-exe-src/setup-mPHDZzAJ.hs, .../.stack/setup-exe-src/setup-mPHDZzAJ.o )                                                                                                                           

.../.stack/setup-exe-src/setup-mPHDZzAJ.hs:1:1: error:
    Could not find module ‘Prelude’
    There are files missing in the ‘base-4.11.1.0’ package,
    try running 'ghc-pkg check'.
    Use -v to see a list of the files searched for.
  |
1 | import Distribution.Simple
  | ^

.../.stack/setup-exe-src/setup-mPHDZzAJ.hs:1:1: error:
    Could not find module ‘Distribution.Simple’
    There are files missing in the ‘Cabal-2.2.0.1’ package,
    try running 'ghc-pkg check'.
    Use -v to see a list of the files searched for.
  |
1 | import Distribution.Simple
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^

--  While building simple Setup.hs using:
      /usr/bin/ghc -rtsopts -threaded -clear-package-db -global-package-db -hide-all-packages -package base -main-is StackSetupShim.mainOverride -package Cabal-2.2.0.1 .../.stack/setup-exe-src/setup-mPHDZzAJ.hs .../.stack/setup-exe-src/setup-shim-mPHDZzAJ.hs -o .../.stack/setup-exe-cache/x86_64-linux/tmp-Cabal-simple_mPHDZzAJ_2.2.0.1_ghc-8.4.3
    Process exited with code: ExitFailure 1

I.e. ghc-options is completely ignored.

@dunrix
Copy link

dunrix commented Apr 19, 2020

Same issue, exactly as described by @devurandom #3409 (comment)

I'm surprised, configure/build ghc options specified in stack.yaml in accordance to official documentation, being not passed to ghc compiler is not considered as a fundamental flaw to be fixed asap.

Because we moved to new systems with GHC installations set for dynamic linking, we were forced to drop stack and adjust projects to rely on Cabal only.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants