Compare commits

...

42 Commits

Author SHA1 Message Date
3d6c7fff64 chore(release): 0.6.42 2023-07-31 18:42:33 +01:00
d08d1b9b5c feat: options for log-level and github source repository
Changes:

- Adds optional --log-level flag and lots of debug output when level is
  set to "debug"
- Adds optional --github-src-repo flag to specify a custom GitHub
  repository to download source tarball from.
- Resolve all current Rubocop complaints.
2023-07-31 18:39:38 +01:00
6e32219c24 chore(deps): add webp to Brewfile 2023-07-31 18:36:22 +01:00
d2548191f1 chore(release): 0.6.41 2023-01-16 23:52:25 +00:00
8ed16b27c0 ci(builds): add python to CI dependencies 2023-01-16 23:23:43 +00:00
14f7aa13d9 chore(release): 0.6.40 2023-01-08 22:39:03 +00:00
59ebbdaa2b Merge pull request #79 from jimeh/fix-nightly-builds 2023-01-08 22:38:16 +00:00
d98c14dde5 chore(deps): remove python CI dependency
Instead use default python version install on macOS to install dmgbuild.
2023-01-08 21:21:54 +00:00
590b0ac21a chore(deps): remove curl from Brewfile
Curl is part of macOS, and the curl homebrew formula is keg-only.
Meaning there's no reason to install it for our purposes.
2023-01-08 20:39:17 +00:00
8c84ef128f chore(release): 0.6.39 2022-12-04 20:33:32 +00:00
8b447b6237 feat(version): correctly handle Emacs 30.x builds 2022-12-04 20:32:55 +00:00
c3d19694e7 feat(deprecate): posix-spawn patch is no longer supported
Nor is it needed, as it was only an issue in master for a short period
of time.
2022-12-04 20:30:20 +00:00
cff89684c6 chore(release): 0.6.38 2022-12-01 22:35:08 +00:00
48a512fbce feat(patch): add round-undecorated-frame from emacs-plus for 29.x 2022-12-01 22:30:48 +00:00
a3530c02e8 feat(patch): add support for experimental poll patch from emacs-plus for 29.x 2022-12-01 22:30:42 +00:00
138ac74ba5 chore(release): 0.6.37 2022-12-01 22:09:38 +00:00
0ba971ef61 feat(tree-sitter): support new --with-tree-sitter configure flag 2022-12-01 22:08:29 +00:00
1ae8771b2c chore(release): 0.6.36 2022-10-08 14:41:30 +01:00
1f2868d4b3 fix(native-comp): support new configure flag format
Commit e245c4f226979ccb717cccc8f82b2b0a0f96bdac on Emacs' master branch
added support for optional flags to the --with-native-compilation
configure flag.

This change to output of ./configure --help broke the native comp
detection present in our build script.

This change adds support for the new configure flag format, while also
using it to specify AOT when enabled.

It is still backwards compatible with the configure script in older
commits.

Fixes #76
2022-10-08 14:38:37 +01:00
bfa5bcf79b chore(release): 0.6.35 2022-08-10 16:48:24 +01:00
02d85f899f Merge pull request #75 from jimeh/fix-libgccjit12-compatibility
fix(native-comp): compatibility with libgccjit 12 homebrew formula
2022-08-10 16:46:45 +01:00
aeb3a75e5c chore(patch): minor simplification to libgccjit patches
By matching more targeted sets of strings, it should hopefully make
these patches more future-proof.
2022-08-10 16:31:51 +01:00
Alice Rum
e0fd2b16eb fix(native-comp): compatibility with libgccjit 12 homebrew formula
Since the latest update of `libgccjit` in brew to version 12, emacs does
not build again. Problem is that now dylib exists in multiple locations,
and `MAC_CFLAGS` environment variable is not filled correctly in
`configure.ac`. This commit fixes the issue.
2022-08-10 16:30:10 +01:00
d24ac084b7 chore(release): 0.6.34 2022-07-27 23:25:28 +01:00
159a7333de Merge pull request #73 from jimeh/fix-emacs-28
fix(emacs-28): patch configure.ac to support latest libgccjit
2022-07-27 23:23:39 +01:00
b582523642 fix(emacs-28): patch configure.ac to support latest libgccjit
When building Emacs 28.x the build script will attempt to patch
configure.ac if needed to support the latest version of libgccjit which
renamed libgccjit.so to libgccjit.dylib.

Fixes #72
2022-07-27 23:18:58 +01:00
4f1e748df2 chore(release): 0.6.33 2022-04-30 19:37:01 +01:00
d984633991 chore(deps): update gon package to 0.2.5 2022-04-30 19:35:21 +01:00
616f74d624 chore(release): 0.6.32 2022-04-30 17:46:51 +01:00
d7963b7664 chore(helper): minor tweak to emacs helper launch script 2022-04-30 17:46:06 +01:00
a20a8456ab feat(deps): add sqlite brew dependency for Emacs 29.x 2022-04-30 17:45:21 +01:00
8ad3ff4f53 feat(dbus): add flag to explicitly disable dbus support
Fixes #69
2022-04-30 17:27:41 +01:00
e31f5aaf93 fix(native-comp): support libgccjit 11.3.0
The libgccjit shared library file was renamed from libgccjit.so to
libgccjit.0.dylib in 11.3.0.

Fixes #71
2022-04-30 17:13:50 +01:00
c2fb07fdb8 chore(release): 0.6.31 2022-02-25 10:33:12 +00:00
07e0e3dacd fix: set source-directory correctly
Fixes #68
2022-02-25 10:32:03 +00:00
efddb9ef92 chore(release): 0.6.30 2022-02-08 03:07:18 +00:00
f7f4c0433a Merge pull request #66 from jimeh/add-homebrew-site-lisp-path 2022-02-08 03:05:31 +00:00
cbd8cb27b6 fix(site-lisp): add Homebrew's site-lisp directory to locallisppath
This should allow mu4e to be loaded from the mu homebrew package, among
other homebrew packages that provides emacs site-lisp files.

Ref: https://github.com/jimeh/emacs-builds/issues/19
2022-02-08 00:44:09 +00:00
656b96510a chore(release): 0.6.29 2022-02-07 21:07:10 +00:00
084776db6b feat(cask): add support for pretest builds 2022-02-07 21:04:59 +00:00
1e6d6cc6cf chore(release): 0.6.28 2022-01-15 23:19:07 +00:00
68ef4c066c feat(build): add dbus dependency to enable support in Emacs builds
Dbus support is automatically enabled if available on the system.
2022-01-15 23:17:25 +00:00
8 changed files with 439 additions and 118 deletions

View File

@@ -1,9 +1,30 @@
AllCops:
TargetRubyVersion: 2.3
TargetRubyVersion: 2.4
NewCops: enable
Layout/LineLength:
Max: 80
Style/AccessorGrouping:
Enabled: false
Style/Documentation:
Enabled: false
Metrics/AbcSize:
Enabled: false
Metrics/BlockLength:
Enabled: false
Metrics/ClassLength:
Enabled: false
Metrics/CyclomaticComplexity:
Enabled: false
Metrics/MethodLength:
Enabled: false
Metrics/PerceivedComplexity:
Enabled: false

View File

@@ -2,7 +2,7 @@
brew 'autoconf'
brew 'coreutils'
brew 'curl'
brew 'dbus'
brew 'expat'
brew 'gcc'
brew 'gmp'
@@ -22,5 +22,8 @@ brew 'make'
brew 'ncurses'
brew 'nettle'
brew 'pkg-config'
brew 'sqlite'
brew 'texinfo'
brew 'tree-sitter'
brew 'webp'
brew 'zlib'

View File

@@ -2,6 +2,104 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
### [0.6.42](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.41...v0.6.42) (2023-07-31)
### Features
* options for log-level and github source repository ([d08d1b9](https://github.com/jimeh/build-emacs-for-macos/commit/d08d1b9b5c4001302564dc8915884c465802f3b5))
### [0.6.41](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.40...v0.6.41) (2023-01-16)
### [0.6.40](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.39...v0.6.40) (2023-01-08)
### [0.6.39](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.38...v0.6.39) (2022-12-04)
### Features
* **deprecate:** posix-spawn patch is no longer supported ([c3d1969](https://github.com/jimeh/build-emacs-for-macos/commit/c3d19694e7e4d33d462c9917683c2d63f69002f5))
* **version:** correctly handle Emacs 30.x builds ([8b447b6](https://github.com/jimeh/build-emacs-for-macos/commit/8b447b6237fbbd94c4e72af8ee79969c7cfc9363))
### [0.6.38](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.37...v0.6.38) (2022-12-01)
### Features
* **patch:** add round-undecorated-frame from emacs-plus for 29.x ([48a512f](https://github.com/jimeh/build-emacs-for-macos/commit/48a512fbce79759caa987e2880585bd0bc937977))
* **patch:** add support for experimental poll patch from emacs-plus for 29.x ([a3530c0](https://github.com/jimeh/build-emacs-for-macos/commit/a3530c02e8260106f87d464e5cb398dcb2819460))
### [0.6.37](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.36...v0.6.37) (2022-12-01)
### Features
* **tree-sitter:** support new --with-tree-sitter configure flag ([0ba971e](https://github.com/jimeh/build-emacs-for-macos/commit/0ba971ef61a195c91e87aa381d5d3b044461b4f6))
### [0.6.36](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.35...v0.6.36) (2022-10-08)
### Bug Fixes
* **native-comp:** support new configure flag format ([1f2868d](https://github.com/jimeh/build-emacs-for-macos/commit/1f2868d4b3784e906665e9f3b6b9bba8fd72292f)), closes [#76](https://github.com/jimeh/build-emacs-for-macos/issues/76)
### [0.6.35](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.34...v0.6.35) (2022-08-10)
### Bug Fixes
* **native-comp:** compatibility with libgccjit 12 homebrew formula ([e0fd2b1](https://github.com/jimeh/build-emacs-for-macos/commit/e0fd2b16eb91ac5a98ed4ec31f4773ab22cbd470))
### [0.6.34](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.33...v0.6.34) (2022-07-27)
### Bug Fixes
* **emacs-28:** patch configure.ac to support latest libgccjit ([b582523](https://github.com/jimeh/build-emacs-for-macos/commit/b582523642ad4c5298f5a7890edd9b48c0433684)), closes [#72](https://github.com/jimeh/build-emacs-for-macos/issues/72)
### [0.6.33](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.32...v0.6.33) (2022-04-30)
### [0.6.32](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.31...v0.6.32) (2022-04-30)
### Features
* **dbus:** add flag to explicitly disable dbus support ([8ad3ff4](https://github.com/jimeh/build-emacs-for-macos/commit/8ad3ff4f53505408aa097527177032a1fd6008e0)), closes [#69](https://github.com/jimeh/build-emacs-for-macos/issues/69)
* **deps:** add sqlite brew dependency for Emacs 29.x ([a20a845](https://github.com/jimeh/build-emacs-for-macos/commit/a20a8456ab1e8de6357d5d121b9565ba65a6dd71))
### Bug Fixes
* **native-comp:** support libgccjit 11.3.0 ([e31f5aa](https://github.com/jimeh/build-emacs-for-macos/commit/e31f5aaf9355b674c2a86b8eda35f6513f344b72)), closes [#71](https://github.com/jimeh/build-emacs-for-macos/issues/71)
### [0.6.31](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.30...v0.6.31) (2022-02-25)
### Bug Fixes
* set source-directory correctly ([07e0e3d](https://github.com/jimeh/build-emacs-for-macos/commit/07e0e3dacddfbdb7a59aceaa2dc9cdf503ac2bcc)), closes [#68](https://github.com/jimeh/build-emacs-for-macos/issues/68)
### [0.6.30](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.29...v0.6.30) (2022-02-08)
### Bug Fixes
* **site-lisp:** add Homebrew's site-lisp directory to locallisppath ([cbd8cb2](https://github.com/jimeh/build-emacs-for-macos/commit/cbd8cb27b6ceff2e128c38cd1cc8f8380b9b4bfb))
### [0.6.29](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.28...v0.6.29) (2022-02-07)
### Features
* **cask:** add support for pretest builds ([084776d](https://github.com/jimeh/build-emacs-for-macos/commit/084776db6b7e61958088d7b2a2588e9889e60c21))
### [0.6.28](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.27...v0.6.28) (2022-01-15)
### Features
* **build:** add dbus dependency to enable support in Emacs builds ([68ef4c0](https://github.com/jimeh/build-emacs-for-macos/commit/68ef4c066c3fd1a7337198e8f773866088b4f481))
### [0.6.27](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.26...v0.6.27) (2021-12-05)

View File

@@ -7,6 +7,7 @@ require 'erb'
require 'etc'
require 'fileutils'
require 'json'
require 'logger'
require 'net/http'
require 'optparse'
require 'pathname'
@@ -18,33 +19,68 @@ require 'yaml'
class Error < StandardError; end
module Output
def info(msg, newline: true)
out "INFO: #{msg}", newline: newline
end
class << self
LEVELS = {
debug: Logger::DEBUG,
error: Logger::ERROR,
fatal: Logger::FATAL,
info: Logger::INFO,
unknown: Logger::UNKNOWN,
warn: Logger::WARN
}.freeze
def out(msg, newline: true)
if newline
warn "==> #{msg}"
else
$stderr.print "==> #{msg}"
def log_level
LEVELS.key(logger.level)
end
def log_level=(level)
logger.level = LEVELS.fetch(level&.to_sym)
end
def logger
@logger ||= Logger.new($stderr).tap do |logger|
logger.level = Logger::INFO
logger.formatter = proc do |severity, _datetime, _progname, msg|
"==> #{severity.upcase}: #{msg}"
end
end
end
end
def err(msg = nil)
%i[debug info warn error].each do |severity|
define_method(severity) do |msg, newline: true|
logger.send(severity, format_msg(msg, newline: newline))
end
end
def fatal(msg = nil)
raise Error, msg
end
private
def logger
Output.logger
end
def format_msg(msg, newline: true)
msg = msg.join("\n") if msg.is_a?(Array)
msg = msg.strip
msg = "#{msg}\n" if newline
msg
end
end
module System
include Output
def run_cmd(*args)
out("CMD: #{args.join(' ')}")
debug "executing: #{args.join(' ')}"
cmd(*args)
end
def cmd(*args)
system(*args) || err("Exit code: #{$CHILD_STATUS.exitstatus}")
system(*args) || fatal("Exit code: #{$CHILD_STATUS.exitstatus}")
end
end
@@ -61,7 +97,7 @@ end
class OSVersion
def initialize
@version = `sw_vers -productVersion`.match(
/(?<major>\d+)(?:\.(?<minor>\d+)(:?\.(?<patch>\d+))?)?/
/(?<major>\d+)(?:\.(?<minor>\d+)(?:\.(?<patch>\d+))?)?/
)
end
@@ -86,8 +122,7 @@ class Build
include Output
include System
EMACS_MIRROR_REPO = 'emacs-mirror/emacs'
DOWNLOAD_URL = 'https://github.com/emacs-mirror/emacs/tarball/%s'
DEFAULT_GITHUB_REPO = 'emacs-mirror/emacs'
attr_reader :root_dir
attr_reader :source_dir
@@ -106,7 +141,7 @@ class Build
load_plan(options[:plan]) if options[:plan]
unless meta[:sha] && meta[:date]
err 'Failed to get commit info from GitHub.'
fatal 'Failed to get commit info from GitHub.'
end
tarball = download_tarball(meta[:sha])
@@ -122,7 +157,9 @@ class Build
CLIHelperEmbedder.new(app).embed
CSourcesEmbedder.new(app, @source_dir).embed
LibEmbedder.new(app, brew_dir, extra_libs, options[:relink_eln]).embed
LibEmbedder.new(
app, brew_dir, extra_libs, relink_eln_files: options[:relink_eln]
).embed
GccLibEmbedder.new(app, gcc_info).embed if options[:native_comp]
archive_build(build_dir) if options[:archive]
@@ -131,6 +168,7 @@ class Build
private
def load_plan(filename)
debug "Loading plan from: #{filename}"
plan = YAML.safe_load(File.read(filename), [:Time])
@ref = plan.dig('source', 'ref')
@@ -163,6 +201,10 @@ class Build
@output_dir ||= (options[:output] || File.join(root_dir, 'builds'))
end
def github_src_repo
@github_src_repo ||= options[:github_src_repo] || DEFAULT_GITHUB_REPO
end
def brew_dir
@brew_dir ||= `brew --prefix`.chomp
end
@@ -189,8 +231,8 @@ class Build
def download_tarball(sha)
FileUtils.mkdir_p(tarballs_dir)
url = (DOWNLOAD_URL % sha)
filename = "emacs-mirror-emacs-#{sha[0..6]}.tgz"
url = "https://github.com/#{github_src_repo}/tarball/#{sha}"
filename = "#{github_src_repo.gsub(/[^a-zA-Z0-9-]+/, '-')}-#{sha[0..6]}.tgz"
target = File.join(tarballs_dir, filename)
if File.exist?(target)
@@ -212,7 +254,7 @@ class Build
log_args[1..-1]
end
out "CMD: #{log_args.join(' ')}"
debug "executing: #{log_args.join(' ')}"
cmd(*args)
target
@@ -231,7 +273,7 @@ class Build
info 'Extracting tarball...'
result = run_cmd('tar', '-xzf', filename, '-C', sources_dir)
err 'Tarball extraction failed.' unless result
fatal 'Tarball extraction failed.' unless result
patches.each { |patch| apply_patch(patch, target) }
@@ -250,26 +292,53 @@ class Build
@supports_xwidgets ||= !!configure_help.match(/\s+--with-xwidgets\s+/)
end
def supports_tree_sitter?
@supports_tree_sitter ||= !!configure_help.match(
/\s+--with-tree-sitter(\s|=).+/
)
end
def supports_native_comp?
@supports_native_comp ||= !native_comp_configure_flag.nil?
end
def native_comp_configure_match
@native_comp_configure_match ||= configure_help.match(
/\s+?(--with-native(?:comp|-compilation))(.+)?\s+?/
)
end
def native_comp_configure_flag
@native_comp_configure_flag ||= configure_help.match(
/\s+(--with-native(?:comp|-compilation))\s+/
)&.[](1)
return @native_comp_configure_flag if @native_comp_configure_flag
return unless native_comp_configure_match&.[](1)
@native_comp_configure_flag = [
native_comp_configure_match[1],
native_comp_configure_flag_arg
].compact.join('=')
end
def native_comp_configure_flag_arg
return @native_comp_configure_flag_arg if @native_comp_configure_flag_arg
return if native_comp_configure_match&.[](2) != '[=TYPE]'
@native_comp_configure_flag_arg = \
(options[:native_full_aot] ? 'aot' : 'yes')
end
def detect_native_comp
info 'Detecting native-comp support: ', newline: false
info 'Detecting native-comp support...'
options[:native_comp] = supports_native_comp?
puts options[:native_comp] ? 'Supported' : 'Not supported'
info 'Native-comp is: ' \
"#{options[:native_comp] ? 'Supported' : 'Not supported'}"
end
def verify_native_comp
return if supports_native_comp?
err 'This emacs source tree does not support native-comp'
fatal 'This emacs source tree does not support native-comp'
end
def autogen
@@ -288,7 +357,7 @@ class Build
if File.exist?(emacs_app)
info 'Emacs.app already exists in ' \
"\"#{target.gsub(root_dir + '/', '')}\", attempting to use."
"\"#{target.gsub("#{root_dir}/", '')}\", attempting to use."
return emacs_app
end
@@ -305,7 +374,7 @@ class Build
"-I#{File.join(gcc_info.libgccjit_root_dir, 'include')}",
'-O2',
(options[:native_march] ? '-march=native' : nil),
ENV['CFLAGS']
ENV.fetch('CFLAGS', nil)
].compact.join(' ')
ENV['LDFLAGS'] = [
@@ -316,14 +385,14 @@ class Build
"-I#{File.join(gcc_info.libgccjit_root_dir, 'include')}",
# Ensure library re-linking and code signing will work after building.
'-Wl,-headerpad_max_install_names',
ENV['LDFLAGS']
ENV.fetch('LDFLAGS', nil)
].compact.join(' ')
ENV['LIBRARY_PATH'] = [
gcc_info.lib_dir,
gcc_info.darwin_lib_dir,
gcc_info.libgccjit_lib_dir,
ENV['LIBRARY_PATH']
ENV.fetch('LIBRARY_PATH', nil)
].compact.join(':')
end
@@ -337,7 +406,7 @@ class Build
File.join(brew_dir, 'opt/zlib/lib/pkgconfig'),
File.join(brew_dir, 'Homebrew/Library/Homebrew/os/mac/pkgconfig',
OS.version.to_s),
ENV['PKG_CONFIG_PATH']
ENV.fetch('PKG_CONFIG_PATH', nil)
].compact.join(':')
ENV['PATH'] = [
@@ -346,11 +415,11 @@ class Build
File.join(brew_dir, 'opt/gnu-sed/libexec/gnubin'),
File.join(brew_dir, 'bin'),
File.join(brew_dir, 'opt/texinfo/bin'),
ENV['PATH']
ENV.fetch('PATH', nil)
].compact.join(':')
ENV['LIBRARY_PATH'] = [
ENV['LIBRARY_PATH'],
ENV.fetch('LIBRARY_PATH', nil),
'/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib'
].compact.join(':')
@@ -359,15 +428,20 @@ class Build
'--with-modules',
'--enable-locallisppath=' \
'/Library/Application Support/Emacs/${version}/site-lisp:' \
'/Library/Application Support/Emacs/site-lisp'
'/Library/Application Support/Emacs/site-lisp:' \
'/usr/local/share/emacs/site-lisp'
]
if options[:xwidgets] && supports_xwidgets?
configure_flags << '--with-xwidgets'
end
if options[:tree_sitter] && supports_tree_sitter?
configure_flags << '--with-tree-sitter'
end
configure_flags << native_comp_configure_flag if options[:native_comp]
configure_flags << '--without-rsvg' if options[:rsvg] == false
configure_flags << '--without-dbus' if options[:dbus] == false
run_cmd './configure', *configure_flags
run_cmd './configure', *configure_flags.compact
# Disable aligned_alloc on Mojave and below. See issue:
# https://github.com/daviderestivo/homebrew-emacs-head/issues/15
@@ -384,8 +458,12 @@ class Build
make_flags << "BYTE_COMPILE_EXTRA_FLAGS=--eval '(setq comp-speed 2)'"
if options[:native_full_aot]
info 'Using NATIVE_FULL_AOT=1'
make_flags << 'NATIVE_FULL_AOT=1'
info 'Using native compile full AOT'
# We do not need to supply the full AOT make arg if
# --with-native-compilation=aot configure flag is supported.
unless native_comp_configure_flag_arg
make_flags << 'NATIVE_FULL_AOT=1'
end
ENV.delete('NATIVE_FAST_BOOT')
else
ENV.delete('NATIVE_FULL_AOT')
@@ -393,11 +471,11 @@ class Build
end
end
run_cmd 'make', *make_flags
run_cmd 'make', *make_flags.compact
run_cmd 'make', 'install'
end
err 'Build failed.' unless File.exist?(emacs_app)
fatal 'Build failed.' unless File.exist?(emacs_app)
emacs_app
end
@@ -407,8 +485,8 @@ class Build
target_dir = File.join(output_dir, build_name)
if File.exist?(target_dir)
err "Output directory #{target_dir} already exists, " \
'please delete it and try again'
fatal "Output directory #{target_dir} already exists, " \
'please delete it and try again'
end
info "Copying \"#{app_name}\" to: #{target_dir}"
@@ -486,7 +564,8 @@ class Build
'MacOS/lib/emacs/**/native-lisp'].first
if source.nil?
err 'Failed to find native-lisp cache directory for symlink creation.'
fatal 'Failed to find native-lisp cache directory for ' \
'symlink creation.'
end
end
@@ -502,7 +581,7 @@ class Build
contents_dir = File.join(app, 'Contents')
FileUtils.cd(contents_dir) do
filename = Dir['MacOS/Emacs.pdmp', 'MacOS/libexec/Emacs.pdmp'].first
err "no Emacs.pdmp file found in #{app}" unless filename
fatal "no Emacs.pdmp file found in #{app}" unless filename
info 'patching Emacs.pdmp to point at new native-lisp paths'
content = File.read(filename, mode: 'rb').gsub(
@@ -514,7 +593,7 @@ class Build
"../native-lisp/#{sanitized_eln_version}/"
)
File.open(filename, 'w') { |f| f.write(content) }
File.write(filename, content)
end
end
@@ -546,7 +625,10 @@ class Build
build = File.basename(build_dir)
parent_dir = File.dirname(build_dir)
if !File.exist?(archive_filename)
if File.exist?(archive_filename)
info "#{filename} archive exists in " \
"#{target_dir}, skipping archving."
else
info "Creating #{filename} archive in \"#{target_dir}\"..."
FileUtils.cd(parent_dir) do
cmd('tar', '-cjf', archive_filename, build)
@@ -556,9 +638,6 @@ class Build
FileUtils.rm_rf(build_dir)
end
end
else
info "#{filename} archive exists in " \
"#{target_dir}, skipping archving."
end
end
@@ -574,7 +653,7 @@ class Build
.gsub('#define HAVE_ALLOCA_H 1',
'#undef HAVE_ALLOCA_H')
File.open(filename, 'w') { |f| f.write(content) }
File.write(filename, content)
end
def meta
@@ -583,9 +662,9 @@ class Build
ref_sha = options[:git_sha] || ref
info "Fetching info for git ref: #{ref_sha}"
commit_json = github_api_get(
"/repos/#{EMACS_MIRROR_REPO}/commits/#{ref_sha}"
"/repos/#{github_src_repo}/commits/#{ref_sha}"
)
err "Failed to get commit info about: #{ref_sha}" if commit_json.nil?
fatal "Failed to get commit info about: #{ref_sha}" if commit_json.nil?
commit = JSON.parse(commit_json)
meta = {
@@ -615,31 +694,32 @@ class Build
end
def effective_version
@effective_version ||= begin
case ref
when /^emacs-26.*/
'emacs-26'
when /^emacs-27.*/
'emacs-27'
when /^emacs-28.*/
'emacs-28'
else
'emacs-29'
end
end
@effective_version ||= case ref
when /^emacs-26.*/
'emacs-26'
when /^emacs-27.*/
'emacs-27'
when /^emacs-28.*/
'emacs-28'
when /^emacs-29.*/
'emacs-29'
else
'emacs-30'
end
end
def patches(opts = {})
p = []
if %w[emacs-26 emacs-27 emacs-28 emacs-29].include?(effective_version)
if %w[emacs-26 emacs-27 emacs-28 emacs-29 emacs-30]
.include?(effective_version)
p << {
url: 'https://github.com/d12frosted/homebrew-emacs-plus/raw/master/' \
"patches/#{effective_version}/fix-window-role.patch"
}
end
if %w[emacs-27 emacs-28 emacs-29].include?(effective_version)
if %w[emacs-27 emacs-28 emacs-29 emacs-30].include?(effective_version)
p << {
url: 'https://github.com/d12frosted/homebrew-emacs-plus/raw/master/' \
"patches/#{effective_version}/system-appearance.patch"
@@ -660,15 +740,41 @@ class Build
end
end
if %w[emacs-28 emacs-29].include?(effective_version)
if options[:posix_spawn]
if %w[emacs-29 emacs-30].include?(effective_version)
p << {
url: 'https://github.com/d12frosted/homebrew-emacs-plus/raw/master/' \
"patches/#{effective_version}/round-undecorated-frame.patch"
}
if options[:poll]
p << {
url: 'https://github.com/d12frosted/homebrew-emacs-plus/raw/master/' \
"patches/#{effective_version}/posix-spawn.patch"
"patches/#{effective_version}/poll.patch"
}
end
end
if effective_version == 'emacs-28'
p << {
replace: [
'configure.ac',
'grep libgccjit.so\$',
'grep -E \'libgccjit\.(so|dylib)$\''
],
allow_failure: true
}
end
if %w[emacs-28 emacs-29].include?(effective_version)
p << {
replace: [
'configure.ac',
'grep -E \'libgccjit\.(so|dylib)$\'',
'grep -E \'libgccjit\.(so|dylib)$\' | tail -1'
],
allow_failure: true
}
end
if effective_version == 'emacs-27'
p << {
url: 'https://github.com/d12frosted/homebrew-emacs-plus/raw/master/' \
@@ -687,7 +793,7 @@ class Build
end
def apply_patch(patch, target)
err "\"#{target}\" does not exist." unless File.exist?(target)
fatal "\"#{target}\" does not exist." unless File.exist?(target)
if patch[:file]
info 'Applying patch...'
@@ -715,20 +821,37 @@ class Build
end
elsif patch[:replace]
err 'Patch replace input error' unless patch[:replace].size == 3
fatal 'Patch replace input error' unless patch[:replace].size == 3
file, before, after = patch[:replace]
info "Applying patch to #{file}..."
filepath = File.join(target, file)
err "\"#{file}\" does not exist in #{target}" unless File.exist?(filepath)
unless File.exist?(filepath)
if patch[:allow_failure]
info "File #{filepath} does not exist, skipping patch."
return
end
fatal "\"#{file}\" does not exist in #{target}"
end
f = File.open(filepath, 'rb')
s = f.read
sub = s.gsub!(before, after)
err "Replacement filed in #{file}" if sub.nil?
if sub.nil?
if patch[:allow_failure]
info 'Patch did not apply, skipping.'
return
end
fatal "Replacement failed in #{file}"
end
f.reopen(filepath, 'wb').write(s)
f.close
info "#{file} patched."
end
end
@@ -764,11 +887,15 @@ class AbstractEmbedder
attr_reader :app
def initialize(app)
err "#{app} does not exist" unless File.exist?(app)
fatal "#{app} does not exist" unless File.exist?(app)
@app = app
end
def relative_path(path)
Pathname.new(path).relative_path_from(Pathname.new(app)).to_s
end
def invocation_dir
@invocation_dir ||= File.join(app, 'Contents', 'MacOS')
end
@@ -811,7 +938,8 @@ end
class CSourcesEmbedder < AbstractEmbedder
PATH_PATCH = <<~ELISP
;; Allow Emacs to find bundled C sources.
(setq source-directory (expand-file-name ".."))
(setq source-directory
(expand-file-name ".." (file-name-directory load-file-name)))
ELISP
attr_reader :source_dir
@@ -823,12 +951,16 @@ class CSourcesEmbedder < AbstractEmbedder
end
def embed
info 'Embedding C source files into Emacs.app for documentation purposes'
info 'Bundling C source files into Emacs.app for documentation purposes...'
src_dir = File.join(source_dir, 'src')
target_dir = File.join(resources_dir, 'src')
debug "Copying *.c and *.h files from '#{src_dir}' " \
"to: #{relative_path(target_dir)}"
Dir[File.join(src_dir, '**', '*.{c,h}')].each do |f|
rel = f[src_dir.size + 1..-1]
target = File.join(resources_dir, 'src', rel)
target = File.join(target_dir, rel)
FileUtils.mkdir_p(File.dirname(target))
cmd('cp', '-pRL', f, target)
end
@@ -836,6 +968,8 @@ class CSourcesEmbedder < AbstractEmbedder
return if File.exist?(site_start_el_file) &&
File.read(site_start_el_file).include?(PATH_PATCH)
debug "Patching '#{relative_path(site_start_el_file)}' to allow Emacs to " \
'find bundled C sources'
File.open(site_start_el_file, 'a') do |f|
f.puts("\n#{PATH_PATCH}")
end
@@ -853,7 +987,7 @@ class LibEmbedder < AbstractEmbedder
attr_reader :extra_libs
attr_reader :relink_eln_files
def initialize(app, lib_source, extra_libs = [], relink_eln_files = true)
def initialize(app, lib_source, extra_libs = [], relink_eln_files: true)
super(app)
@lib_source = lib_source
@@ -862,7 +996,7 @@ class LibEmbedder < AbstractEmbedder
end
def embed
info 'Embedding libraries into Emacs.app'
info 'Bundling shared libraries into Emacs.app...'
binary = "#{bin}-bin" if File.exist?("#{bin}-bin")
binary ||= bin
@@ -878,7 +1012,7 @@ class LibEmbedder < AbstractEmbedder
copy_extra_libs(extra_libs, binary) if extra_libs.any?
if relink_eln_files && eln_files.any?
info "Embedding libraries for #{eln_files.size} *.eln files " \
info "Bundling shared libraries for #{eln_files.size} *.eln files " \
'within Emacs.app'
eln_files.each { |f| copy_libs(f) }
@@ -899,49 +1033,76 @@ class LibEmbedder < AbstractEmbedder
return if rpaths.include?(rpath)
while_writable(exe) do
debug "Setting rpath for '#{relative_path(exe)}' to: #{rpath}"
cmd('install_name_tool', '-add_rpath', rpath, exe)
end
end
def copy_libs(exe)
exe_file = File.basename(exe)
exe_filename = File.basename(exe)
copied_libs = []
debug "Bundling shared libraries for: #{relative_path(exe)}"
`otool -L "#{exe}"`.split("\n")[1..-1].each do |line|
# Parse otool -L output
match = line.match(%r{^\s+(.+/(lib[^/ ]+))\s})
next unless match && match[1].start_with?(lib_source)
next unless match
lib_filepath = match[1]
lib_filename = File.basename(lib_filepath)
# Only bundle libraries from lib_source.
next unless lib_filepath.start_with?(lib_source)
unless File.exist?(lib_filepath)
warn "-- Shared library '#{lib_filepath}' does not exist, skipping"
next
end
copied = false
while_writable(exe) do
if match[2] == exe_file
cmd('install_name_tool', '-id',
File.join('@rpath', match[2].to_s), exe)
if lib_filename == exe_filename
id_name = File.join('@rpath', lib_filename)
debug "-- Setting install name to: #{id_name}"
cmd('install_name_tool', '-id', id_name, exe)
else
cmd('install_name_tool', '-change', match[1],
File.join('@rpath', match[2].to_s), exe)
debug "-- Bundling shared library: #{lib_filepath}"
lib_target = File.join(lib_dir, lib_filename)
unless File.exist?(lib_target)
debug '-- -- Copying to: ' \
"#{relative_path(File.join(lib_dir, lib_filename))}"
FileUtils.mkdir_p(lib_dir)
cmd('cp', '-pRL', lib_filepath, lib_target)
copied_libs << lib_target
copied = true
end
change_target = File.join('@rpath', lib_filename)
debug "-- -- Relinking to: #{change_target}"
cmd('install_name_tool', '-change', lib_filepath, change_target, exe)
end
end
next if match[2] == exe_file || File.exist?(File.join(lib_dir, match[2]))
FileUtils.mkdir_p(lib_dir)
cmd('cp', '-pRL', match[1], lib_dir)
copy_libs(File.join(lib_dir, match[2].to_s))
next if lib_filename == exe_filename || !copied
end
copied_libs.each { |lib| copy_libs(lib) }
end
def copy_extra_libs(extra_libs, exe)
def copy_extra_libs(extra_libs, _exe)
extra_libs.each do |lib|
debug "Bundling extra shared library: #{lib}"
lib_file = File.basename(lib)
target = "#{lib_dir}/#{lib_file}"
unless File.exist?(target)
FileUtils.mkdir_p(lib_dir)
debug "-- Copying to: #{lib_file}"
cmd('cp', '-pRL', lib, lib_dir)
end
while_writable(target) do
cmd('install_name_tool', '-id',
File.join('@rpath', lib_file), target)
end
copy_libs(target)
end
end
@@ -969,10 +1130,10 @@ class GccLibEmbedder < AbstractEmbedder
return
end
info 'Embedding libgccjit into Emacs.app'
info 'Bundling libgccjit into Emacs.app'
if gcc_info.lib_dir.empty?
err "No suitable GCC lib dir found in #{gcc_info.root_dir}"
fatal "No suitable GCC lib dir found in #{gcc_info.root_dir}"
end
FileUtils.mkdir_p(File.dirname(target_dir))
@@ -987,6 +1148,7 @@ class GccLibEmbedder < AbstractEmbedder
return if File.exist?(site_start_el_file) &&
File.read(site_start_el_file).include?(env_setup)
debug 'Setting up site-start.el for self-contained native-comp Emacs.app'
File.open(site_start_el_file, 'a') do |f|
f.puts("\n#{env_setup}")
end
@@ -1124,7 +1286,8 @@ class GccInfo
def libgccjit_lib_dir
@libgccjit_lib_dir ||= Dir[
File.join(libgccjit_root_dir, 'lib/gcc/*/libgccjit.so*')
File.join(libgccjit_root_dir, 'lib/gcc/*/libgccjit*.dylib'),
File.join(libgccjit_root_dir, 'lib/gcc/*/libgccjit.so*'),
]
.map { |path| File.dirname(path) }
.select { |path| File.basename(path).match(/^\d+$/) }
@@ -1132,18 +1295,18 @@ class GccInfo
end
def verify_libgccjit
err 'gcc not installed' unless Dir.exist?(root_dir)
err 'libgccjit not installed' unless Dir.exist?(libgccjit_root_dir)
fatal 'gcc not installed' unless Dir.exist?(root_dir)
fatal 'libgccjit not installed' unless Dir.exist?(libgccjit_root_dir)
if libgccjit_lib_dir&.empty?
err "Detected libgccjit (#{libgccjit_root_dir}) does not have any " \
'libgccjit.so* files. Please try reinstalling libgccjit: ' \
'brew reinstall libgccjit'
if libgccjit_lib_dir.empty?
fatal "Detected libgccjit (#{libgccjit_root_dir}) does not have any " \
'libgccjit.so* files. Please try reinstalling libgccjit: ' \
'brew reinstall libgccjit'
end
return if major_version == libgccjit_major_version
err <<~TEXT
fatal <<~TEXT
Detected GCC and libgccjit library paths do not belong to the same major
version of GCC. Detected paths:
- #{lib_dir}
@@ -1151,7 +1314,7 @@ class GccInfo
TEXT
end
def get_binding
def get_binding # rubocop:disable Naming/AccessorMethodName
binding
end
@@ -1174,11 +1337,15 @@ if __FILE__ == $PROGRAM_NAME
native_march: false,
parallel: Etc.nprocessors,
rsvg: true,
dbus: true,
xwidgets: true,
tree_sitter: true,
github_src_repo: nil,
github_auth: true,
dist_include: ['COPYING'],
archive: true,
archive_keep: false
archive_keep: false,
log_level: 'info'
}
begin
@@ -1210,6 +1377,12 @@ if __FILE__ == $PROGRAM_NAME
cli_options[:xwidgets] = v
end
opts.on('--[no-]tree-sitter',
'Enable/disable tree-sitter if supported' \
'(default: enabled)') do |v|
cli_options[:tree_sitter] = v
end
opts.on('--[no-]native-comp',
'Enable/disable native-comp ' \
'(default: enabled if supported)') do |v|
@@ -1240,12 +1413,17 @@ if __FILE__ == $PROGRAM_NAME
cli_options[:rsvg] = v
end
opts.on('--[no-]dbus',
'Enable/disable dbus support (default: enabled)') do |v|
cli_options[:dbus] = v
end
opts.on('--no-titlebar', 'Apply no-titlebar patch (default: disabled)') do
cli_options[:no_titlebar] = true
end
opts.on('--posix-spawn', 'Apply posix-spawn patch (default: disabled)') do
cli_options[:posix_spawn] = true
opts.on('--posix-spawn', 'Apply posix-spawn patch (deprecated)') do
warn '==> WARN: posix-spawn patch is deprecated as has no effect.'
end
opts.on('--no-frame-refocus',
@@ -1253,6 +1431,19 @@ if __FILE__ == $PROGRAM_NAME
cli_options[:no_frame_refocus] = true
end
opts.on('--[no-]poll',
'Enable/disable experimental use of poll() instead of select() ' \
'to support > 1024 file descriptors ' \
'(default: disabled)') do |v|
cli_options[:poll] = v
end
opts.on('--github-src-repo REPO',
'Specify a GitHub repo to download source tarballs from ' \
'(default: emacs-mirror/emacs)') do |v|
cli_options[:github_src_repo] = v
end
opts.on('--[no-]github-auth',
'Make authenticated GitHub API requests if GITHUB_TOKEN ' \
'environment variable is set.' \
@@ -1293,6 +1484,11 @@ if __FILE__ == $PROGRAM_NAME
cli_options[:archive_keep] = v
end
opts.on('--log-level LEVEL',
'Build script log level (default: info)') do |v|
cli_options[:log_level] = v
end
opts.on(
'--plan FILE',
'Follow given plan file, instead of using given git ref/sha'
@@ -1301,6 +1497,7 @@ if __FILE__ == $PROGRAM_NAME
end
end.parse!
Output.log_level = cli_options[:log_level]
work_dir = cli_options.delete(:work_dir)
Build.new(work_dir, ARGV.shift, cli_options).build
rescue Error => e

2
go.mod
View File

@@ -16,7 +16,7 @@ require (
github.com/hexops/gotextdiff v1.0.3
github.com/jimeh/undent v1.1.0
github.com/mattn/go-isatty v0.0.13 // indirect
github.com/mitchellh/gon v0.2.3
github.com/mitchellh/gon v0.2.5
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/stretchr/testify v1.7.0
github.com/urfave/cli/v2 v2.3.0

4
go.sum
View File

@@ -160,8 +160,8 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky
github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA=
github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/gon v0.2.3 h1:fObN7hD14VacGG++t27GzTW6opP0lwI7TsgTPL55wBo=
github.com/mitchellh/gon v0.2.3/go.mod h1:Ua18ZhqjZHg8VyqZo8kNHAY331ntV6nNJ9mT3s2mIo8=
github.com/mitchellh/gon v0.2.5 h1:mVWtqTzV03W0avJqmqjk9M0qls3TDUXfc9ETJaPIOWY=
github.com/mitchellh/gon v0.2.5/go.mod h1:Ua18ZhqjZHg8VyqZo8kNHAY331ntV6nNJ9mT3s2mIo8=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
resolve_link() {
"$(type -p greadlink readlink | head -1)" "$1"
"$(command -v greadlink || command -v readlink)" "$1"
}
abs_dirname() {

View File

@@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"regexp"
"strings"
)
// Errors
@@ -26,7 +27,8 @@ func VersionToName(version string) (string, error) {
return "", ErrEmptyVersion
}
if stableVersion.MatchString(version) {
if stableVersion.MatchString(version) ||
strings.HasSuffix(version, "-pretest") {
return "Emacs-" + version, nil
}