mirror of
https://github.com/jimeh/build-emacs-for-macos.git
synced 2026-02-19 13:06:38 +00:00
Update and fix things for current Emacs trunk (24.4)
Notes: - The sRGB patch is now a simple text-replacement, as diff/patch files seem to just fail. Even Homebrew's emacs formula does it this way. - Removed fullscreen patch, as Emacs 24.4 includes fullscreen support on OS X, both native and pre-Lion style fullscreen. More details here: http://www.emacswiki.org/emacs/FullScreen#toc23
This commit is contained in:
33
README.md
33
README.md
@@ -1,20 +1,24 @@
|
||||
# build-emacs-for-osx
|
||||
|
||||
Use this script at your own risk. It currently works for me on my own machine,
|
||||
which as of writing runs:
|
||||
which as of writing is:
|
||||
|
||||
* Mac OS X Lion 10.7.3 (11D50)
|
||||
* Xcode 4.2 (4D199)
|
||||
* OS X 10.8.5 (12F45)
|
||||
* Xcode 5.0 (5A1413)
|
||||
|
||||
Your luck might vary. Do note that it does not build a universal application.
|
||||
The CPU architecture of the built application will be that of the machine it
|
||||
was built on.
|
||||
|
||||
|
||||
## Why?
|
||||
|
||||
I've been using [Homebrew](http://mxcl.github.com/homebrew/) the past few
|
||||
I've been using [Homebrew][] the past few
|
||||
months to build from HEAD. Homebrew comes with a number of patches, including
|
||||
the [ns-toogle-fullscreen][fs] and [sRGB][] patches which I use.
|
||||
the [sRGB][] patches which I use.
|
||||
|
||||
[homebrew]: http://mxcl.github.com/homebrew/
|
||||
[srgb]: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=8402
|
||||
|
||||
Homebrew does not build a self-contained application though, which caused
|
||||
issues for me when I needed to rollback to a specific build. I found the
|
||||
@@ -25,30 +29,31 @@ So I decided to quickly hack together a script to automate that manual
|
||||
process. The code is a horrible hack, but it (seemingly) works as I'm writing
|
||||
this in Emacs built with it.
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
Myself I run the following command which will download a tarball of the
|
||||
`master` branch, apply the fullscreen and sRGB patches, and build Emacs.app:
|
||||
`master` branch, apply the sRGB patch, and build Emacs.app:
|
||||
|
||||
./build-emacs-for-osx
|
||||
|
||||
Or for example if you want to build the `EMACS_PRETEST_24_0_91` tag, run:
|
||||
Or for example if you want to build the `emacs-24.3` tag, run:
|
||||
|
||||
./build-emacs-for-osx EMACS_PRETEST_24_0_91
|
||||
./build-emacs-for-osx emacs-24.3
|
||||
|
||||
Resulting applications are saved to the `builds` directory in a bzip2
|
||||
compressed tarball.
|
||||
|
||||
|
||||
## Internals
|
||||
|
||||
I decided to pull Emacs' source from the GitHub mirror rather than the
|
||||
I decided to pull Emacs' source from a GitHub [mirror][repo] rather than the
|
||||
official Bzr repo cause I'm not familiar with Bzr, and GitHub lets you easily
|
||||
download tarballs of any branch, commit or tag.
|
||||
download tarballs of any branch, commit or tag. And the tarballs from GitHub
|
||||
are just over 30MB, compared to ~1GB to pull the offical Bzr repo.
|
||||
|
||||
[repo]: https://github.com/mirrors/emacs
|
||||
|
||||
The only option passed in `./configure` is `--with-ns`, meaning the resulting
|
||||
application only supports the CPU architecture of the system is was built on.
|
||||
There might be more side-effects to, but I haven't noticed any.
|
||||
|
||||
|
||||
[fs]: https://gist.github.com/1012927
|
||||
[srgb]: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=8402
|
||||
|
||||
@@ -8,8 +8,8 @@ require 'optparse'
|
||||
# Config
|
||||
#
|
||||
|
||||
DOWNLOAD_URL = "https://github.com/emacsmirror/emacs/tarball/%s"
|
||||
LATEST_URL = "https://api.github.com/repos/emacsmirror/emacs/commits?sha=%s"
|
||||
DOWNLOAD_URL = "https://github.com/mirrors/emacs/tarball/%s"
|
||||
LATEST_URL = "https://api.github.com/repos/mirrors/emacs/commits?sha=%s"
|
||||
|
||||
ROOT_DIR = File.expand_path('..', __FILE__)
|
||||
TARBALL_DIR = "#{ROOT_DIR}/tarballs"
|
||||
@@ -46,22 +46,15 @@ end
|
||||
def patches(opts = {})
|
||||
p = []
|
||||
|
||||
if opts[:fullscreen]
|
||||
if !opts[:lion]
|
||||
# Use non-Lion fullscreen patch. Works on Lion, but doesn't integrate
|
||||
# with Mission Control like a "true" Lion Fullscreen app.
|
||||
p << 'https://raw.github.com/gist/1746342/' +
|
||||
'702dfe9e2dd79fddd536aa90d561efdeec2ba716'
|
||||
else
|
||||
# Use a "true" Lion Fullscreen patch.
|
||||
p << 'https://raw.github.com/gist/2238260/' +
|
||||
'e44224323706d3fa8b435e75a0da7b461801ae5f'
|
||||
end
|
||||
end
|
||||
|
||||
if opts[:srgb]
|
||||
p << 'https://raw.github.com/gist/1361934/' +
|
||||
'f5b58b8d5f06650749addbe2a198b8cf1d0ce5a3'
|
||||
p << {
|
||||
:replace => [
|
||||
"src/nsterm.m",
|
||||
"*col = [NSColor colorWithCalibratedRed: r green: g blue: b alpha: 1.0];",
|
||||
"*col = [NSColor colorWithDeviceRed: r green: g blue: b alpha: 1.0];"
|
||||
]
|
||||
}
|
||||
end
|
||||
|
||||
p
|
||||
@@ -73,22 +66,14 @@ end
|
||||
#
|
||||
|
||||
def parse_options
|
||||
options = {
|
||||
:lion => false,
|
||||
:fullscreen => true,
|
||||
:srgb => true
|
||||
}
|
||||
options = {:srgb => true}
|
||||
|
||||
OptionParser.new do |opts|
|
||||
opts.banner = "Usage: ./build-emacs-for-osx [options] [branch/tag/sha]"
|
||||
|
||||
opts.on("--lion", "Enable 'true' Lion fullscreen mode.") do
|
||||
options[:lion] = true
|
||||
end
|
||||
|
||||
opts.on("--no-fullscreen", "Skip fullscreen patch.") do
|
||||
options[:fullscreen] = false
|
||||
end
|
||||
opts.banner = "Usage: ./build-emacs-for-osx [options] [branch/tag/sha]\n" +
|
||||
"\n" +
|
||||
"Branch, tag, and SHA are from the mirrors/emacs Github repo,\n" +
|
||||
"available here: https://github.com/mirrors/emacs\n" +
|
||||
"\n"
|
||||
|
||||
opts.on('--no-srgb', "Skip sRGB patch.") do
|
||||
options[:srgb] = false
|
||||
@@ -108,7 +93,7 @@ def download_tarball(sha)
|
||||
|
||||
url = (DOWNLOAD_URL % sha)
|
||||
|
||||
filename = "emacsmirror-emacs-#{sha[0..6]}.tgz"
|
||||
filename = "mirrors-emacs-#{sha[0..6]}.tgz"
|
||||
target = File.join(TARBALL_DIR, filename)
|
||||
|
||||
if !File.exist?(target)
|
||||
@@ -132,8 +117,8 @@ def extract_tarball(filename, patches = [])
|
||||
puts "\nExtracting tarball..."
|
||||
system "tar -xzf \"#{filename}\" -C \"#{SOURCES_DIR}\""
|
||||
raise "\nERROR: Tarball extraction failed." unless File.exist?(target)
|
||||
patches.each do |url|
|
||||
apply_patch(url, target)
|
||||
patches.each do |patch|
|
||||
apply_patch(patch, target)
|
||||
end
|
||||
else
|
||||
puts "\nINFO: #{dirname} source tree exists, attempting to use."
|
||||
@@ -152,7 +137,7 @@ def compile_source(source)
|
||||
end
|
||||
|
||||
system "cd \"#{source}\" && ./configure --with-ns"
|
||||
system "cd \"#{source}\" && make bootstrap"
|
||||
# system "cd \"#{source}\" && make bootstrap"
|
||||
system "cd \"#{source}\" && make install"
|
||||
|
||||
raise "\nERROR: Build failed." unless File.exist?("#{target}/Emacs.app")
|
||||
@@ -199,22 +184,40 @@ def get_ref_info(ref = 'master')
|
||||
}
|
||||
end
|
||||
|
||||
def apply_patch(url, target)
|
||||
def apply_patch(patch, target)
|
||||
raise "ERROR: \"#{target}\" does not exist." unless File.exist?(target)
|
||||
system "mkdir -p \"#{target}/patches\""
|
||||
if patch[:url]
|
||||
system "mkdir -p \"#{target}/patches\""
|
||||
|
||||
patch_file = "#{target}/patches/patch-{num}.diff"
|
||||
num = 1
|
||||
while File.exist? patch_file.gsub('{num}', num.to_s.rjust(3, '0'))
|
||||
num += 1
|
||||
patch_file = "#{target}/patches/patch-{num}.diff"
|
||||
num = 1
|
||||
while File.exist? patch_file.gsub('{num}', num.to_s.rjust(3, '0'))
|
||||
num += 1
|
||||
end
|
||||
patch_file.gsub!('{num}', num.to_s.rjust(3, '0'))
|
||||
|
||||
puts "Downloading patch: #{url}"
|
||||
system "curl -L# \"#{url}\" -o \"#{patch_file}\""
|
||||
|
||||
puts "Applying patch..."
|
||||
system "cd \"#{target}\" && patch -f -p1 -i \"#{patch_file}\""
|
||||
elsif patch[:replace]
|
||||
raise "ERROR: Patch replace input error" unless patch[:replace].size == 3
|
||||
file, before, after = patch[:replace]
|
||||
filepath = File.join(target, file)
|
||||
|
||||
if !File.exist?(filepath)
|
||||
raise "ERROR: \"#{file}\" does not exist in #{target}"
|
||||
end
|
||||
|
||||
f = File.open(filepath, 'rb')
|
||||
s = f.read
|
||||
sub = s.gsub!(before, after)
|
||||
raise "ERROR: Replacement filed in #{file}" if sub.nil?
|
||||
|
||||
f.reopen(filepath, 'wb').write(s)
|
||||
f.close
|
||||
end
|
||||
patch_file.gsub!('{num}', num.to_s.rjust(3, '0'))
|
||||
|
||||
puts "Downloading patch: #{url}"
|
||||
system "curl -L# \"#{url}\" -o \"#{patch_file}\""
|
||||
|
||||
puts "Applying patch..."
|
||||
system "cd \"#{target}\" && patch -f -p1 -i \"#{patch_file}\""
|
||||
end
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user