Skip to content

Instantly share code, notes, and snippets.

@AllenDang
Last active July 7, 2024 09:42
Show Gist options
  • Save AllenDang/f019593e65572a8e0aefc96058a2d23e to your computer and use it in GitHub Desktop.
Save AllenDang/f019593e65572a8e0aefc96058a2d23e to your computer and use it in GitHub Desktop.
Build gccemacs on MacOS catalina with gcc 10 installed by homebrew.

Use pre-built gccemacs

Fortunatly we could use pre-built gccemacs right now.

Those two repos did the greate job for us.

https://github.com/twlz0ne/nix-gccemacs-darwin

https://github.com/twlz0ne/nix-gccemacs-sierra

Here is the tutorial:

Install nix

https://nixos.org/

For MacOS catalina

Install

nix-env -iA cachix -f https://cachix.org/api/v1/install
cachix use gccemacs-darwin
nix-env -iA emacsGccDarwin -f https://github.com/twlz0ne/nix-gccemacs-darwin/archive/master.zip

Update

nix-env -iA emacsGccDarwin -f https://github.com/twlz0ne/nix-gccemacs-darwin/archive/master.zip

For MacOS sierra

Install

nix-env -iA cachix -f https://cachix.org/api/v1/install
cachix use gccemacs-sierra
nix-env -iA emacsGccSierra -f https://github.com/twlz0ne/nix-gccemacs-sierra/archive/master.zip

Update

nix-env -iA emacsGccSierra -f https://github.com/twlz0ne/nix-gccemacs-sierra/archive/master.zip

It's done

Launch emacs from terminal, and you could find related app bundle's path by right click emacs icon in Docker.

Build gccemacs on MacOS catalina

It's a hard time to make gccemacs work on MacOS catalina. I've met countless problems by following every tutorials I can get from google. Fortunately I finally get it work!

Hope this tutorial could help you.

GCC with libgccjit enabled

cd /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula

Edit gcc.rb like this

@@ -53,7 +53,7 @@ class Gcc < Formula
     #  - Ada, which requires a pre-existing GCC Ada compiler to bootstrap
     #  - Go, currently not supported on macOS
     #  - BRIG
-    languages = %w[c c++ objc obj-c++ fortran]
+    languages = %w[c c++ objc obj-c++ fortran jit]

     osmajor = `uname -r`.split(".").first
     pkgversion = "Homebrew GCC #{pkg_version} #{build.used_options*" "}".strip
@@ -73,6 +73,7 @@ class Gcc < Formula
       --with-system-zlib
       --with-pkgversion=#{pkgversion}
       --with-bugurl=https://github.com/Homebrew/homebrew-core/issues
+      --enable-host-shared
     ]

     # Xcode 10 dropped 32-bit support

Build gcc by homebrew brew install gcc --build-from-source --force

Get gccemacs source code

Clone https://github.com/emacs-mirror/emacs and checkout feature/native-comp branch.

Build using this script

Create a build.sh outside emacs source code folder.

# native-comp optimization
export PATH="/usr/local/opt/gnu-sed/libexec/gnubin:${PATH}"
export CFLAGS="-I/usr/local/Cellar/gcc/10.1.0/include"
export LDFLAGS="-L/usr/local/Cellar/gcc/10.1.0/lib/gcc/10 -I/usr/local/Cellar/gcc/10.1.0/include"
export LIBRARY_PATH="/usr/local/Cellar/gcc/10.1.0/lib/gcc/10:${LIBRARY_PATH:-}"

cd emacs || exit

git clean -xfd

./autogen.sh

./configure \
     --disable-dependency-tracking \
     --disable-silent-rules \
     --enable-locallisppath=/usr/local/share/emacs/28.0.50/site-lisp \
     --prefix=/usr/local/opt/gccemacs \
     --without-dbus \
     --without-imagemagick \
     --with-mailutils \
     --with-ns \
     --disable-ns-self-contained \
     --with-cairo \
     --with-modules \
     --with-xml2 \
     --with-gnutls \
     --with-json \
     --with-rsvg \
     --with-nativecomp

# Ensure /usr/local/opt/gccemacs exists
rm -rf /usr/local/opt/gccemacs
mkdir /usr/local/opt/gccemacs

# Ensure the directory to which we will dump Emacs exists and has the correct
# permissions set.
libexec=/usr/local/libexec/emacs/28.0.50
if [ ! -d $libexec ]; then
  sudo mkdir -p $libexec
  sudo chown $USER $libexec
fi

make -j4
make install 

rm -rf "/Applications/Emacs.app"
mv nextstep/Emacs.app "/Applications/"

cd /usr/local/bin || exit
rm emacs
rm emacsclient
ln -s /usr/local/opt/gccemacs/bin/emacs .
ln -s /usr/local/opt/gccemacs/bin/emacsclient .


cd /Applications/Emacs.app/Contents || exit
ln -s /usr/local/opt/gccemacs/share/emacs/28.0.50/lisp .

To use Spacemacs

No special actions are needed.

To use Doom

Latest doom already support to compile all modules with native-comp.

Update to latest version.

To do so, upgrade doom to latest version. doom upgrade

Compile all modules

After that, do doom sync to compile all modules.

Generate local env file

Run doom env to generate local env file.

It's done.

Open emacs and feel the performance boost. Enjoy!

@strayer
Copy link

strayer commented Aug 12, 2020

So, compilation worked, but now running emacs fails with this:

emacs: dlopen(/usr/local/bin/../lisp/emacs-lisp/eln-x86_64-apple-darwin19.6.0-89a730c11dec204e/lisp-mode.eln, 1): image not found

Really weird.

@AllenDang
Copy link
Author

@strayer Make sure these two lines works with correct path setting.

cd /Applications/Emacs.app/Contents || exit
ln -s /usr/local/opt/gccemacs/share/emacs/28.0.50/lisp .

@quangIO
Copy link

quangIO commented Aug 12, 2020

@strayer, just move or symlink the lisp folder in your emacs build to /usr/local/lisp/

@strayer
Copy link

strayer commented Aug 12, 2020

Yeah, I already checked those paths because they felt relevant, but they seem to be correct. I think emacs tries to find that file in the wrong path, not sure where this /usr/local/bin/../lisp/ comes from. Creating a symlink a suggested by @quangIO works, even though it feels wrong ;)

@quangIO
Copy link

quangIO commented Aug 12, 2020

I believe emacs searches the load-path https://www.emacswiki.org/emacs/LoadPath. But symlinking is quicker :)

@strayer
Copy link

strayer commented Aug 12, 2020

After letting doom upgrade, everything seems to run fine! Sadly, the scrolling performance is still horrible on HiDPI screens… oh well.

@t0ster
Copy link

t0ster commented Aug 13, 2020

Thanks for this guide! Built successfully, however for me performance is worse than d12frosted/emacs-plus@27 brew version at least in doom emacs.

@agzam
Copy link

agzam commented Aug 14, 2020

I can't figure out how to build with GUI, hitting:

configure: error: The include files (AppKit/AppKit.h etc) that
are required for a Nextstep build are missing or cannot be compiled.
Either fix this, or re-configure with the option '--without-ns'.

I need the GUI. Any ideas guys?

@AllenDang
Copy link
Author

@agzam Same issue with ashton314, you could try to use CC=/usr/bin/clang ./configure and see if it works.

@ashton314
Copy link

I haven’t been able to compile my elisp files. Compiling Emacs itself with clang works fine, but then when I try compiling the elisp Emacs throws me into the debugger, saying that it wasn’t built with JIT support.

@pcf000
Copy link

pcf000 commented Aug 23, 2020

Note that if "brew install gcc" updates brew and its formulae, it's likely to undo the changes to gcc.rb that enable building libgccjit.

I also had an issue with /usr/bin/install and the -D option, which is a Linux thing, but maybe I just have a weird setup. The solution for me was "brew install coreutils" and then making sure the Makefile used /usr/local/opt/coreutils/libexec/gnubin/install instead of /usr/bin/install.

@zzkt
Copy link

zzkt commented Aug 26, 2020

as of "update 11" you'll also need to symlink the eln cache for Emacs.app to run. something like...

ln -s /usr/local/opt/gccemacs/libexec/emacs/28.0.50/x86_64-apple-darwin18.7.0/eln-cache /Applications/Emacs.app/Contents/.

@howardabrams
Copy link

I needed to add the following in order to find the correct GCC:

export PATH="${GCC_DIR}/bin:${SED_DIR}/libexec/gnubin:${PATH}"
export CC="gcc-10"

@oguzserbetci
Copy link

Just noting for someone running into the same problem as I did, make sure the version of gcc you have is the same as the env vars use. Brew updated mine to 10.2.0 , and even though there was no folder for 10.1 the compilation didn't throw any meaningful errors...

@ThiagoLira
Copy link

ThiagoLira commented Sep 27, 2020

My compilation process halts after a bunch of repeated errors like these ones:
Does anyone knows what might be wrong with my instalation?

./lisp.h:2639:53: error: implicit declaration of function 'typeof' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
  return FIXNUM_OVERFLOW_P (n) ? make_biguint (n) : make_fixnum (n);
                                                    ^
./lisp.h:444:26: note: expanded from macro 'make_fixnum'
#  define make_fixnum(n) lisp_h_make_fixnum (n)
                         ^
./lisp.h:395:9: note: expanded from macro 'lisp_h_make_fixnum'
     ({ typeof (+(n)) lisp_h_make_fixnum_n = n; \
        ^
./lisp.h:2639:53: error: expected ';' after expression
./lisp.h:444:26: note: expanded from macro 'make_fixnum'
#  define make_fixnum(n) lisp_h_make_fixnum (n)
                         ^
./lisp.h:395:23: note: expanded from macro 'lisp_h_make_fixnum'
     ({ typeof (+(n)) lisp_h_make_fixnum_n = n; \
                      ^
./lisp.h:2639:53: error: use of undeclared identifier 'lisp_h_make_fixnum_n'
./lisp.h:444:26: note: expanded from macro 'make_fixnum'
#  define make_fixnum(n) lisp_h_make_fixnum (n)
                         ^
./lisp.h:395:23: note: expanded from macro 'lisp_h_make_fixnum'
     ({ typeof (+(n)) lisp_h_make_fixnum_n = n; \
                      ^
./lisp.h:2639:53: error: use of undeclared identifier 'lisp_h_make_fixnum_n'
./lisp.h:444:26: note: expanded from macro 'make_fixnum'
#  define make_fixnum(n) lisp_h_make_fixnum (n)
                         ^
./lisp.h:396:31: note: expanded from macro 'lisp_h_make_fixnum'
        eassert (!FIXNUM_OVERFLOW_P (lisp_h_make_fixnum_n)); \
                                     ^
./lisp.h:2639:53: error: use of undeclared identifier 'lisp_h_make_fixnum_n'
./lisp.h:444:26: note: expanded from macro 'make_fixnum'
#  define make_fixnum(n) lisp_h_make_fixnum (n)
                         ^
./lisp.h:396:31: note: expanded from macro 'lisp_h_make_fixnum'
        eassert (!FIXNUM_OVERFLOW_P (lisp_h_make_fixnum_n)); \


@Grekkor
Copy link

Grekkor commented Oct 4, 2020

Getting the same errors as @ThiagoLira

@zikajk
Copy link

zikajk commented Oct 19, 2020

Well, that was stupid :D It is built with libgccjit, but I didn't realize Homebrew installed GCC 10.2.0, not 10.1.0 as specified in the build.sh above. It is building now.

Have you solved it? I can see that others are using 10.2.0.
I see that libgccjit is in /usr/local/opt but i encounter the same error as you do.

@oguzserbetci
Copy link

I had similar problems, which were solved by changing the environment variables in the beginning of the build.sh to the installed versions:

# native-comp optimization
export PATH="/usr/local/opt/gnu-sed/libexec/gnubin:${PATH}"
export CFLAGS="-I/usr/local/Cellar/gcc/10.2.0/include"
export LDFLAGS="-L/usr/local/Cellar/gcc/10.2.0/lib/gcc/10 -I/usr/local/Cellar/gcc/10.2.0/include"
export LIBRARY_PATH="/usr/local/Cellar/gcc/10.2.0/lib/gcc/10:${LIBRARY_PATH:-}"

@Colelyman
Copy link

Thanks for this, it has been very helpful! I encountered an error similar to @strayer (with the dlopen ... image not found) and fixed it by linking in the native-lisp directory instead of the lisp directory as previously suggested. YMMV!

@farynaio
Copy link

farynaio commented Dec 16, 2020

That's amazing, thanks for sharing @AllenDang. So far emacs had started and it's compiling everything in batch, it looks very promising.

@thecocoa
Copy link

thecocoa commented Dec 28, 2020

Thank you, @AllenDang. I get the warning:

checking for dlfunc... no
checking for gcc_jit_context_acquire in -lgccjit... yes
checking libgccjit.h usability... yes
checking libgccjit.h presence... no
configure: WARNING: libgccjit.h: accepted by the compiler, rejected by the preprocessor!
configure: WARNING: libgccjit.h: proceeding with the compiler's result
checking for libgccjit.h... yes
checking for libpng >= 1.0.0... yes
checking whether png_longjmp is declared... yes

but the build continues. Do you get these warnings during ./configure?

@biswanaths
Copy link

biswanaths commented Dec 31, 2020

I am getting this error while using the script
/usr/bin/install: illegal option -- D
Any workaround this ?

@AllenDang
Copy link
Author

@thecocoa Yes, I encountered same warning, it's ok.

@quangIO
Copy link

quangIO commented Dec 31, 2020

@biswa The solution was posted above (tldr: use coreutils).

@biswanaths
Copy link

Thank you. Sorry for spamming and missed the above.
Yes installed coreutils and exported the path to make sure Make used that.

@takuma-yoneda
Copy link

For anyone who is still looking at this:
If you're checking out 42fc752a14 or later,
You must replace --with-nativecomp --> --with-native-compilation in the script above.

As of 42fc752a14 the new configure flag to activate the Elisp native compilation is --with-native-compilation.

(See https://akrl.sdf.org/gccemacs.html#orgf5ebdd1)

@takuma-yoneda
Copy link

After compilation finishes, if you fail to launch emacs with an error like this:

emacs: dlopen(/Applications/Emacs.app/Contents/MacOS/../native-lisp/28.0.50-54532fd9/window-0d1b8b93-738411b0.eln, 1): image not found

You just need to symlink the proper native-lisp directory as:

ln -snf /usr/local/opt/gccemacs/lib/emacs/28.0.50/native-lisp /Applications/Emacs.app/Contents/MacOS/../native-lisp

(Actually, this is already posted above)

@hraban
Copy link

hraban commented Aug 17, 2021

I had to link both native-lisp and lisp into the final Emacs.app:

From the source directory:

ln -s "$PWD/native-lisp" nextstep/Emacs.app/Contents/
ln -s "$PWD/lisp" nextstep/Emacs.app/Contents/Resources/

Not sure what's happening. Commit bf1ec4952e67b474bff813cd26e4d612a359baf1, from Tue Aug 17 11:11:35 2021 +0300. Compilation flags ./configure --enable-link-time-optimization --with-imagemagick --with-native-compilation --with-json CFLAGS=-O3

@hraban
Copy link

hraban commented Aug 29, 2021

Update: it was me all along: I had this problem because I only ran make, not make install. I thought make install would copy Emacs to my /usr/something, but it turns out that it installs the necessary extra tools into nextstep/Emacs.app. So: make install is necessary for building on mac os, after which you can move the Emacs.app to /Applications.

@sevillaarvin
Copy link

@agzam Same issue with ashton314, you could try to use CC=/usr/bin/clang ./configure and see if it works.

It worked, thanks! I was agonizing over this for days.

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