Skip to content
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

Linking hack for macOS Sierra #27536

Merged
merged 10 commits into from
Aug 3, 2017

Conversation

Ericson2314
Copy link
Member

Motivation for this change

Sierra imposes and arbitrary limit on mach-o header sizes, preventing too many libraries form being linkned. Following @copumpkin's suggestion, we recursively divide the libraries between children using -reexport-l until the header size is presumed small enough.

"Fixes" #22810

Things done
  • Tested using sandboxing
    (nix.useSandbox on NixOS,
    or option build-use-sandbox in nix.conf
    on non-NixOS)
  • Built on platform(s)
    • NixOS
    • macOS
    • Linux
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nox --run "nox-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Fits CONTRIBUTING.md.

@mention-bot
Copy link

@Ericson2314, thanks for your PR! By analyzing the history of the files in this pull request, we identified @pikajude, @edolstra, @vcunat, @LnL7 and @copumpkin to be potential reviewers.

@Ericson2314
Copy link
Member Author

I'm getting ld: file not found: /nix/store/vjbaqsdys43yay0ynzi00v82d9r8xyw4-clang-4.0.0/lib/libLTO.dylib for reasons I know not.

@LnL7
Copy link
Member

LnL7 commented Jul 21, 2017

We don't have LTO support, not sure why you're running into that tho. See #19312

@shlevy
Copy link
Member

shlevy commented Jul 21, 2017

@Ericson2314 The patch is not much shorter than the wrapper itself, any chance we can either factor out the common bits better or just have a second wrapper? 😕

@domenkozar
Copy link
Member

domenkozar commented Jul 21, 2017

Another approach would be patching Cabal (although I'm not sure how much would break): commercialhaskell/stack#3209 (comment)

EDIT: not to discourage this work (thank you John!), I'm still thinking about possible alternatives since it's mostly Haskell that's affected.

@Ericson2314
Copy link
Member Author

@shlevy Ah, second inner wrapper with mutual recursion makes a lot of sense—didn't think of that I'll switch.

@domenkozar
Copy link
Member

domenkozar commented Jul 21, 2017

@Ericson2314 so @copumpkin proposed to patch GHC linker and upstream the change, which I think makes more sense. This would fix the issue for non-Nix users which is clearly a more general solution (for Haskell, but not for non-Haskell in Nix).

@shlevy
Copy link
Member

shlevy commented Jul 21, 2017

If this is working I'd rather not have to wait for the GHC linker change... We can always turn this off once we're sure the GHC fix is sufficient

@domenkozar
Copy link
Member

Another potential solution is to use haskell/cabal#3979

@shlevy
Copy link
Member

shlevy commented Jul 21, 2017

@domenkozar is that different from #25537 ?

@domenkozar
Copy link
Member

@shlevy it's not, but then I don't understand how you're still seeing the problem with nixpkgs? :)

@shlevy
Copy link
Member

shlevy commented Jul 21, 2017

@domenkozar Kept adding deps to our haskell packages and hit it again 😄

@domenkozar
Copy link
Member

@Ericson2314
Copy link
Member Author

I think this is a good thing to have around Nixpkgs regardless. Our need is Haskell, but the problem is not Haskell-specific (that is, if other languages can get on our level of code reuse 😏).

'' else ''
wrap ${prefix}ld ${./ld-wrapper.sh}
export ldWrapper=${prefix}ld
wrap ${prefix}ld-reexport-delegate ${./macos-sierra-reexport-hack.sh}
Copy link
Member

Choose a reason for hiding this comment

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

Looks like reexport-delegate isn't referenced anywhere but from this script itself, how does this get called? 😕

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah I had those messed up; fixed later.

@Ericson2314 Ericson2314 force-pushed the appease-sierra-linker branch 2 times, most recently from f3e7d5d to 1286947 Compare July 21, 2017 18:15
@Ericson2314
Copy link
Member Author

Ericson2314 commented Jul 21, 2017

Ok, back to the weird LTO error now. Fixed. -lto_library was not being properly filtered out.

@Ericson2314 Ericson2314 force-pushed the appease-sierra-linker branch 2 times, most recently from d590e3f to 8360abc Compare July 21, 2017 20:50
@Ericson2314
Copy link
Member Author

Now, I get linking failures without a message. Pushing a commit with debug stuff in case anyone else wants to look.

@Ericson2314 Ericson2314 force-pushed the appease-sierra-linker branch 2 times, most recently from 4713d0a to 40825d8 Compare July 25, 2017 19:45
@Ericson2314
Copy link
Member Author

Ericson2314 commented Jul 26, 2017

By the way, yesterday got back to __LINKEDIT problems.

@Ericson2314 Ericson2314 force-pushed the appease-sierra-linker branch 3 times, most recently from f0c4e68 to 5a15ea8 Compare July 27, 2017 19:39
@Ericson2314
Copy link
Member Author

CC @orivej --- you've done some great ld-wrapper work, including improving further on style things I pointed out with the old code, so pinging you lest I forget anything here.

Ericson2314 and others added 7 commits July 31, 2017 17:02
Probably best to override Haskell packages set, or anything else
linking a lot of libraries, with this.
As described in NixOS#18461, MacOS no
longer accepts dylibs which only reexport other dylibs, because their
symbol tables are empty. To get around this, we define an object file
with a single "private extern" symbol, which hopefully won't clobber
anything.
fi

# first half of libs
@binPrefix@ld -macosx_version_min 10.10 -arch x86_64 -dylib \
Copy link
Member Author

Choose a reason for hiding this comment

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

@copumpkin @LnL7 / other Darwin people. I just cargo-culted -macosx_version_min 10.10 from elsewhere, and it's probably necessary. What should it be, if it is passed anything at all?

Copy link
Member

Choose a reason for hiding this comment

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

you can use $MACOSX_DEPLOYMENT_TARGET, that's defined in the stdenv.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks!

@Ericson2314 Ericson2314 force-pushed the appease-sierra-linker branch 2 times, most recently from 9967a96 to 134b713 Compare August 1, 2017 01:20
Also add appropriate `meta.platforms = ...` to each derivation.
@Ericson2314
Copy link
Member Author

Anyone have any opinions on how I've organized things (especially since this last commit)?

@@ -297,7 +297,7 @@ in rec {
initialPath = import ../common-path.nix { inherit pkgs; };
shell = "${pkgs.bash}/bin/bash";

cc = import ../../build-support/cc-wrapper {
cc = lib.callPackageWith {} ../../build-support/cc-wrapper {
Copy link
Contributor

Choose a reason for hiding this comment

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

What does this do?

Copy link
Member Author

@Ericson2314 Ericson2314 Aug 1, 2017

Choose a reason for hiding this comment

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

It adds the override field so I can replace cc while leaving everything else the same. Probably should add a note for that.

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.

Overall LGTM!

case "${!n}" in
-l*) let overflowCount+=1 ;;
-reexport-l*) let overflowCount+=1 ;;
*) ;;
Copy link
Member

Choose a reason for hiding this comment

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

Should we handle -- here or elsewhere?

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh I wasn't aware of it; looking up.

Copy link
Member Author

Choose a reason for hiding this comment

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

You mean just plain paths to dylibs passed in? I didn't see any -- in the man page.

Copy link
Member

Choose a reason for hiding this comment

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

I just mean the standard -- to separate command line flags from files that start with --, no idea if ld supports it but most tools do.

Copy link
Member Author

Choose a reason for hiding this comment

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

@shlevy Well I don't yet handle libraries passed in by path yet at all, in fact.

Copy link
Member Author

Choose a reason for hiding this comment

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

@shlevy Well I don't yet handle libraries passed in by path yet at all, in fact. I'll look into -- and that.

Copy link
Member Author

Choose a reason for hiding this comment

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

Eh, let's just do this as followup if needed.

if bad-asdf
then echo "bad-asdf can succeed on non-sierra, OK" >&2
else echo "bad-asdf should fail on sierra, OK" >&2
fi
Copy link
Member

Choose a reason for hiding this comment

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

I don't love that we won't be able to catch regressions due to the exe just no longer breaking the limit for some reason

Copy link
Member Author

@Ericson2314 Ericson2314 Aug 1, 2017

Choose a reason for hiding this comment

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

Neither do I. But I couldn't think of anything better without much more work.

;;
-l)
echo "cctools LD does not support '-L foo' or '-l foo'" >&2
exit 1
Copy link
Contributor

Choose a reason for hiding this comment

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

How can a general purpose linker just fail to process these args? This is bound to break linking something.

Copy link
Member Author

@Ericson2314 Ericson2314 Aug 1, 2017

Choose a reason for hiding this comment

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

Well, I suppose the man page could be wrong. I thought i tested too but let me double check.

Copy link
Member

Choose a reason for hiding this comment

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

Note that this isn't a failure to parse -Lpath or -llib, just -L path and -l lib. The latter is supported by the GNU toolchain nowadays but can't be expected to work everywhere (and, FWIW, from my understanding this is a limitation of the real linker program, not this script)

Copy link
Contributor

Choose a reason for hiding this comment

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

I didn't know that macOS ld does not support these args without spaces, then there is no problem. This is funny, since it has quite a few arguments that start with -l (-lazy-l* -lazy_library -lazy_framework -lto_library).

Copy link
Member Author

Choose a reason for hiding this comment

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

@orivej Yes I should special case the rest of those--I only did -lto_library.

@Ericson2314 Ericson2314 merged commit cd6c452 into NixOS:master Aug 3, 2017
Ericson2314 added a commit that referenced this pull request Aug 3, 2017
@Ericson2314 Ericson2314 deleted the appease-sierra-linker branch August 3, 2017 21:28
@Ericson2314
Copy link
Member Author

Somebody just ping me if this needs more features

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.
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
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants