diff --git a/README.md b/README.md index 7947307..e684bc7 100644 --- a/README.md +++ b/README.md @@ -141,7 +141,7 @@ Options: --[no-]relink-eln-files Enable/disable re-linking shared libraries in bundled *.eln files (default: enabled) --[no-]rsvg Enable/disable SVG image support via librsvg (default: enabled) --[no-]dbus Enable/disable dbus support (default: enabled) - --[no-]alpha-background Enable/disable experimental alpha-background patch when building Emacs 30.x - 31.x (default: disabled) + --alpha-background Apply experimental alpha-background patch when building Emacs 30.x - 31.x (default: disabled) --no-frame-refocus Apply no-frame-refocus patch when building Emacs 27.x - 31.x (default: disabled) --no-titlebar Apply no-titlebar patch when building Emacs 27.x - 28.x (default: disabled) --[no-]xwidgets Enable/disable XWidgets when building Emacs 27.x (default: disabled) @@ -155,6 +155,7 @@ Options: -o, --output DIR Output directory for finished builds (default: /builds) --build-name NAME Override generated build name --dist-include x,y,z List of extra files to copy from Emacs source into build folder/archive (default: COPYING) + --icon-uri URI Local path or URL to a .icns file to replace the default app icon --[no-]self-sign Enable/disable self-signing of Emacs.app (default: enabled) --[no-]archive Enable/disable creating *.tbz archive (default: enabled) --[no-]archive-keep-build-dir diff --git a/build-emacs-for-macos b/build-emacs-for-macos index 11d2c76..ea90fad 100755 --- a/build-emacs-for-macos +++ b/build-emacs-for-macos @@ -229,6 +229,7 @@ class Build handle_native_lisp(app) + IconEmbedder.new(app, options[:icon_uri]).embed if options[:icon_uri] CLIHelperEmbedder.new(app).embed CSourcesEmbedder.new(app, @source_dir).embed LibEmbedder.new( @@ -1413,6 +1414,59 @@ class CSourcesEmbedder < AbstractEmbedder end end +class IconEmbedder < AbstractEmbedder + include Helpers + + def initialize(app, icon_uri) + super(app) + + @icon_uri = icon_uri + end + + def embed + return if @icon_uri.nil? || @icon_uri.strip.empty? + + source = resolve_source(@icon_uri) + + unless File.extname(source).downcase == '.icns' + fatal 'Icon must be a .icns file' + end + + target = File.join(resources_dir, 'Emacs.icns') + info 'Replacing application icon...' + run_cmd('cp', '-pRL', source, target) + ensure + cleanup_download_tmpdir(source) + end + + private + + def resolve_source(uri) + if valid_url?(uri) + download_icon(uri) + else + path = File.expand_path(uri) + fatal "Icon file does not exist: #{path}" unless File.exist?(path) + path + end + end + + def download_icon(url) + @download_tmpdir = Dir.mktmpdir(%w[emacs-icon .tmp]) + path = File.join(@download_tmpdir, 'icon.icns') + info "Downloading icon from: #{url}" + run_cmd('curl', '-L#', url, '-o', path) + path + end + + def cleanup_download_tmpdir(source) + return unless @download_tmpdir && source + return unless source.start_with?(@download_tmpdir) + + FileUtils.rm_rf(@download_tmpdir) + end +end + class LibEmbedder < AbstractEmbedder attr_reader :lib_sources attr_reader :extra_libs @@ -2127,6 +2181,7 @@ class CLIOptions github_src_repo: nil, github_auth: true, dist_include: ['COPYING', 'configure_output.txt'], + icon_uri: nil, self_sign: true, archive: true, archive_keep: false, @@ -2323,6 +2378,11 @@ class CLIOptions 'folder/archive (default: COPYING)' ) { |v| options[:dist_include] = v } + opts.on( + '--icon-uri URI', + 'Local path or URL to a .icns file to replace the default app icon' + ) { |v| options[:icon_uri] = v } + opts.on( '--[no-]self-sign', 'Enable/disable self-signing of Emacs.app (default: enabled)'