haskell: work around linker limits on Mac OS X Sierra.#25537
haskell: work around linker limits on Mac OS X Sierra.#25537shlevy merged 2 commits intoNixOS:masterfrom
Conversation
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.
|
cc @shlevy |
peti
left a comment
There was a problem hiding this comment.
I wonder about the strange way the Darwin-specific code in integrated.
| fi | ||
| done | ||
|
|
||
| if "${if stdenv.isDarwin then "true" else "false"}"; then |
There was a problem hiding this comment.
Considering the fact you have conditionals in the Nix language, why is that feature used here to create input for yet another level of conditional that's evaluated by the shell? This looks awkward. Is there a deeper reason for this implementation choice?
There was a problem hiding this comment.
It was mostly due to my lack of familiarity with Nix. I've switched to @shlevy 's suggestion.
| done | ||
|
|
||
| # Work around a linker limit in Mac OS X Sierra (see generic-builder.nix): | ||
| if "${if stdenv.isDarwin then "true" else "false"}"; then |
shlevy
left a comment
There was a problem hiding this comment.
Untested, but overall looks great! Can you just change the stylistic nit (in both files)?
| fi | ||
| done | ||
|
|
||
| if "${if stdenv.isDarwin then "true" else "false"}"; then |
There was a problem hiding this comment.
Nit: prefer
'' + (stdenv.lib.optionalString stdenv.isDarwin ''
darwin-only-command
'') + ''
the-rest
''There was a problem hiding this comment.
Done, thanks for the suggestion.
|
@judah You've tested the latest? |
|
Running the test again now. It will probably take a couple hours since it needs to re-bootstrap GHC. I'll ping back on this thread once I've seen the test pass. |
| configureFlags+=" --extra-lib-dirs=$p/lib" | ||
| fi | ||
| done | ||
| '' + (optionalString stdenv.isDarwin '' |
There was a problem hiding this comment.
I think we also want to skip this when building a static library/executable.
There was a problem hiding this comment.
It's a no-op in that case since static libraries have the different extension *.a and aren't affected by the dynamic-library-dirs field.
|
Confirmed that the build still passed after the fix. |
|
LGTM 👍 |
| # libraries) from all the dependencies. | ||
| local dynamicLinksDir="$out/lib/links" | ||
| mkdir -p $dynamicLinksDir | ||
| local foundDylib=false |
There was a problem hiding this comment.
I don't see where foundDylib is used. Perhaps you wanted to set foundDylib to "true" in the for loop below, and then if no dylib is found, delete the (empty) $out/lib/links dir?
There was a problem hiding this comment.
Sorry about that; sent out #25602 to remove the line.
Originally I was going to add more complicated logic to handle the different Linux/Mac cases (since the former uses a different extension for shared libraries). But the call to stdenv.isDarwin has an equivalent effect.
|
@judah, can you please address @cstrahan's comments from #25537 (review)? |
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 whena 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-dirsfield.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
hscolourwhich is built bygeneric-builder.nix.Tested by building the
stackbinary as described in #22810.