Skip to content

haskell: work around linker limits on Mac OS X Sierra. #25537

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

Merged
merged 2 commits into from
May 5, 2017

Conversation

judah
Copy link
Contributor

@judah judah commented May 5, 2017

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.

Sorry, something went wrong.

Verified

This commit was signed with the committer’s verified signature. The key has expired.
LnL7 Daiderd Jordan
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.
@mention-bot
Copy link

@judah, thanks for your PR! By analyzing the history of the files in this pull request, we identified @peti, @cstrahan and @dmjio to be potential reviewers.

@judah
Copy link
Contributor Author

judah commented May 5, 2017

cc @shlevy

@LnL7 LnL7 added 6.topic: darwin Running or building packages on Darwin 6.topic: haskell labels May 5, 2017
Copy link
Member

@peti peti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder about the strange way the Darwin-specific code in integrated.

@@ -228,6 +228,25 @@ stdenv.mkDerivation ({
configureFlags+=" --extra-lib-dirs=$p/lib"
fi
done
if "${if stdenv.isDarwin then "true" else "false"}"; then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was mostly due to my lack of familiarity with Nix. I've switched to @shlevy 's suggestion.

@@ -97,6 +97,29 @@ symlinkJoin {
fi
done
# Work around a linker limit in Mac OS X Sierra (see generic-builder.nix):
if "${if stdenv.isDarwin then "true" else "false"}"; then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dito

Copy link
Member

@shlevy shlevy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Untested, but overall looks great! Can you just change the stylistic nit (in both files)?

@@ -228,6 +228,25 @@ stdenv.mkDerivation ({
configureFlags+=" --extra-lib-dirs=$p/lib"
fi
done
if "${if stdenv.isDarwin then "true" else "false"}"; then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: prefer

'' + (stdenv.lib.optionalString stdenv.isDarwin ''
  darwin-only-command
'') + ''
  the-rest
''

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, thanks for the suggestion.

Verified

This commit was signed with the committer’s verified signature. The key has expired.
LnL7 Daiderd Jordan
@shlevy
Copy link
Member

shlevy commented May 5, 2017

@judah You've tested the latest?

@judah
Copy link
Contributor Author

judah commented May 5, 2017

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.

@@ -228,6 +228,23 @@ stdenv.mkDerivation ({
configureFlags+=" --extra-lib-dirs=$p/lib"
fi
done
'' + (optionalString stdenv.isDarwin ''
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we also want to skip this when building a static library/executable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@judah
Copy link
Contributor Author

judah commented May 5, 2017

Confirmed that the build still passed after the fix.

@dmjio
Copy link
Member

dmjio commented May 5, 2017

LGTM 👍

# libraries) from all the dependencies.
local dynamicLinksDir="$out/lib/links"
mkdir -p $dynamicLinksDir
local foundDylib=false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@shlevy shlevy merged commit 2caa7b8 into NixOS:master May 5, 2017
@peti
Copy link
Member

peti commented May 7, 2017

@judah, can you please address @cstrahan's comments from #25537 (review)?

@shlevy shlevy mentioned this pull request Jul 21, 2017
8 tasks
infinisil added a commit to infinisil/nixpkgs that referenced this pull request Jan 29, 2020
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.
peti pushed a commit that referenced this pull request Jan 31, 2020
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.
peti pushed a commit that referenced this pull request Jan 31, 2020
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.
anna328p pushed a commit to anna328p/nixpkgs that referenced this pull request Feb 2, 2020
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.
jpgu-epam pushed a commit to jpgu-epam/nixpkgs that referenced this pull request Feb 4, 2020
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.
@gnprice gnprice mentioned this pull request Apr 2, 2020
10 tasks
Gabriella439 added a commit to MercuryTechnologies/nixpkgs that referenced this pull request Dec 1, 2022
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.
@Janik-Haag Janik-Haag added the 12. first-time contribution This PR is the author's first one; please be gentle! label Jun 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
6.topic: darwin Running or building packages on Darwin 6.topic: haskell 12. first-time contribution This PR is the author's first one; please be gentle!
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants