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.
|
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)
|
## [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
|
the first element of the `comp-eln-load-path` variable. The path string must end
|
||||||
with a `/`.
|
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`
|
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
|
within your Emacs configuration directory:
|
||||||
said directory which have a file size of zero bytes:
|
|
||||||
|
|
||||||
```elisp
|
```elisp
|
||||||
(when (boundp 'comp-eln-load-path)
|
(when (boundp 'comp-eln-load-path)
|
||||||
(let ((eln-cache-dir (expand-file-name "cache/eln-cache/"
|
(setcar comp-eln-load-path
|
||||||
user-emacs-directory))
|
(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"))))
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Issues
|
### Issues
|
||||||
|
|||||||
@@ -72,7 +72,6 @@ class Build
|
|||||||
DOWNLOAD_URL = 'https://github.com/emacs-mirror/emacs/tarball/%s'
|
DOWNLOAD_URL = 'https://github.com/emacs-mirror/emacs/tarball/%s'
|
||||||
LATEST_URL = 'https://api.github.com/repos/emacs-mirror/emacs/commits/%s'
|
LATEST_URL = 'https://api.github.com/repos/emacs-mirror/emacs/commits/%s'
|
||||||
NATIVE_COMP_REF_REGEXP = %r{^feature/native-comp}.freeze
|
NATIVE_COMP_REF_REGEXP = %r{^feature/native-comp}.freeze
|
||||||
LAUNCHER_TEMPLATE = './launcher.bash.erb'
|
|
||||||
|
|
||||||
attr_reader :root_dir
|
attr_reader :root_dir
|
||||||
attr_reader :source_dir
|
attr_reader :source_dir
|
||||||
@@ -96,16 +95,11 @@ class Build
|
|||||||
autogen
|
autogen
|
||||||
detect_native_comp if options[:native_comp].nil?
|
detect_native_comp if options[:native_comp].nil?
|
||||||
|
|
||||||
if options[:native_comp] && options[:launcher].nil?
|
|
||||||
options[:launcher] = true
|
|
||||||
end
|
|
||||||
|
|
||||||
app = compile_source(@source_dir)
|
app = compile_source(@source_dir)
|
||||||
symlink_internals(app)
|
symlink_internals(app)
|
||||||
|
|
||||||
LibEmbedder.new(app, brew_dir, extra_libs).embed
|
LibEmbedder.new(app, brew_dir, extra_libs).embed
|
||||||
LibGccJitEmbedder.new(app, gcc_dir).embed if options[:native_comp]
|
LibGccJitEmbedder.new(app, gcc_dir).embed if options[:native_comp]
|
||||||
LauncherEmbedder.new(app, LAUNCHER_TEMPLATE).embed if options[:launcher]
|
|
||||||
|
|
||||||
archive_app(app)
|
archive_app(app)
|
||||||
end
|
end
|
||||||
@@ -256,6 +250,8 @@ class Build
|
|||||||
apply_native_comp_macos_fixes
|
apply_native_comp_macos_fixes
|
||||||
end
|
end
|
||||||
|
|
||||||
|
apply_native_comp_env_setup_patch(source)
|
||||||
|
|
||||||
ENV['CFLAGS'] = [
|
ENV['CFLAGS'] = [
|
||||||
"-I#{gcc_dir}/include",
|
"-I#{gcc_dir}/include",
|
||||||
'-O2',
|
'-O2',
|
||||||
@@ -426,6 +422,17 @@ class Build
|
|||||||
system(*args) || err("Exit code: #{$CHILD_STATUS.exitstatus}")
|
system(*args) || err("Exit code: #{$CHILD_STATUS.exitstatus}")
|
||||||
end
|
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
|
def apply_native_comp_macos_fixes
|
||||||
filename = 'Makefile.in'
|
filename = 'Makefile.in'
|
||||||
pattern = /^src: Makefile\n(.*BIN_DESTDIR.*)\nblessmail: Makefile src\n/m
|
pattern = /^src: Makefile\n(.*BIN_DESTDIR.*)\nblessmail: Makefile src\n/m
|
||||||
@@ -521,7 +528,10 @@ class Build
|
|||||||
def apply_patch(patch, target)
|
def apply_patch(patch, target)
|
||||||
err "\"#{target}\" does not exist." unless File.exist?(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"
|
patch_dir = "#{target}/macos_patches"
|
||||||
run_cmd('mkdir', '-p', patch_dir)
|
run_cmd('mkdir', '-p', patch_dir)
|
||||||
|
|
||||||
@@ -535,8 +545,7 @@ class Build
|
|||||||
info "Downloading patch: #{patch[:url]}"
|
info "Downloading patch: #{patch[:url]}"
|
||||||
run_cmd('curl', '-L#', patch[:url], '-o', patch_file)
|
run_cmd('curl', '-L#', patch[:url], '-o', patch_file)
|
||||||
|
|
||||||
info 'Applying patch...'
|
apply_patch({ file: patch_file }, target)
|
||||||
FileUtils.cd(target) { run_cmd('patch', '-f', '-p1', '-i', patch_file) }
|
|
||||||
elsif patch[:replace]
|
elsif patch[:replace]
|
||||||
err 'Patch replace input error' unless patch[:replace].size == 3
|
err 'Patch replace input error' unless patch[:replace].size == 3
|
||||||
|
|
||||||
@@ -739,67 +748,6 @@ class LibGccJitEmbedder < AbstractEmbedder
|
|||||||
end
|
end
|
||||||
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
|
if __FILE__ == $PROGRAM_NAME
|
||||||
cli_options = {
|
cli_options = {
|
||||||
macos_fixes: true,
|
macos_fixes: true,
|
||||||
@@ -855,12 +803,6 @@ if __FILE__ == $PROGRAM_NAME
|
|||||||
cli_options[:macos_fixes] = v
|
cli_options[:macos_fixes] = v
|
||||||
end
|
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, ' \
|
opts.on('--rsvg', 'Enable SVG image support via librsvg, ' \
|
||||||
'can yield a unstable build (default: disabled)') do
|
'can yield a unstable build (default: disabled)') do
|
||||||
cli_options[:rsvg] = true
|
cli_options[:rsvg] = true
|
||||||
@@ -885,6 +827,12 @@ if __FILE__ == $PROGRAM_NAME
|
|||||||
'use --native-full-aot instead'
|
'use --native-full-aot instead'
|
||||||
end
|
end
|
||||||
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!
|
end.parse!
|
||||||
|
|
||||||
Build.new(File.expand_path(__dir__), ARGV.shift, cli_options).build
|
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