diff --git a/README.md b/README.md index ec09684..a8c19e1 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,8 @@ Options: --[no-]xwidgets Enable/disable XWidgets (default: enabled) --[no-]native-comp Enable/disable native-comp (default: enabled if supported) --[no-]native-fast-boot Enable/disable NATIVE_FAST_BOOT (default: enabled if native-comp supported) + --[no-]native-comp-macos-fixes + Enable/disable fix based on feature/native-comp-macos-fixes branch (default: enabled if native-comp supported) ``` Resulting applications are saved to the `builds` directory in a bzip2 compressed @@ -143,8 +145,8 @@ Add the following near the top of your `early-init.el` or `init.el`: ``` By default natively compiled `*.eln` files will be cached in -`~/.emacs.d/eln-cache/`. If you want to customize that, simply add a new path as -the first element to the `comp-eln-load-path` variable. The path string must end +`~/.emacs.d/eln-cache/`. If you want to customize that, simply set a new path as +the first element of the `comp-eln-load-path` variable. The path string must end with a `/`. Also it seems somewhat common that some `*.eln` files are left behind with a @@ -159,7 +161,7 @@ said directory which have a file size of zero bytes: (when (boundp 'comp-eln-load-path) (let ((eln-cache-dir (expand-file-name "cache/eln-cache/" user-emacs-directory)) (find-exec (executable-find "find"))) - (add-to-list 'comp-eln-load-path eln-cache-dir) + (setcar comp-eln-load-path eln-cache-dir) ;; Quitting emacs while native compilation in progress can leave zero byte ;; sized *.eln files behind. Hence delete such files during startup. (when find-exec diff --git a/build-emacs-for-macos b/build-emacs-for-macos index 3297403..d88eb60 100755 --- a/build-emacs-for-macos +++ b/build-emacs-for-macos @@ -1,6 +1,7 @@ #!/usr/bin/env ruby # frozen_string_literal: true +require 'English' require 'date' require 'etc' require 'fileutils' @@ -10,9 +11,10 @@ require 'optparse' require 'pathname' require 'uri' +class Error < StandardError; end + def err(msg = nil) - warn("ERROR: #{msg}") if msg - exit 1 + raise Error, msg end class Build @@ -172,6 +174,10 @@ class Build verify_native_comp verify_libgccjit + if options[:macos_fixes] && ref != 'feature/native-comp-macos-fixes' + apply_native_comp_macos_fixes + end + ENV['NATIVE_FAST_BOOT'] = '1' if options[:native_fast_boot] ENV['CFLAGS'] = [ "-I#{gcc_dir}/include", @@ -316,8 +322,12 @@ class Build def meta return @meta if @meta - url = format(LATEST_URL, (options[:git_sha] || ref)) - commit = JSON.parse(http_get(url)) + ref_sha = options[:git_sha] || ref + url = format(LATEST_URL, ref_sha) + commit_json = http_get(url) + err "Failed to get commit info about: #{ref_sha}" if commit_json.nil? + + commit = JSON.parse(commit_json) @meta = { sha: commit['sha'], @@ -326,12 +336,47 @@ class Build end def http_get(url) - Net::HTTP.get(URI.parse(url)) + response = Net::HTTP.get_response(URI.parse(url)) + return unless response.code == '200' + + response.body end def run_cmd(*args) puts '==> ' + args.join(' ') - system(*args) || exit($CHILD_STATUS.exitstatus) + system(*args) || err("Exit code: #{$CHILD_STATUS.exitstatus}") + end + + def apply_native_comp_macos_fixes + filename = 'Makefile.in' + content = File.read(filename).gsub( + /^src: Makefile\n(.*BIN_DESTDIR.*)\nblessmail: Makefile src\n/m + ) do |match| + old_src_body = Regexp.last_match(1).strip + + # check if already patched + if old_src_body.include?('BIN_DESTDIR=\'${ns_appbindir}/\'') + return old_src_body + end + + self_contained = old_src_body.gsub( + 'BIN_DESTDIR=\'$(DESTDIR)${bindir}/\'', + 'BIN_DESTDIR=\'${ns_appbindir}/\'' + ) + + <<~REPLACEMENT + src: Makefile + ifeq (${ns_self_contained},no) + \t#{old_src_body} + else + \t#{self_contained} + endif + + blessmail: Makefile src + REPLACEMENT + end + + File.open(filename, 'w') { |f| f.write(content) } end def effective_version @@ -369,24 +414,31 @@ class Build p end - def apply_patch(patch, target) + def apply_patch(patch, target, abort_on_failure = true) err "\"#{target}\" does not exist." unless File.exist?(target) if patch[:url] - run_cmd('mkdir', '-p', "#{target}/patches") + patch_dir = "#{target}/macos_patches" + run_cmd('mkdir', '-p', patch_dir) - patch_file = "#{target}/patches/patch-{num}.diff" + patch_file = "#{patch_dir}/patch-{num}.diff" num = 1 while File.exist?(patch_file.gsub('{num}', num.to_s.rjust(3, '0'))) num += 1 end patch_file = patch_file.gsub('{num}', num.to_s.rjust(3, '0')) - puts "Downloading patch: #{patch[:url]}" - run_cmd('curl', '-L#', patch[:url], '-o', patch_file) + begin + puts "Downloading patch: #{patch[:url]}" + run_cmd('curl', '-L#', patch[:url], '-o', patch_file) - puts 'Applying patch...' - FileUtils.cd(target) { run_cmd('patch', '-f', '-p1', '-i', patch_file) } + puts 'Applying patch...' + FileUtils.cd(target) { run_cmd('patch', '-f', '-p1', '-i', patch_file) } + rescue Error => e + raise e if abort_on_failure + + puts "WARN: Failed to apply patch: #{e.message}" + end elsif patch[:replace] err 'Patch replace input error' unless patch[:replace].size == 3 @@ -530,7 +582,8 @@ if __FILE__ == $PROGRAM_NAME cli_options = { native_fast_boot: true, parallel: Etc.nprocessors, - xwidgets: true + xwidgets: true, + macos_fixes: true } OptionParser.new do |opts| @@ -571,7 +624,18 @@ if __FILE__ == $PROGRAM_NAME '(default: enabled if native-comp supported)') do |v| cli_options[:native_fast_boot] = v end + + opts.on('--[no-]native-comp-macos-fixes', + 'Enable/disable fix based on feature/native-comp-macos-fixes ' \ + 'branch (default: enabled if native-comp supported)') do |v| + cli_options[:macos_fixes] = v + end end.parse! - Build.new(File.expand_path(__dir__), ARGV.shift, cli_options).build + begin + Build.new(File.expand_path(__dir__), ARGV.shift, cli_options).build + rescue Error => e + warn "ERROR: #{e.message}" + exit 1 + end end