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

Distributable Binaries For Macos #185

Merged
merged 8 commits into from
Feb 16, 2023
Merged

Distributable Binaries For Macos #185

merged 8 commits into from
Feb 16, 2023

Conversation

d-xo
Copy link
Collaborator

@d-xo d-xo commented Jan 31, 2023

Description

This PR lets us build binaries for macos that only link dynamically against libs that we can be sure will be provided by macos itself. All other non system c dependencies (secp256k1, libff, gmp, ...) are linked statically. This is required since full static linking is not supported on macos.

Cabal doesn't seem to offer friendly config options that would make the production of this kind of binary easy, and in the end we are relying on some behaviour that is at best poorly documented (and quite possibly implicit / unintended):

  • ghc / cabal allows users to pass library directories to be searched during linking
  • if these library dirs contain both static and dynamic versions of some required lib, it will be linked dynamically
  • if they contain only static versions of the lib, it will be linked statically

We can therefore get the behaviour we want by ensuring that we pass only static versions of the libs that we wish to be statically linked. Once this is done, we can do a final piece of denixification to rewrite the library paths for the remaining dynamic libs to point to /usr/lib/ instead of the nix store, giving us "static" binaries that can run without requiring the installation of additional libraries on any x86 macos system.

I tested the updated release pipeline on a fork: https://github.com/d-xo/hevm/actions/runs/4049153909 which produced binaries that can be tested here: https://github.com/d-xo/hevm/releases/tag/release%2F0.50.3.

output of otool -L on the resulting macos binary:

	/usr/lib/libstdc++.dylib (compatibility version 1.0.0, current version 1.0.0)
	/usr/lib/libiconv.dylib (compatibility version 7.0.0, current version 7.0.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.60.2)

Checklist

  • tested locally
  • added automated tests
  • updated the docs
  • updated the changelog

fully static executables are not supported on macos, and it is required
to link dynamically against core system libraries (e.g. libSystem).

we therefore produce here binaries for macos that have all c deps linked
statically with the exception of:

- libcxx
- libiconv
- libsystem

we can be confident that these will always be provided at runtime by
macos itself.

convincing cabal / ghc to produce such a binary was pretty obscure, and
we rely on some (afaict) undocumented behaviour where passing a library
directory to cabal via `--extra-library-dirs` that contains only static
libs (i.e. *.a files) and no dynamic libs (i.e. *.dylib files) results
in static linkage, while passing a lib dir that contains both results in
dynamic linkage.
@d-xo d-xo linked an issue Jan 31, 2023 that may be closed by this pull request
Copy link
Collaborator

@msooseth msooseth left a comment

Choose a reason for hiding this comment

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

LGTM

flake.nix Show resolved Hide resolved
@d-xo d-xo merged commit 7e1dbf3 into main Feb 16, 2023
@minimapletinytools
Copy link

goodness 😭

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Static Binaries for MacOS
3 participants