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

emacs: Make gccemacs build on darwin #94637

Merged
merged 10 commits into from Sep 2, 2020

Conversation

antifuchs
Copy link
Contributor

@antifuchs antifuchs commented Aug 4, 2020

Motivation for this change

To allow macOS/darwin users to build Emacs with the native-comp feature. These changes are all for problems that on Darwin, result in broken binary installs and failures to resolve the emacs derivation.

Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS linux)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • 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 nixpkgs-review --run "nixpkgs-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Ensured that relevant documentation is up to date
  • Fits CONTRIBUTING.md.

@ofborg ofborg bot added the 6.topic: darwin Running or building packages on Darwin label Aug 4, 2020
@antifuchs antifuchs changed the title [wip] Make gccemacs build on darwin [wip] emacs: Make gccemacs build on darwin Aug 4, 2020
@antifuchs
Copy link
Contributor Author

@evanrelf I decided to open a real PR & take this here from #93716. Am currently building libgccjit from this branch and I suspect that this time, the emacs configure stage won't error out... but it'll be 2 hours /:

@ofborg ofborg bot added the 6.topic: emacs label Aug 4, 2020
@evanrelf
Copy link

evanrelf commented Aug 4, 2020

@antifuchs Awesome! And thanks for letting me know 🙂

@ofborg ofborg bot requested review from jwiegley, lovek323 and peti August 4, 2020 05:53
@antifuchs antifuchs changed the title [wip] emacs: Make gccemacs build on darwin emacs: Make gccemacs build on darwin Aug 4, 2020
@antifuchs
Copy link
Contributor Author

antifuchs commented Aug 4, 2020

OK, I finally got this to build properly, and it looks like the native-comp emacs branch is working on this Darwin installation:

  • native GUI
  • compilation at runtime
  • json via libjason

@antifuchs
Copy link
Contributor Author

One more thing that is currently failing:

  • /nix/store/6s7nbin6khpmc6f6nwvcxl3m3h48c3fn-binutils-wrapper-2.31.1/bin/ld: line 207: /nix/store/7gmqwn05rw84kx06wyqhg7ciyn34j0qa-binutils-2.31.1/bin/ld: No such file or directory - seems like binutils aren't present, preventing native-compile from working properly (it compiles to .elc regardless)

@antifuchs
Copy link
Contributor Author

So this looks like the default native-compilation $PATH that gets set uses the binutils-wrapper ld, which exists, but the wrapped ld doesn't: there's actually a comment about it in the darwin binutils wrappers. I'm not sure what to do about this, or where this comes from (and why AOT compilation during build works, it produces .eln files then!)

@Mic92 Mic92 requested a review from LnL7 August 5, 2020 06:10
@@ -251,7 +251,7 @@ postInstall() {
fi

if type "install_name_tool"; then
for i in "${!outputLib}"/lib/*.*.dylib; do
for i in "${!outputLib}"/lib/*.*.dylib "${!outputLib}"/lib/*.so.[0-9]; do
Copy link
Member

Choose a reason for hiding this comment

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

Is it a bug in gcc buildsystem that they install libgccjit as .so file?

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, looks like it. They still make weird linux-soname based assumptions around how the structure works, but I think we could just set this as a make variable (or patch it) to fix. Probably the better way to fix it!

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member

@Mic92 Mic92 Aug 5, 2020

Choose a reason for hiding this comment

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

Anyway if you don't patch the build system would it not be better to rename it from .so to .dylib?

@antifuchs
Copy link
Contributor Author

antifuchs commented Aug 8, 2020

So as far as I can tell, on Darwin you must pass linker options (especially the ones used to find libgccjit) to ld via command-line args, and the LIBRARY_PATH env variable does nothing, even with wrapper scripts. That complicates post-install AOT compilation a bit. I filed an enhancement request with the gnu emacs tracker, to let users set driver options, but until then I don't think this can work... unless we build & ship a custom wrapper script.

@FRidh FRidh added this to WIP in Staging via automation Aug 15, 2020
Staging automation moved this from WIP to Ready Aug 17, 2020
@antifuchs
Copy link
Contributor Author

antifuchs commented Aug 24, 2020

Status update on this:

  • I have to fix merge conflicts on this.

  • There's a change pending that will add the ability to set linker paths directly via an elisp variable, in https://github.com/emacs-mirror/emacs/tree/scratch/native-comp-gcc-driver-options (I'm building emacs against my changes).

  • With that change, I have an outstanding change to make use of that facility, which allows native-comp emacs to run and compile elisp on Darwin.

  • I also tried actioning @Mic92's suggestion of patching the libgccjit build process, but could not figure out a way yet to make it properly install the versioned dylib file and a symlink to it... something always clobbers that final symlink. As re-building libgccjit takes 3-4 hours each go-around and the problem occurs at the final install phase, I'd prefer to stick to installing the .so for now (as it works regardless of file name), and fix that build process in a follow-up PR.

I'll push changes to make this happen as soon as the scratch branch is on the native-comp feature branch, hopefully the next couple of days!

The default `strip` invocation tries to strip global symbols from the
library, and refuses because those are indirect symbol table
references.
@mjlbach

This comment has been minimized.

This changes PATH such that the correct linker can be found to
construct .eln files at runtime.
Since Darwin's linker does not understand LIBRARY_PATH, we have to set
the library path as explicit linker flags: This requires a very recent
feature/native-comp emacs revision, but it runs on Darwin and
correctly compiles files at runtime.
It's not necessary to use strip -x otherwise, so let's just use it for
the JIT library.
This is the portable way to address the system-appropriate libc,
better than conditionalizing by (darwin/GNU) system or using either
one.
@antifuchs
Copy link
Contributor Author

antifuchs commented Aug 30, 2020

I'm not able to test this branch locally on linux as p11-kit tests fail while building emacs. This isn't happening on master for me.

That's curious - I could build this derivation just fine on Ubuntu 18.04. I am, however, getting a weird test failure in something else that this PR doesn't touch /: (Update: That was a timing problem in the python pytest suite; installing that derivation in single-core mode got me a functional emacs on my Linux box).

This way, we don't have to drag clang or binutils/binutils-wrapped
into the emacs closure, and can instead rely on using the correct one
for the platform we're running on.

Co-authored-by: Matthew Bauer <mjbauer95@gmail.com>
The -B flag to gcc (and libgccjit) allows us to specify where it can
find things it needs to correctly compile code (both programs and
libraries) without adjusting any environmental flags: So, no need to
wrap the program for a PATH entry containing binutils, and no need to
explicitly pass a linker path anymore.
The -B flag to gcc (and libgccjit) allows us to specify where it can
find things it needs to correctly compile code (both programs and
libraries) without adjusting any environmental flags: So, no need to
wrap the program for a PATH entry containing binutils, and no need to
explicitly pass a linker path anymore.
@adisbladis adisbladis merged commit 6fc3562 into NixOS:staging Sep 2, 2020
Staging automation moved this from Ready to Done Sep 2, 2020
@antifuchs antifuchs deleted the gccemacs-on-darwin branch September 2, 2020 22:20
@rcorrear
Copy link

rcorrear commented Sep 4, 2020

Hi all! Been following the discussion lately, haven't tried it but thanks for all the effort! A question comes to mind, has anyone tried the patch for "emacsMac" here?

@mjlbach
Copy link
Contributor

mjlbach commented Sep 4, 2020

@rcorrear If you mean, will native-compilation (gccemacs) work with the Mitsuharu's emacs-mac repository, the answer is no. Native compilation is currently in a feature branch, and it would be nontrivial to merge mitsuharu's work. You'll likely have to wait until native compilation is merged into emacs.

@rcorrear
Copy link

rcorrear commented Sep 4, 2020

@mjlbach yeah, that's what I wanted to know, thanks!

@adelbertc
Copy link
Contributor

Apologies if this is an inappropriate place to ask, but does anyone know if there is a cached build of emacsGcc on macOS available? I just tried building it with something like:

    emacsPackagesNg =
      let
        emacs-overlay =
          import (builtins.fetchTarball https://github.com/nix-community/emacs-overlay/archive/master.tar.gz);

        pkgs = import (fetchGit {
          url = "https://github.com/NixOS/nixpkgs.git";
          rev = "6fc3562432357cdbcbb30804b47feacfac452acb"; # this is this PR's merge commit
        }) {
          overlays = [ emacs-overlay ];
        };
      in
        pkgs.emacsPackagesNgGen pkgs.emacsGcc;

on a 2017 13" MacBook Pro and it was compiling from like 11:30AM - 7:30PM before I Ctrl+C'd it, and even after all that time it was still building LLVM things 😬

@mjlbach
Copy link
Contributor

mjlbach commented Sep 20, 2020

If you want, you can use my overlay/cachix which has CI for macOS (only on the linked branch).

https://github.com/mjlbach/emacs-pgtk-nativecomp-overlay/tree/cleanups

@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/lsopenurlswithrole-error-opening-nix-installed-application-emacs-native-comp-on-macos/9132/1

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

Successfully merging this pull request may close these issues.

None yet