From a8d4db284cc216afa6793173f17e3811305eff05 Mon Sep 17 00:00:00 2001 From: Jim Myhrberg Date: Tue, 18 Aug 2020 02:20:18 +0100 Subject: [PATCH] fix(native_comp): Improve ./install-patched-gcc helper Instead of just installing a pre-patched gcc formula, copy the local formula from Homebrew and apply a patch to it, before then installing it. This should be a lot more future-proof. --- .gitignore | 3 +- Formula/gcc.rb.patch | 21 ++++++ Formulas/gcc.rb | 155 ------------------------------------------- README.md | 23 +++++-- install-patched-gcc | 15 ++++- 5 files changed, 55 insertions(+), 162 deletions(-) create mode 100644 Formula/gcc.rb.patch delete mode 100644 Formulas/gcc.rb diff --git a/.gitignore b/.gitignore index 2105af6..f75fd16 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ .DS_Store +Formula/* +Gemfile.lock builds sources tarballs -Gemfile.lock \ No newline at end of file diff --git a/Formula/gcc.rb.patch b/Formula/gcc.rb.patch new file mode 100644 index 0000000..3417ab9 --- /dev/null +++ b/Formula/gcc.rb.patch @@ -0,0 +1,21 @@ +diff --git a/Formula/gcc.rb b/Formula/gcc.rb +index 1bd636d496..03ad124218 100644 +--- a/Formula/gcc.rb ++++ b/Formula/gcc.rb +@@ -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 diff --git a/Formulas/gcc.rb b/Formulas/gcc.rb deleted file mode 100644 index c361709..0000000 --- a/Formulas/gcc.rb +++ /dev/null @@ -1,155 +0,0 @@ -# frozen_string_literal: true - -class Gcc < Formula - desc 'GNU compiler collection' - homepage 'https://gcc.gnu.org/' - url 'https://ftp.gnu.org/gnu/gcc/gcc-10.2.0/gcc-10.2.0.tar.xz' - mirror 'https://ftpmirror.gnu.org/gcc/gcc-10.2.0/gcc-10.2.0.tar.xz' - sha256 'b8dd4368bb9c7f0b98188317ee0254dd8cc99d1e3a18d0ff146c855fe16c1d8c' - license 'GPL-3.0' - head 'https://gcc.gnu.org/git/gcc.git' - - bottle do - sha256 '8dbccea194c20b1037b7e8180986e98a8ee3e37eaac12c7d223c89be3deaac6a' => :catalina - sha256 '79d2293ce912dc46af961f30927b31eb06844292927be497015496f79ac41557' => :mojave - sha256 '5ed870a39571614dc5d83be26d73a4164911f4356b80d9345258a4c1dc3f1b70' => :high_sierra - end - - # The bottles are built on systems with the CLT installed, and do not work - # out of the box on Xcode-only systems due to an incorrect sysroot. - pour_bottle? do - reason 'The bottle needs the Xcode CLT to be installed.' - satisfy { MacOS::CLT.installed? } - end - - depends_on 'gmp' - depends_on 'isl' - depends_on 'libmpc' - depends_on 'mpfr' - - uses_from_macos 'zlib' - - # GCC bootstraps itself, so it is OK to have an incompatible C++ stdlib - cxxstdlib_check :skip - - def version_suffix - if build.head? - 'HEAD' - else - version.to_s.slice(/\d+/) - end - end - - def install - # GCC will suffer build errors if forced to use a particular linker. - ENV.delete 'LD' - - # We avoiding building: - # - 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 jit] - - osmajor = `uname -r`.split('.').first - pkgversion = "Homebrew GCC #{pkg_version} #{build.used_options * ' '}".strip - - args = %W[ - --build=x86_64-apple-darwin#{osmajor} - --prefix=#{prefix} - --libdir=#{lib}/gcc/#{version_suffix} - --disable-nls - --enable-checking=release - --enable-languages=#{languages.join(',')} - --program-suffix=-#{version_suffix} - --with-gmp=#{Formula['gmp'].opt_prefix} - --with-mpfr=#{Formula['mpfr'].opt_prefix} - --with-mpc=#{Formula['libmpc'].opt_prefix} - --with-isl=#{Formula['isl'].opt_prefix} - --with-system-zlib - --with-pkgversion=#{pkgversion} - --with-bugurl=https://github.com/Homebrew/homebrew-core/issues - --enable-host-shared - ] - - # Xcode 10 dropped 32-bit support - args << '--disable-multilib' if DevelopmentTools.clang_build_version >= 1000 - - # System headers may not be in /usr/include - sdk = MacOS.sdk_path_if_needed - if sdk - args << '--with-native-system-header-dir=/usr/include' - args << "--with-sysroot=#{sdk}" - end - - # Avoid reference to sed shim - args << 'SED=/usr/bin/sed' - - # Ensure correct install names when linking against libgcc_s; - # see discussion in https://github.com/Homebrew/legacy-homebrew/pull/34303 - inreplace 'libgcc/config/t-slibgcc-darwin', '@shlib_slibdir@', "#{HOMEBREW_PREFIX}/lib/gcc/#{version_suffix}" - - mkdir 'build' do - system '../configure', *args - - # Use -headerpad_max_install_names in the build, - # otherwise updated load commands won't fit in the Mach-O header. - # This is needed because `gcc` avoids the superenv shim. - system 'make', 'BOOT_LDFLAGS=-Wl,-headerpad_max_install_names' - system 'make', 'install' - - bin.install_symlink bin / "gfortran-#{version_suffix}" => 'gfortran' - end - - # Handle conflicts between GCC formulae and avoid interfering - # with system compilers. - # Rename man7. - Dir.glob(man7 / '*.7') { |file| add_suffix file, version_suffix } - # Even when we disable building info pages some are still installed. - info.rmtree - end - - def add_suffix(file, suffix) - dir = File.dirname(file) - ext = File.extname(file) - base = File.basename(file, ext) - File.rename file, "#{dir}/#{base}-#{suffix}#{ext}" - end - - test do - (testpath / 'hello-c.c').write <<~EOS - #include - int main() - { - puts("Hello, world!"); - return 0; - } - EOS - system "#{bin}/gcc-#{version_suffix}", '-o', 'hello-c', 'hello-c.c' - assert_equal "Hello, world!\n", `./hello-c` - - (testpath / 'hello-cc.cc').write <<~EOS - #include - int main() - { - std::cout << "Hello, world!" << std::endl; - return 0; - } - EOS - system "#{bin}/g++-#{version_suffix}", '-o', 'hello-cc', 'hello-cc.cc' - assert_equal "Hello, world!\n", `./hello-cc` - - (testpath / 'test.f90').write <<~EOS - integer,parameter::m=10000 - real::a(m), b(m) - real::fact=0.5 - - do concurrent (i=1:m) - a(i) = a(i) + fact*b(i) - end do - write(*,"(A)") "Done" - end - EOS - system "#{bin}/gfortran", '-o', 'test', 'test.f90' - assert_equal "Done\n", `./test` - end -end diff --git a/README.md b/README.md index 1b2915e..1b0c9ed 100644 --- a/README.md +++ b/README.md @@ -94,17 +94,27 @@ To build the stable `emacs-27.1` release git tag, with XWidgets support, run: To build a Emacs.app with native-comp support ([gccemacs](https://akrl.sdf.org/gccemacs.html)) from the `feature/native-comp` -branch, you will need to install a patched version of Homebrew's `gcc` formula, -which is included in `Forumlas/gcc.rb`. This can easily be installed by running: +branch, you will need to install a patched version of Homebrew's `gcc` formula +that includes libgccjit. + +The patch itself is in `./Formula/gcc.rb.patch`, and comes from +[this](https://gist.github.com/mikroskeem/0a5c909c1880408adf732ceba6d3f9ab#1-gcc-with-libgccjit-enabled) +gist. + +You can install the patched formula by running the helper script: ``` ./install-patched-gcc ``` -This requires installing and compiling GCC from source, and take anywhere +The helper script will copy your local `gcc.rb` Forumla from Homebrew to +`./Formula`, and apply the `./Formula/gcc.rb.patch` to it. After which it then +proceed to install the patched gcc formula which includes libgccjit. + +As it requires installing and compiling GCC from source, it can take anywhere between 30-60 minutes or more depending on your machine. -Then to build a Emacs.app with native compilation enabled, run: +And finally to build a Emacs.app with native compilation enabled, run: ``` ./build-emacs-for-macos -j 4 --native-comp feature/native-comp @@ -127,6 +137,11 @@ Emacs. - Patches applied are pulled from [emacs-plus](https://github.com/d12frosted/homebrew-emacs-plus), which is an excellent Homebrew formula with lots of options not available elsewhere. +- The following gists were all extremely useful in figuring out how get get + native-comp building on macOS: + - https://gist.github.com/mikroskeem/0a5c909c1880408adf732ceba6d3f9ab#1-gcc-with-libgccjit-enabled + - https://github.com/shshkn/emacs.d/blob/master/docs/nativecomp.md + - https://gist.github.com/AllenDang/f019593e65572a8e0aefc96058a2d23e ## Internals diff --git a/install-patched-gcc b/install-patched-gcc index 5f2edae..ac8c2cb 100755 --- a/install-patched-gcc +++ b/install-patched-gcc @@ -1,4 +1,15 @@ #! /usr/bin/env bash +set -e -export HOMEBREW_NO_AUTO_UPDATE=1 -brew install ./Formulas/gcc.rb --build-from-source --force +brewdir="$(brew --prefix)" +formula="${brewdir}/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/gcc.rb" + +if [ ! -f "$formula" ]; then + echo "ERROR: ${formula} does not exist." 1>&2 + exit 1 +fi + +cp "$formula" ./Formula/ + +patch -f -p1 -i ./Formula/gcc.rb.patch +brew install ./Formula/gcc.rb --build-from-source --force