Skip to content
This repository was archived by the owner on Oct 7, 2020. It is now read-only.

hie executable should be compiled with -dynamic #1171

Open
mpickering opened this issue Apr 11, 2019 · 22 comments
Open

hie executable should be compiled with -dynamic #1171

mpickering opened this issue Apr 11, 2019 · 22 comments
Assignees

Comments

@mpickering
Copy link
Collaborator

See https://gitlab.haskell.org/ghc/ghc/issues/15524

c356c38

Testing this change on my branch it makes a huge difference.

Any volunteers to integrate this into stack and the ./install.hs script?

@power-fungus perhaps?

@nponeccop
Copy link
Contributor

nponeccop commented Apr 11, 2019

Unfortunately it opens another can of worms. Dynamic linking in Haskell doesn't work as of 2019, there are a bunch of issues. It may work if we also build a static version, doubling build times. Cabal-install, Stack and GHC are all broken in one way or another:

haskell/cabal#1720
commercialhaskell/stack#3409
https://gitlab.haskell.org/ghc/ghc/issues/16526

and so on :) Basically it seems to work, but corner cases (such as dynamic linking of Setup.hs) don't work. Also Windows has had dynamic linking completely broken since GHC 7.8, and while it seems to be fixed now, neither Stack nor Haskell.org have binaries with dynamic base, which prevents -dynamic from working on Windows in general even if it's able now on Windows GHC developers' boxes.

I'm a big proponent of dynamic builds, they are better in every aspect than "traditional" static builds. So dynamic linking of HIE is a pretty nice feature to have.

But it's blocked by upstream bugs for now.

@mpickering
Copy link
Collaborator Author

hie is the only binary which needs to be dynamically linked. It doesn't have a custom Setup.hs or anything complicated like the tickets you are suggesting. Have you tried compiling HIE with the executable-dynamic: True option set? Does it not work on your system?

@nponeccop
Copy link
Contributor

nponeccop commented Apr 11, 2019

I didn't try it. But it can't work on Windows because I checked the last binaries and .dlls aren't there. So any build script should at very least change the setting if on Windows.

Also, the dynamic linking may seem to work, but bugs affect corner cases we may or may not encounter in the future. For example, the static Setup.hs linking bug affects dependencies too, but only if we disable "vanilla" (static) libraries with library-vanilla: false as well. And with vanilla libraries build time is twice as long.

So yeah, we may try to do it, but the idea of my comments is merely that we may regret :) as we need to support a wide range of platforms and scenarios.

@Anrock
Copy link
Collaborator

Anrock commented Apr 11, 2019

Seems working on the first look on Win 10. Just to be sure i did it right:

  1. Added a dynamic-executable: true to cabal.project
  2. stack ./install hie-8.6.4

I just checked that hie launches ok for stack project and handles basic diagnostic like misspelled name of type in scope.

@nponeccop
Copy link
Contributor

nponeccop commented Apr 11, 2019

Is hie dynamically linked indeed? can you look at the .exe with http://dependencywalker.com/ ? I don't think stack uses cabal.project at all so I suspect you got a statically linked .exe

@Anrock
Copy link
Collaborator

Anrock commented Apr 11, 2019

@nponeccop i've loaded the EXE into dep walker, how exactly i determine if it's dynamically linked?

@nponeccop
Copy link
Contributor

It should have some 90+ libHS*.dll. If it has the same dlls as stack.exe then it's static.

@Anrock
Copy link
Collaborator

Anrock commented Apr 11, 2019

Welp, it didn't work then. All I see is winapi related libs and no traces of anything libHS*-like, module(?) list is slightly longer than stack.exe, with addition of DBGHELP.DLL, PSAPI.DLL, SHLWAPI.DLL and WINMM.DLL.

@nponeccop
Copy link
Contributor

nponeccop commented Apr 11, 2019

with addition of DBGHELP.DLL, PSAPI.DLL, SHLWAPI.DLL and WINMM.DLL

these are all windows dlls. So it's definitely not dynamic.

@mpickering how do you build hie so it's dynamic? with cabal new-build?

@samuelpilz
Copy link
Contributor

I can have a look at this. What is actually required for this?

@nponeccop
Copy link
Contributor

nponeccop commented Apr 12, 2019

@power-fungus We want to build hie and all its dependencies with -dynamic, which means generating .so and linking dynamically. Note that this means that the snapshots in ~/.stack are built with -dynamic too.

I know one way to do it:

ghc-options:
  "$everything": -dynamic

I think it goes to ~/.stack/config or something

@samuelpilz
Copy link
Contributor

@nponeccop so this is really more of a thing the user has to do? Because the build process does not touch these files.

@nponeccop
Copy link
Contributor

We need to answer some questions:

  • Is it possible to achieve dynamically linked hie executable with Stack?
  • Is it beneficial (e.g. the dynamic linking shortens build times or uses much less disk space)?
  • What are implications for Stack snapshot cache and end-user applications in general? Are they forced to use dynamic linking in their projects as well or not?
  • Which platforms and/or bitnesses out of Linux, Windows and MacOS are not supported at this time due to upstream bugs or other problems?

So we need someone to do this research. I only found the ghc-options: -dynamic solution but it seems to be a hack: e.g. cabal-install has a high-level settings of executable-dynamic: true and corresponding configure options instead. Neither I tested that it actually worked

@mpickering
Copy link
Collaborator Author

@nponeccop Please can you reopen this issue as it is not resolved yet.

You can read more about the investigations I did into this issue on the GHC issue tracker

In summary

  • Nix users are worst affected by this because of the poor interaction between --enable-library-for-ghci and --enable-split-sections. There has recently been a patch which disables --enable-library-for-ghci but it will take a while before all users have moved onto a commit which contains this fix.
  • The runtime linker built into GHC is still many times slower than the system dynamic linker and it seems to scale in a non-linear manner. (100x in my test case)
  • The only workaround that be applied from the tooling side is to dynamically link the HIE executable, the other solutions require modifications to installed user packages.

It seems that your argument boils down to the fact that dynamic linking might not work on all platforms but as it improves the experience of users on platforms where it does work then we should try to enable it or at least provide an option to enable it.

Further to this, we should certainly make sure that hie-nix dynamically links hie as it is nix users who are most going to be affected.

@alanz alanz reopened this Apr 13, 2019
@nponeccop
Copy link
Contributor

Oh sorry I closed it by mistake

@alanz
Copy link
Collaborator

alanz commented Apr 14, 2019

In the interim, can we make this platform-dependent? So it is enabled for platforms where we know it works.

@samuelpilz
Copy link
Contributor

@alanz I am currently experimenting with dynamic building on linux. But I need assistence in testing if the build script I write does indeed build everything dynamically.

@samuelpilz
Copy link
Contributor

Can someone try to check if cabal new-install hie --enable-executable-dynamic -w ... does the correct thing? Or should a different command be used?

@nponeccop
Copy link
Contributor

I need assistance in testing if the build script I write does indeed build everything dynamically.

The goal is just to build the hie executable dynamically. So you can check it with ldd {full path to hie}. If you see many libHS* files it's dynamic. If you see about 10 references then it's static.

@samuelpilz
Copy link
Contributor

samuelpilz commented Sep 4, 2019

Are there any updates on this? I can add cabal-dynamic-* targets (or something similar) and adding the flag --enable-executable-dynamic. However, I am not an expert on the caveats that need to be considered.

@mpickering
Copy link
Collaborator Author

Well, -dynamic is faster but apparently not a good option by default. So perhaps it's worth adding a target as an experiment, most people probably won't notice the extra few seconds it takes..

@jneira
Copy link
Member

jneira commented Sep 5, 2019

For the record, --enable-executable-dynamic does nothing on windows in my tests (inspecting exes with the dependency walker)
Moreove it seems that ghc doesn't support it yet: https://gitlab.haskell.org/ghc/ghc/wikis/windows-dynamic-linking
So no benefit but no harm either.

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

No branches or pull requests

6 participants