-
Notifications
You must be signed in to change notification settings - Fork 697
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
cabal install/build: static executables and stripping #7236
Comments
I confirm 1 with newest dev cabal and GHC 9.2.0-alpha. I get the following error with 2 and 3:
which probably is a libc error, fixed 2 months ago after 8 years: https://sourceware.org/bugzilla/show_bug.cgi?id=15648 Generally, I've heard statically linking with libc is hard and produced binaries that are not portable. Which may be why people do this differently: https://github.com/utdemir/ghc-musl and https://github.com/nh2/static-haskell-nix. Which may also be why cabal or GHC silently ignores it sometimes. I agree it should not be silent about it. So, in this issue, I'd focus on the lack of stripping. I've repeated 1, 2 and 3 without |
The following tells me that However, I tried
and the binary is still not stripped. Moreover I added |
I am already using musl, not glibc. It is thus clearly a cabal issue. |
Oh, I missed that. I hope installing musl and busybox on my old Ubuntu 16.04 won't be a problem, in case I try to repro and debug. Anyway, stripping first, in case it's somehow related. |
Here's an easy way to get an alpine container up and running:
hope it helps. |
Indeed my old Ubuntu is enough to repro the musl stuff. I've followed these docker instructions exactly and I reproduced all 3 cases from the ticket description with GHC 9.0.1. |
Minor related inconsistency: the default ~/.cabal/config says "-- executable-stripping:\n", while it's supposed (doc/installing-packages.rst) to have the default value there, which doc/cabal-project.rst and others claim to be True in this case. And indeed Cabal/src/Distribution/Simple/Setup.hs, which I assume sets the default values, has
instead of Edit: though there is still
in cabal-install/src/Distribution/Client/PackageHash.hs, but also
in cabal-install/src/Distribution/Client/ProjectPlanning.hs. Edit2: the cleared default seems to be compensated for elsewhere in b408d16. |
OK, as far as I can see, stripping (possibly also static linking) was just never implemented for the new-* commands. At least, the new codepaths, the ones that really get called for new-*, e.g., the one containing Before we set up to implement this, we'd need a consensus about when the stripping should be called: whether only when copying exes for new-install, or already when creating the exe files, which is done in new-build as well (but then it would be stripping in place, I guess?). The documentation would need to reflect that, as well. For static linking, there is no doubts about when to do it, I suppose, and we probably don't want to try and guess if it's going to fail, e.g., due to libc. So that could be attempted without any discussion. Edit: are there any TODO notes somewhere for functionality waiting to be implement for new-* and how to do it? Edit2: given that static linking does work for new-build, the hypothesis, by analogy to stripping, is that it's not implemented for new-install only. Porting from new-build to new-install should be easier than from v1-install to new-install. Unless there is a good reason it wasn't implemented for new-install specificaly, but I doubt it. Is there? Edit3: I'm leaving this for now until I get any feedback. |
@typedrat, @fgaz: do you by chance remember what was the original plan for new-install and new-build regarding stripping and static linking? Right now new-build links statically, if requested, but new-install silently ignores the request. Both silently ignore stripping request. I'm not counting on any design doc, but your memory or even just gut feeling would already give us something to work with. |
I'd say yes, especially if v1- did. As for why,
I don't think there was a specific plan for new-install except "do what new-build does", and I wasn't yet following cabal's development when new-build planning happened |
@fgaz: thank you. In that case, I think the plan to fix this issue, at last re stripping, but possibly also for static linking, can be to port the chunks of v1 code to v2 and otherwise scavenge and transplant until we reach feature parity in this respect between v1, v2, build and install. If nobody volunteers, I may attempt that at some point, given that I've already code-dived a bit. |
Something we need to investigate before enabling stripping (and we'd need to open GHC issue if it's GHC's fault, or perhaps open just in case): sometimes stripping breaks statically linked executables. Citing @phadej:
Links from Oleg related to linking in GHC vs in cabal and where to open the issue: #7339, #7382 |
It is a Cabal issue, because I'm experiencing it on MacOS. See #6688. |
The |
Workaround for haskell/cabal#7236
I'm going to look into these issues. |
The target of `cabal install` is not considered to be a local package, which means local configuration (e.g. in cabal.project, or flags like --enable-profiling) does not apply to it. In 76670eb, we changed the behaviour to applying the local flags to cabal install targets, but it used the literal target string as a package name to which the flags were additionally applied. However, `cabal install` targets are NOT necessarily package names, so, e.g., if we did `cabal install exe:mycomp`, the local flags would not apply since "exe:mycomp" is not a recognized /package/. The solution is to parse the target selectors first, and apply the local flags to the package of the resolved targets. Fixes haskell#7297 haskell#8909 and the install part of haskell#7236
It turns out that we don't ever attempt to strip the executable if it is not being installed. Maybe we should, or perhaps not. The current state of affairs is that with #9697, |
The target of `cabal install` is not considered to be a local package, which means local configuration (e.g. in cabal.project, or flags like --enable-profiling) does not apply to it. In 76670eb, we changed the behaviour to applying the local flags to cabal install targets, but it used the literal target string as a package name to which the flags were additionally applied. However, `cabal install` targets are NOT necessarily package names, so, e.g., if we did `cabal install exe:mycomp`, the local flags would not apply since "exe:mycomp" is not a recognized /package/. The solution is to parse the target selectors first, and apply the local flags to the package of the resolved targets. Fixes haskell#7297 haskell#8909 and the install part of haskell#7236
The target of `cabal install` is not considered to be a local package, which means local configuration (e.g. in cabal.project, or flags like --enable-profiling) does not apply to it. In 76670eb, we changed the behaviour to applying the local flags to cabal install targets, but it used the literal target string as a package name to which the flags were additionally applied. However, `cabal install` targets are NOT necessarily package names, so, e.g., if we did `cabal install exe:mycomp`, the local flags would not apply since "exe:mycomp" is not a recognized /package/. The solution is to parse the target selectors first, and apply the local flags to the package of the resolved targets. Fixes haskell#7297, haskell#8909, the install part of haskell#7236, haskell#8529, haskell#7832
The target of `cabal install` is not considered to be a local package, which means local configuration (e.g. in cabal.project, or flags like --enable-profiling) does not apply to it. In 76670eb, we changed the behaviour to applying the local flags to cabal install targets, but it used the literal target string as a package name to which the flags were additionally applied. However, `cabal install` targets are NOT necessarily package names, so, e.g., if we did `cabal install exe:mycomp`, the local flags would not apply since "exe:mycomp" is not a recognized /package/. The solution is to parse the target selectors first, and apply the local flags to the package of the resolved targets. Fixes haskell#7297, haskell#8909, the install part of haskell#7236, haskell#8529, haskell#7832
The target of `cabal install` is not considered to be a local package, which means local configuration (e.g. in cabal.project, or flags like --enable-profiling) does not apply to it. In 76670eb, we changed the behaviour to applying the local flags to cabal install targets, but it used the literal target string as a package name to which the flags were additionally applied. However, `cabal install` targets are NOT necessarily package names, so, e.g., if we did `cabal install exe:mycomp`, the local flags would not apply since "exe:mycomp" is not a recognized /package/. The solution is to parse the target selectors first, and apply the local flags to the package of the resolved targets. Fixes haskell#7297, haskell#8909, the install part of haskell#7236, haskell#8529, haskell#7832
The target of `cabal install` is not considered to be a local package, which means local configuration (e.g. in cabal.project, or flags like --enable-profiling) does not apply to it. In 76670eb, we changed the behaviour to applying the local flags to cabal install targets, but it used the literal target string as a package name to which the flags were additionally applied. However, `cabal install` targets are NOT necessarily package names, so, e.g., if we did `cabal install exe:mycomp`, the local flags would not apply since "exe:mycomp" is not a recognized /package/. The solution is to parse the target selectors first, and apply the local flags to the package of the resolved targets. Fixes haskell#7297, haskell#8909, the install part of haskell#7236, haskell#8529, haskell#7832
The target of `cabal install` is not considered to be a local package, which means local configuration (e.g. in cabal.project, or flags like --enable-profiling) does not apply to it. In 76670eb, we changed the behaviour to applying the local flags to cabal install targets, but it used the literal target string as a package name to which the flags were additionally applied. However, `cabal install` targets are NOT necessarily package names, so, e.g., if we did `cabal install exe:mycomp`, the local flags would not apply since "exe:mycomp" is not a recognized /package/. The solution is to parse the target selectors first, and apply the local flags to the package of the resolved targets. Fixes haskell#7297, haskell#8909, the install part of haskell#7236, haskell#8529, haskell#7832
The target of `cabal install` is not considered to be a local package, which means local configuration (e.g. in cabal.project, or flags like --enable-profiling) does not apply to it. In 76670eb, we changed the behaviour to applying the local flags to cabal install targets, but it used the literal target string as a package name to which the flags were additionally applied. However, `cabal install` targets are NOT necessarily package names, so, e.g., if we did `cabal install exe:mycomp`, the local flags would not apply since "exe:mycomp" is not a recognized /package/. The solution is to parse the target selectors first, and apply the local flags to the package of the resolved targets. Fixes haskell#7297, haskell#8909, the install part of haskell#7236, haskell#8529, haskell#7832
Considering that it is currently "not a bug" that stripping is only done on install, this ticket is now fixed by #9697. If you want/think stripping should also be done after building do open a new ticket about it. |
The target of `cabal install` is not considered to be a local package, which means local configuration (e.g. in cabal.project, or flags like --enable-profiling) does not apply to it. In 76670eb, we changed the behaviour to applying the local flags to cabal install targets, but it used the literal target string as a package name to which the flags were additionally applied. However, `cabal install` targets are NOT necessarily package names, so, e.g., if we did `cabal install exe:mycomp`, the local flags would not apply since "exe:mycomp" is not a recognized /package/. The solution is to parse the target selectors first, and apply the local flags to the package of the resolved targets. Fixes haskell#7297, haskell#8909, the install part of haskell#7236, haskell#8529, haskell#7832
Description
Various combinations of
configure
/build
/install
and--enable-executable-static
/--enable-executable-stripping
do not produce a static + stripped executable.System information
Alpine Linux - musl libc and busybox.
Setup
Steps to reproduce
cabal install
, directly:cabal install --installdir=. --install-method=copy --enable-executable-stripping --enable-executable-static
observation:
verbose output:
Oof, that didn't go well at all. Dynamic, not stripped.
cabal build
:observation:
verbose output:
Close, but no cigar. Static, not stripped.
cabal configure
followed bycabal build
:observation:
verbose output:
Still static but not stripped...
So the conclusion is that stripping just doesn't work and static linking is unreliable, at least for me.
This is either a pretty sad state of affairs, or I am missing something very obvious.
Additionally, I also find the interaction between the commands in 2. and 3. and
cabal install
to be a bit weird, the executable is getting rebuilt even with the same flags set ininstall
when runningcabal install
even though nothing changed and everything should be cached. But that is another topic.Expected behavior
Stripped and statically linked executables.
(
tst: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped
)Additional context
Ghc and cabal were installed via ghcup in a clean environment.
The text was updated successfully, but these errors were encountered: