-
-
Notifications
You must be signed in to change notification settings - Fork 14.6k
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
macOS Sierra and Haskell "malformed mach-o: load commands size" #22810
Comments
This is crushing. Basically none of my haskell projects are executable. |
^ same for me |
I don't see a reasonable solution to this issue other than to disable dynamic linking of Haskell libraries on Darwin. |
How can one accomplish this? |
Like http://nixos.org/nixpkgs/manual/#how-to-build-with-profiling-enabled, but instead of
|
as a preliminary report, I tried this with our project that was bombing by using: haskellPackageOverrides = self: super: {
mkDerivation = args: super.mkDerivation (args // {
enableSharedExecutables = false;
enableSharedLibraries = false;
});
}; and it failed due to a build failure with
I haven't tracked down yet for sure why this fails. It doesn't seem like |
Here's a hacky way to workaround this:
@peti would you be ok with something like this for Darwin only? Would be happy to prepare a PR. |
@dajmaki, yeah, that would be a viable workaround, I suppose. |
@dajmaki I was thinking about something like this with rpath before. This will cause conflicts when using multiple haskell packages in a |
I just got hit with this. Still no path forward? |
Just got bitten by this as well. |
(whoops commented from my work account 'dajmaki', switching to my private one). @LnL7 could you give an example of a conflict? I'm not quite following. EDIT: Another problem with my workaround is that if one is building a statically linked executable this will include the dynamic libraries in the closure for no reason. |
I get this on Sierra once I pass That makes no sense to me, why is it suddenly using longer path? |
Assigning myself to keep this on my radar, but no guarantee I'll be able to get too it in a timely manner. |
The Sierra linker added a limit on the number of paths that any one dynamic library (`*.dylib`) can reference. This causes problems when a Haskell library has many immediate dependencies (NixOS#22810). We follow a similar fix as GHC/Cabal/Stack: for each derivation, create a new directory with symlinks to all the dylibs of its immediate dependencies, and patch its package DB to reference that directory using the new `dynamic-library-dirs` field. Note that this change is a no-op for older versions of GHC, i.e., they will continue to fail on some packages as before. Also note that this change causes the bootstrapped versions of GHC to be recompiled, since they depend on `hscolour` which is built by `generic-builder.nix`. Tested by building the `stack` binary as described in NixOS#22810.
The Sierra linker added a limit on the number of paths that any one dynamic library (`*.dylib`) can reference. This causes problems when a Haskell library has many immediate dependencies (NixOS#22810). We follow a similar fix as GHC/Cabal/Stack: for each derivation, create a new directory with symlinks to all the dylibs of its immediate dependencies, and patch its package DB to reference that directory using the new `dynamic-library-dirs` field. Note that this change is a no-op for older versions of GHC, i.e., they will continue to fail on some packages as before. Also note that this change causes the bootstrapped versions of GHC to be recompiled, since they depend on `hscolour` which is built by `generic-builder.nix`. Tested by building the `stack` binary as described in NixOS#22810.
The Sierra linker added a limit on the number of paths that any one dynamic library (`*.dylib`) can reference. This causes problems when a Haskell library has many immediate dependencies (#22810). We follow a similar fix as GHC/Cabal/Stack: for each derivation, create a new directory with symlinks to all the dylibs of its immediate dependencies, and patch its package DB to reference that directory using the new `dynamic-library-dirs` field. Note that this change is a no-op for older versions of GHC, i.e., they will continue to fail on some packages as before. Also note that this change causes the bootstrapped versions of GHC to be recompiled, since they depend on `hscolour` which is built by `generic-builder.nix`. Tested by building the `stack` binary as described in #22810. (cherry picked from commit 7131e06)
I had an idea for a workaround here... not sure it belongs in Nix though. Mach-O dylibs have the option to re-export other dylibs. We can create "intermediate" dylibs that re-export all the other libraries, as deep as we want. So if the first re-exporting dylib fills up, we create another one. And if needed, we do it recursively. I hope we don't get that big though 😄 |
I don't know how we could solve this for stack in Nix itself. We have about 300 dependencies, each taking on average about 100 chars for the rpath path, resulting into ~33000 chars, just above the limit. I think stack will need to handle this similarly as we do in Nix :) |
What if we package dyld https://opensource.apple.com/tarballs/dyld/dyld-421.1.tar.gz and patch But this probably means we have to bump our SDK to 10.12 |
Pre-10.10 we might have been able to use a custom |
Holy crap could Darwin be more hostile to developers? 😠 |
sure! they could require everything to be signed |
Has anyone opened a ticket with Apple (rdar or Radar or whatever they call it) regarding MAX_MACH_O_HEADER_AND_LOAD_COMMANDS_SIZE? Might be best to fix the problem at its source... assuming they actually listen to their developers... |
I can only hope that since Apple is so against static linking they will be slightly more sympathetic. |
Marking closed since #27536 is in, reopen if this is still broken. |
Previously the package conf files were handled without paying attention to the fact that it's pretty-printed output. One problem was discovered with GHC 8.8.1 on Darwin, where the dynamic-library-dirs first field seems to have increased in length, meaning while before it was dynamic-library-dirs: some-small-directory-name some-more-directories Now it is dynamic-library-dirs: some-larger-directory-name some-more-directories Which breaks the code installed for NixOS#25537, because that assumed the former format, resulting in the reoccurence of the bug in NixOS#22810, see infinisil/all-hies#43 This commit fixes this by "unprettyfying" the package conf files before processing them.
Previously the package conf files were handled without paying attention to the fact that it's pretty-printed output. One problem was discovered with GHC 8.8.1 on Darwin, where the dynamic-library-dirs first field seems to have increased in length, meaning while before it was dynamic-library-dirs: some-small-directory-name some-more-directories Now it is dynamic-library-dirs: some-larger-directory-name some-more-directories Which breaks the code installed for #25537, because that assumed the former format, resulting in the reoccurence of the bug in #22810, see infinisil/all-hies#43 This commit fixes this by "unprettyfying" the package conf files before processing them. Closes #78738.
Previously the package conf files were handled without paying attention to the fact that it's pretty-printed output. One problem was discovered with GHC 8.8.1 on Darwin, where the dynamic-library-dirs first field seems to have increased in length, meaning while before it was dynamic-library-dirs: some-small-directory-name some-more-directories Now it is dynamic-library-dirs: some-larger-directory-name some-more-directories Which breaks the code installed for #25537, because that assumed the former format, resulting in the reoccurence of the bug in #22810, see infinisil/all-hies#43 This commit fixes this by "unprettyfying" the package conf files before processing them. Closes #78738.
Previously the package conf files were handled without paying attention to the fact that it's pretty-printed output. One problem was discovered with GHC 8.8.1 on Darwin, where the dynamic-library-dirs first field seems to have increased in length, meaning while before it was dynamic-library-dirs: some-small-directory-name some-more-directories Now it is dynamic-library-dirs: some-larger-directory-name some-more-directories Which breaks the code installed for NixOS#25537, because that assumed the former format, resulting in the reoccurence of the bug in NixOS#22810, see infinisil/all-hies#43 This commit fixes this by "unprettyfying" the package conf files before processing them. Closes NixOS#78738.
Previously the package conf files were handled without paying attention to the fact that it's pretty-printed output. One problem was discovered with GHC 8.8.1 on Darwin, where the dynamic-library-dirs first field seems to have increased in length, meaning while before it was dynamic-library-dirs: some-small-directory-name some-more-directories Now it is dynamic-library-dirs: some-larger-directory-name some-more-directories Which breaks the code installed for NixOS#25537, because that assumed the former format, resulting in the reoccurence of the bug in NixOS#22810, see infinisil/all-hies#43 This commit fixes this by "unprettyfying" the package conf files before processing them. Closes NixOS#78738.
The workaround that this change deletes was initially contributed in NixOS#25537 to mitigate NixOS#22810 until a more permanent solution could be devised. That more permanent solution was eventually contributed in NixOS#27536, which now obviates the initial workaround, so this change removes it.
The Sierra linker added a limit on the number of paths that any one dynamic library (`*.dylib`) can reference. This causes problems when a Haskell library has many immediate dependencies (NixOS#22810). We follow a similar fix as GHC/Cabal/Stack: for each derivation, create a new directory with symlinks to all the dylibs of its immediate dependencies, and patch its package DB to reference that directory using the new `dynamic-library-dirs` field. Note that this change is a no-op for older versions of GHC, i.e., they will continue to fail on some packages as before. Also note that this change causes the bootstrapped versions of GHC to be recompiled, since they depend on `hscolour` which is built by `generic-builder.nix`. Tested by building the `stack` binary as described in NixOS#22810. (cherry picked from commit 7131e06)
Issue description
The (at this point infamous) load commands size problem still occurs on nixpkgs even after the GHC 8.0.2 / LTS 8.0 update.
I'll try to summarize the underlying issue, but please be aware I'm not an expert and am just stitching together things from other issues. Please correct me if the details are wrong.
This issue is due to a change in macOS's linker in Sierra which limits the mach-O linker load commands to 32768 bytes. Those load commands are dominated by RPATH entries and nix exacerbates the issue greatly by having a ton of long named directories, around one per dependency.
In GHC (https://ghc.haskell.org/trac/ghc/ticket/12479), Stack (commercialhaskell/stack#2577), and Cabal (haskell/cabal#3955, haskell/cabal#3982, et al) it looks like it was resolved by carefully managing the location of dylibs to all be located in the same place so that only one RPATH needed emitting (https://ghc.haskell.org/trac/ghc/ticket/12479#comment:42, probably others).
I could imagine a similar solution could be cooked up by generic-builder and with-package-wrapper to create a lib directory for each haskell derivation to build that has symlinks for each transient dependency, but I'm really quite new to all this so I haven't attempted it yet.
Steps to reproduce
nix-build stack-a5b8d468.nix
withstack-a5b8d468.nix
:On my system yields:
stack-a5b8d468.txt
Technical details
The text was updated successfully, but these errors were encountered: