mirror of
https://github.com/jimeh/build-emacs-for-macos.git
synced 2026-02-19 13:06:38 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
09e67381cb
|
|||
|
d21ccad3e4
|
|||
| 036d2a82d9 | |||
|
111cb64993
|
11
CHANGELOG.md
11
CHANGELOG.md
@@ -2,6 +2,17 @@
|
||||
|
||||
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.3.0](https://github.com/jimeh/build-emacs-for-macos/compare/0.2.0...0.3.0) (2020-09-22)
|
||||
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
* **native_comp:** `--[no-]launcher` option is deprecated, as launcher script is no longer used.
|
||||
|
||||
### Features
|
||||
|
||||
* **native_comp:** use elisp patch instead of launcher script to set LIBRARY_PATH ([111cb64](https://github.com/jimeh/build-emacs-for-macos/commit/111cb6499368d14853a5927d38a43fc5e2f759f4)), closes [#14](https://github.com/jimeh/build-emacs-for-macos/issues/14)
|
||||
|
||||
## [0.2.0](https://github.com/jimeh/build-emacs-for-macos/compare/0.1.1...0.2.0) (2020-09-20)
|
||||
|
||||
|
||||
|
||||
19
README.md
19
README.md
@@ -160,26 +160,13 @@ By default natively compiled `*.eln` files will be cached in
|
||||
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
|
||||
zero-byte file size if Emacs is quit while async native compilation is in
|
||||
progress. Such empty files causes errors on startup, and needs to be deleted.
|
||||
|
||||
Below is an example which stores all compiled `*.eln` files in `cache/eln-cache`
|
||||
within your Emacs configuration directory, and also deletes any `*.eln` files in
|
||||
said directory which have a file size of zero bytes:
|
||||
within your Emacs configuration directory:
|
||||
|
||||
```elisp
|
||||
(when (boundp 'comp-eln-load-path)
|
||||
(let ((eln-cache-dir (expand-file-name "cache/eln-cache/"
|
||||
user-emacs-directory))
|
||||
(find-exec (executable-find "find")))
|
||||
(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
|
||||
(call-process find-exec nil nil nil eln-cache-dir
|
||||
"-name" "*.eln" "-size" "0" "-delete" "-or"
|
||||
"-name" "*.eln.tmp" "-size" "0" "-delete"))))
|
||||
(setcar comp-eln-load-path
|
||||
(expand-file-name "cache/eln-cache/" user-emacs-directory)))
|
||||
```
|
||||
|
||||
### Issues
|
||||
|
||||
@@ -72,7 +72,6 @@ class Build
|
||||
DOWNLOAD_URL = 'https://github.com/emacs-mirror/emacs/tarball/%s'
|
||||
LATEST_URL = 'https://api.github.com/repos/emacs-mirror/emacs/commits/%s'
|
||||
NATIVE_COMP_REF_REGEXP = %r{^feature/native-comp}.freeze
|
||||
LAUNCHER_TEMPLATE = './launcher.bash.erb'
|
||||
|
||||
attr_reader :root_dir
|
||||
attr_reader :source_dir
|
||||
@@ -96,16 +95,11 @@ class Build
|
||||
autogen
|
||||
detect_native_comp if options[:native_comp].nil?
|
||||
|
||||
if options[:native_comp] && options[:launcher].nil?
|
||||
options[:launcher] = true
|
||||
end
|
||||
|
||||
app = compile_source(@source_dir)
|
||||
symlink_internals(app)
|
||||
|
||||
LibEmbedder.new(app, brew_dir, extra_libs).embed
|
||||
LibGccJitEmbedder.new(app, gcc_dir).embed if options[:native_comp]
|
||||
LauncherEmbedder.new(app, LAUNCHER_TEMPLATE).embed if options[:launcher]
|
||||
|
||||
archive_app(app)
|
||||
end
|
||||
@@ -256,6 +250,8 @@ class Build
|
||||
apply_native_comp_macos_fixes
|
||||
end
|
||||
|
||||
apply_native_comp_env_setup_patch(source)
|
||||
|
||||
ENV['CFLAGS'] = [
|
||||
"-I#{gcc_dir}/include",
|
||||
'-O2',
|
||||
@@ -426,6 +422,17 @@ class Build
|
||||
system(*args) || err("Exit code: #{$CHILD_STATUS.exitstatus}")
|
||||
end
|
||||
|
||||
def apply_native_comp_env_setup_patch(source)
|
||||
term = 'native-compile-setup-environment-variables'
|
||||
file = 'lisp/emacs-lisp/comp.el'
|
||||
return if `grep '#{term}' '#{file}'`.strip.size.positive?
|
||||
|
||||
apply_patch(
|
||||
{ file: "#{__dir__}/patches/native-comp-env-setup.patch" },
|
||||
source
|
||||
)
|
||||
end
|
||||
|
||||
def apply_native_comp_macos_fixes
|
||||
filename = 'Makefile.in'
|
||||
pattern = /^src: Makefile\n(.*BIN_DESTDIR.*)\nblessmail: Makefile src\n/m
|
||||
@@ -521,7 +528,10 @@ class Build
|
||||
def apply_patch(patch, target)
|
||||
err "\"#{target}\" does not exist." unless File.exist?(target)
|
||||
|
||||
if patch[:url]
|
||||
if patch[:file]
|
||||
info 'Applying patch...'
|
||||
FileUtils.cd(target) { run_cmd('patch', '-f', '-p1', '-i', patch[:file]) }
|
||||
elsif patch[:url]
|
||||
patch_dir = "#{target}/macos_patches"
|
||||
run_cmd('mkdir', '-p', patch_dir)
|
||||
|
||||
@@ -535,8 +545,7 @@ class Build
|
||||
info "Downloading patch: #{patch[:url]}"
|
||||
run_cmd('curl', '-L#', patch[:url], '-o', patch_file)
|
||||
|
||||
info 'Applying patch...'
|
||||
FileUtils.cd(target) { run_cmd('patch', '-f', '-p1', '-i', patch_file) }
|
||||
apply_patch({ file: patch_file }, target)
|
||||
elsif patch[:replace]
|
||||
err 'Patch replace input error' unless patch[:replace].size == 3
|
||||
|
||||
@@ -739,67 +748,6 @@ class LibGccJitEmbedder < AbstractEmbedder
|
||||
end
|
||||
end
|
||||
|
||||
class LauncherEmbedder < AbstractEmbedder
|
||||
attr_reader :template
|
||||
|
||||
def initialize(app, template)
|
||||
super(app)
|
||||
|
||||
@template = template
|
||||
end
|
||||
|
||||
def embed
|
||||
if embedded?
|
||||
info 'Launcher script already embedded in Emacs.app'
|
||||
return
|
||||
end
|
||||
|
||||
info 'Embedding launcher script into Emacs.app'
|
||||
|
||||
unless File.exist?("#{bin}#{bin_suffix}")
|
||||
FileUtils.mv(bin, "#{bin}#{bin_suffix}")
|
||||
end
|
||||
|
||||
unless File.exist?("#{bin}#{bin_suffix}#{dump_ext}")
|
||||
FileUtils.mv("#{bin}#{dump_ext}", "#{bin}#{bin_suffix}#{dump_ext}")
|
||||
end
|
||||
|
||||
unless File.exist?(bin)
|
||||
File.write(bin, launcher)
|
||||
File.chmod(0o775, bin)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def bin_suffix
|
||||
'-bin'
|
||||
end
|
||||
|
||||
def dump_ext
|
||||
'.pdmp'
|
||||
end
|
||||
|
||||
def embedded?
|
||||
File.exist?(bin) &&
|
||||
File.exist?("#{bin}#{bin_suffix}") &&
|
||||
File.exist?("#{bin}#{bin_suffix}#{dump_ext}")
|
||||
end
|
||||
|
||||
def launcher
|
||||
@launcher ||= ERB.new(File.read(template)).result(binding)
|
||||
end
|
||||
|
||||
def library_paths
|
||||
@library_paths ||= Dir[
|
||||
"#{lib_dir}/gcc/*",
|
||||
"#{lib_dir}/gcc/*/gcc/*apple-darwin*/*"
|
||||
].map do |p|
|
||||
p.gsub(/^#{Regexp.escape(lib_dir + '/')}/, '')
|
||||
end.sort_by { |p| [p.size, p] }
|
||||
end
|
||||
end
|
||||
|
||||
if __FILE__ == $PROGRAM_NAME
|
||||
cli_options = {
|
||||
macos_fixes: true,
|
||||
@@ -855,12 +803,6 @@ if __FILE__ == $PROGRAM_NAME
|
||||
cli_options[:macos_fixes] = v
|
||||
end
|
||||
|
||||
opts.on('--[no-]launcher',
|
||||
'Enable/disable embedded launcher script ' \
|
||||
'(default: enabled if native-comp is enabled)') do |v|
|
||||
cli_options[:launcher] = v
|
||||
end
|
||||
|
||||
opts.on('--rsvg', 'Enable SVG image support via librsvg, ' \
|
||||
'can yield a unstable build (default: disabled)') do
|
||||
cli_options[:rsvg] = true
|
||||
@@ -885,6 +827,12 @@ if __FILE__ == $PROGRAM_NAME
|
||||
'use --native-full-aot instead'
|
||||
end
|
||||
end
|
||||
|
||||
opts.on('--[no-]launcher',
|
||||
'DEPRECATED: Launcher script is no longer used.') do |_|
|
||||
raise Error, '--[no-]launcher option is deprecated, launcher ' \
|
||||
'script is no longer used.'
|
||||
end
|
||||
end.parse!
|
||||
|
||||
Build.new(File.expand_path(__dir__), ARGV.shift, cli_options).build
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
#!/bin/bash
|
||||
# This launcher script is not part of Emacs proper. It is from the
|
||||
# build-emacs-for-macos project (https://github.com/jimeh/build-emacs-for-macos)
|
||||
# and helps facilitate proper startup of Emacs with environment varibales set as
|
||||
# needed.
|
||||
#
|
||||
# Licensed under CC0 1.0 Universal:
|
||||
# https://creativecommons.org/publicdomain/zero/1.0/
|
||||
#
|
||||
set -e
|
||||
|
||||
resolve_link() {
|
||||
local file="$1"
|
||||
|
||||
while [ -L "$file" ]; do
|
||||
file="$(readlink "$file")"
|
||||
done
|
||||
|
||||
echo "$file"
|
||||
}
|
||||
|
||||
realname() {
|
||||
local path="$1"
|
||||
local resolved
|
||||
local cwd
|
||||
|
||||
cwd="$(pwd)"
|
||||
resolved="$(resolve_link "$path")"
|
||||
cd "$(dirname "$resolved")"
|
||||
echo "$(pwd)/$(basename "$resolved")"
|
||||
cd "$cwd"
|
||||
}
|
||||
|
||||
join() {
|
||||
local IFS="$1"
|
||||
local parts=()
|
||||
shift
|
||||
|
||||
for arg in "$@"; do
|
||||
if [ "$arg" != "" ]; then
|
||||
parts+=("$arg")
|
||||
fi
|
||||
done
|
||||
|
||||
echo "${parts[*]}"
|
||||
}
|
||||
|
||||
DIR="$(dirname "$(realname "$0")")"
|
||||
BIN="${DIR}/Emacs<%= bin_suffix %>"
|
||||
|
||||
export PATH="${DIR}/bin:${DIR}/libexec:${PATH}"
|
||||
<% if library_paths.any? %>
|
||||
LIB_PATHS=(
|
||||
'<%= library_paths.map { |p| p.gsub('\'', "\"'\"") }.join("'\n '") %>'
|
||||
)
|
||||
for lib in "${LIB_PATHS[@]}"; do
|
||||
if [ -d "${DIR}/<%= lib_dir_name %>/${lib}" ]; then
|
||||
libs="$(join : "$libs" "${DIR}/<%= lib_dir_name %>/${lib}")"
|
||||
fi
|
||||
done
|
||||
|
||||
LIBRARY_PATH="$(join : "$libs" "$LIBRARY_PATH")"
|
||||
export LIBRARY_PATH
|
||||
<% end %>
|
||||
exec "$BIN" "$@"
|
||||
41
patches/native-comp-env-setup.patch
Normal file
41
patches/native-comp-env-setup.patch
Normal file
@@ -0,0 +1,41 @@
|
||||
diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el
|
||||
index 25e2de9..14ee6dc 100644
|
||||
--- a/lisp/emacs-lisp/comp.el
|
||||
+++ b/lisp/emacs-lisp/comp.el
|
||||
@@ -2801,6 +2801,36 @@ queued with LOAD %"
|
||||
(comp-run-async-workers)
|
||||
(message "Compilation started."))))
|
||||
|
||||
+;;;###autoload
|
||||
+(defun native-compile-setup-environment-variables (&rest _args)
|
||||
+ "Ensure LIBRARY_PATH is set correctly when libgccjit is bundled."
|
||||
+ (when (and (eq system-type 'darwin)
|
||||
+ (string-match-p "\.app\/Contents\/MacOS\/?$"
|
||||
+ invocation-directory))
|
||||
+ (let* ((library-path-env (getenv "LIBRARY_PATH"))
|
||||
+ (gcc-dir (car (file-expand-wildcards
|
||||
+ (concat invocation-directory "lib-*/gcc/*"))))
|
||||
+ (gcc-darwin-dir (car (file-expand-wildcards
|
||||
+ (concat gcc-dir "/gcc/*apple-darwin*/*"))))
|
||||
+ (lib-paths (append
|
||||
+ (list gcc-dir gcc-darwin-dir)
|
||||
+ (if library-path-env (list library-path-env) (list)))))
|
||||
+
|
||||
+ (when (and gcc-dir gcc-darwin-dir)
|
||||
+ (setenv "LIBRARY_PATH" (mapconcat 'identity lib-paths ":")))))
|
||||
+
|
||||
+ ;; Remove advice, as it only needs to run once.
|
||||
+ (advice-remove 'native-compile
|
||||
+ 'native-compile-setup-environment-variables)
|
||||
+ (advice-remove 'native-compile-async
|
||||
+ 'native-compile-setup-environment-variables))
|
||||
+
|
||||
+;; Ensure environment setup runs before any native compilation.
|
||||
+(advice-add 'native-compile :before
|
||||
+ 'native-compile-setup-environment-variables)
|
||||
+(advice-add 'native-compile-async :before
|
||||
+ 'native-compile-setup-environment-variables)
|
||||
+
|
||||
(provide 'comp)
|
||||
|
||||
;;; comp.el ends here
|
||||
Reference in New Issue
Block a user