@@ -19,6 +19,102 @@ require 'yaml'
19
19
20
20
require 'macho'
21
21
22
+ # Custom patch for startup of macOS, allowing Emacs .app bundles to correctly
23
+ # use bundled libgccjit libraries and C sources.
24
+ MACOS_STARTUP_PATCH_SOURCE = <<~PATCH
25
+ From 52b5b168b9db532a18538dc0acc8a1299152fd09 Mon Sep 17 00:00:00 2001
26
+ From: Jim Myhrberg <[email protected] >
27
+ Date: Sun, 1 Dec 2024 08:45:51 +0000
28
+ Subject: [PATCH] feat(macos/startup): add macos-startup.el
29
+
30
+ ---
31
+ lisp/loadup.el | 1 +
32
+ lisp/macos-startup.el | 60 +++++++++++++++++++++++++++++++++++++++++++
33
+ 2 files changed, 61 insertions(+)
34
+ create mode 100644 lisp/macos-startup.el
35
+
36
+ diff --git a/lisp/loadup.el b/lisp/loadup.el
37
+ index bd74a9d6aff..b1d29a3c929 100644
38
+ --- a/lisp/loadup.el
39
+ +++ b/lisp/loadup.el
40
+ @@ -268,6 +268,7 @@
41
+ (load "minibuffer") ; Needs cl-generic, seq (and define-minor-mode).
42
+ (load "frame")
43
+ (load "startup")
44
+ +(load "macos-startup")
45
+ (load "term/tty-colors")
46
+ (load "font-core")
47
+ (load "emacs-lisp/syntax")
48
+ diff --git a/lisp/macos-startup.el b/lisp/macos-startup.el
49
+ new file mode 100644
50
+ index 00000000000..9fb6887f10b
51
+ --- /dev/null
52
+ +++ b/lisp/macos-startup.el
53
+ @@ -0,0 +1,60 @@
54
+ +;;; macos-startup.el --- macOS specific startup actions -*- lexical-binding: t -*-
55
+ +
56
+ +;; Maintainer: Jim Myhrberg <[email protected] >
57
+ +;; Keywords: macos, internal
58
+ +;; Homepage: https://github.com./jimeh/build-emacs-for-macos
59
+ +
60
+ +;; This file is not part of GNU Emacs.
61
+ +
62
+ +;;; Commentary:
63
+ +
64
+ +;; This file contains macOS specific startup actions for self-contained
65
+ +;; macOS *.app bundles. It enables native-compilation via the bundled
66
+ +;; libgccjit, and for the bundled C-sources to be found for
67
+ +;; documentation purposes,
68
+ +
69
+ +;;; Code:
70
+ +
71
+ +(defun macos-startup--in-app-bundle-p ()
72
+ + "Check if invoked from a macOS .app bundle."
73
+ + (and (eq system-type 'darwin)
74
+ + invocation-directory
75
+ + (string-match-p "\\ .app/Contents/MacOS/?$" invocation-directory)))
76
+ +
77
+ +(defun macos-startup--set-source-directory ()
78
+ + "Set `source-directory' so that C-sources can be located."
79
+ + (let* ((src-dir (expand-file-name "../Resources/src" invocation-directory)))
80
+ + (when (file-directory-p src-dir)
81
+ + (setq source-directory (file-name-directory src-dir)))))
82
+ +
83
+ +(defun macos-startup--setup-library-path ()
84
+ + "Configure LIBRARY_PATH env var for native compilation on macOS.
85
+ +
86
+ +Ensures LIBRARY_PATH includes paths to the libgccjit and gcc libraries
87
+ +which are bundled into the .app bundle. This allows native compilation
88
+ +to work without any external system dependencies aside from Xcode."
89
+ + (let* ((new-paths
90
+ + (list (expand-file-name "../Frameworks/gcc/lib" invocation-directory)
91
+ + (expand-file-name "../Frameworks/gcc/lib/apple-darwin" invocation-directory)
92
+ + "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib"))
93
+ + (valid-paths (delq nil (mapcar (lambda (path)
94
+ + (when (file-directory-p path)
95
+ + path))
96
+ + new-paths)))
97
+ + (existing-paths (split-string (or (getenv "LIBRARY_PATH") "") ":" t))
98
+ + (unique-paths (delete-dups (append valid-paths existing-paths))))
99
+ +
100
+ + (when unique-paths
101
+ + (setenv "LIBRARY_PATH" (mapconcat 'identity unique-paths path-separator)))))
102
+ +
103
+ +(defun macos-startup--init ()
104
+ + "Perform macOS specific startup operations."
105
+ + (when (macos-startup--in-app-bundle-p)
106
+ + (macos-startup--set-source-directory)
107
+ + (when (and (fboundp 'native-comp-available-p)
108
+ + (native-comp-available-p))
109
+ + (macos-startup--setup-library-path))))
110
+ +
111
+ +(add-hook 'after-pdump-load-hook #'macos-startup--init)
112
+ +
113
+ +;;; macos-startup.el ends here
114
+ --
115
+ 2.47.0
116
+ PATCH
117
+
22
118
class Error < StandardError
23
119
end
24
120
@@ -1038,6 +1134,8 @@ class Build
1038
1134
}
1039
1135
end
1040
1136
1137
+ p << { source : MACOS_STARTUP_PATCH_SOURCE }
1138
+
1041
1139
p . uniq
1042
1140
end
1043
1141
@@ -1068,6 +1166,20 @@ class Build
1068
1166
else
1069
1167
apply_patch ( { file : patch_file } , target )
1070
1168
end
1169
+ elsif patch [ :source ]
1170
+ patch_dir = "#{ target } /macos_patches"
1171
+ run_cmd ( 'mkdir' , '-p' , patch_dir )
1172
+
1173
+ patch_file = File . join ( patch_dir , 'patch-{num}.diff' )
1174
+ num = 1
1175
+ while File . exist? ( patch_file . gsub ( '{num}' , num . to_s . rjust ( 3 , '0' ) ) )
1176
+ num += 1
1177
+ end
1178
+ patch_file = patch_file . gsub ( '{num}' , num . to_s . rjust ( 3 , '0' ) )
1179
+
1180
+ File . write ( patch_file , patch [ :source ] )
1181
+
1182
+ apply_patch ( { file : patch_file } , target )
1071
1183
elsif patch [ :replace ]
1072
1184
fatal 'Patch replace input error' unless patch [ :replace ] . size == 3
1073
1185
@@ -1198,12 +1310,6 @@ class CLIHelperEmbedder < AbstractEmbedder
1198
1310
end
1199
1311
1200
1312
class CSourcesEmbedder < AbstractEmbedder
1201
- PATH_PATCH = <<~ELISP
1202
- ;; Allow Emacs to find bundled C sources.
1203
- (setq source-directory
1204
- (expand-file-name ".." (file-name-directory load-file-name)))
1205
- ELISP
1206
-
1207
1313
attr_reader :source_dir
1208
1314
1209
1315
def initialize ( app , source_dir )
@@ -1228,15 +1334,6 @@ class CSourcesEmbedder < AbstractEmbedder
1228
1334
src_dir , target_dir , File . join ( '**' , '*.{awk,c,cc,h,in,m,mk}' )
1229
1335
)
1230
1336
end
1231
-
1232
- if File . exist? ( site_start_el_file ) &&
1233
- File . read ( site_start_el_file ) . include? ( PATH_PATCH )
1234
- return
1235
- end
1236
-
1237
- debug "Patching '#{ relative_app_path ( site_start_el_file ) } ' to allow " \
1238
- 'Emacs to find bundled C sources'
1239
- File . open ( site_start_el_file , 'a' ) { |f | f . puts ( "\n #{ PATH_PATCH } " ) }
1240
1337
end
1241
1338
1242
1339
private
@@ -1521,49 +1618,13 @@ class GccLibEmbedder < AbstractEmbedder
1521
1618
1522
1619
FileUtils . rm ( Dir [ File . join ( target_dir , '**' , '.DS_Store' ) ] , force : true )
1523
1620
1524
- if target_darwin_dir != sanitized_target_darwin_dir
1525
- run_cmd ( 'mv' , target_darwin_dir , sanitized_target_darwin_dir )
1526
- end
1621
+ return unless target_darwin_dir != sanitized_target_darwin_dir
1527
1622
1528
- env_setup = ERB . new ( NATIVE_COMP_ENV_VAR_TPL ) . result ( gcc_info . get_binding )
1529
- if File . exist? ( site_start_el_file ) &&
1530
- File . read ( site_start_el_file ) . include? ( env_setup )
1531
- return
1532
- end
1533
-
1534
- debug 'Setting up site-start.el for self-contained native-comp Emacs.app'
1535
- File . open ( site_start_el_file , 'a' ) { |f | f . puts ( "\n #{ env_setup } " ) }
1623
+ run_cmd ( 'mv' , target_darwin_dir , sanitized_target_darwin_dir )
1536
1624
end
1537
1625
1538
1626
private
1539
1627
1540
- NATIVE_COMP_ENV_VAR_TPL = <<~ELISP
1541
- ;; Set LIBRARY_PATH to point at bundled GCC and Xcode Command Line Tools to
1542
- ;; ensure native-comp works.
1543
- (when (and (eq system-type 'darwin)
1544
- (string-match-p "\\ .app\\ /Contents\\ /MacOS\\ /?$"
1545
- invocation-directory))
1546
- (let* ((library-path-env (getenv "LIBRARY_PATH"))
1547
- (devtools-dir
1548
- "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib")
1549
- (gcc-dir (expand-file-name
1550
- "<%= app_bundle_target_lib_dir %>"
1551
- invocation-directory))
1552
- (darwin-dir (expand-file-name
1553
- "<%= app_bundle_target_darwin_lib_dir %>"
1554
- invocation-directory))
1555
- (lib-paths (list)))
1556
-
1557
- (if library-path-env
1558
- (push library-path-env lib-paths))
1559
- (if (file-directory-p devtools-dir)
1560
- (push devtools-dir lib-paths))
1561
- (push darwin-dir lib-paths)
1562
- (push gcc-dir lib-paths)
1563
-
1564
- (setenv "LIBRARY_PATH" (mapconcat 'identity lib-paths ":"))))
1565
- ELISP
1566
-
1567
1628
# Remove all rpaths from Mach-O library files except for @loader_path.
1568
1629
def tidy_lib_rpaths ( directory )
1569
1630
Dir [ File . join ( directory , '**' , '*.{dylib,so}' ) ] . each do |file_path |
0 commit comments