aboutsummaryrefslogtreecommitdiffstats
path: root/Library
diff options
context:
space:
mode:
Diffstat (limited to 'Library')
-rw-r--r--Library/Homebrew/cmd/bottle.rb48
-rw-r--r--Library/Homebrew/formula_installer.rb15
-rw-r--r--Library/Homebrew/formula_support.rb5
-rw-r--r--Library/Homebrew/keg_fix_install_names.rb48
-rw-r--r--Library/Homebrew/test/testball.rb1
5 files changed, 98 insertions, 19 deletions
diff --git a/Library/Homebrew/cmd/bottle.rb b/Library/Homebrew/cmd/bottle.rb
index cda1d776d..6f703d4b3 100644
--- a/Library/Homebrew/cmd/bottle.rb
+++ b/Library/Homebrew/cmd/bottle.rb
@@ -1,8 +1,13 @@
require 'formula'
require 'bottles'
require 'tab'
+require 'keg'
module Homebrew extend self
+ def keg_contains string, keg
+ quiet_system 'fgrep', '--recursive', '--quiet', '--max-count=1', string, keg
+ end
+
def bottle_formula f
unless f.installed?
return ofail "Formula not installed: #{f.name}"
@@ -18,23 +23,48 @@ module Homebrew extend self
bottle_path = Pathname.pwd/filename
sha1 = nil
+ prefix = HOMEBREW_PREFIX.to_s
+ tmp_prefix = '/tmp'
+ cellar = HOMEBREW_CELLAR.to_s
+ tmp_cellar = '/tmp/Cellar'
+
HOMEBREW_CELLAR.cd do
ohai "Bottling #{f.name} #{f.version}..."
- bottle_relocatable = !quiet_system(
- 'grep', '--recursive', '--quiet', '--max-count=1',
- HOMEBREW_CELLAR, "#{f.name}/#{f.version}")
- cellar = nil
- if bottle_relocatable
- cellar = ':any'
- elsif HOMEBREW_CELLAR.to_s != '/usr/local/Cellar'
- cellar = "'#{HOMEBREW_CELLAR}'"
- end
# Use gzip, faster to compress than bzip2, faster to uncompress than bzip2
# or an uncompressed tarball (and more bandwidth friendly).
safe_system 'tar', 'czf', bottle_path, "#{f.name}/#{f.version}"
sha1 = bottle_path.sha1
+ relocatable = false
+
+ keg = Keg.new f.prefix
+ keg.lock do
+ # Relocate bottle library references before testing for built-in
+ # references to the Cellar e.g. Qt's QMake annoyingly does this.
+ keg.relocate_install_names prefix, tmp_prefix, cellar, tmp_cellar
+
+ relocatable = !keg_contains(HOMEBREW_PREFIX, keg)
+ relocatable = !keg_contains(HOMEBREW_CELLAR, keg) if relocatable
+
+ # And do the same thing in reverse to change the library references
+ # back to how they were.
+ keg.relocate_install_names tmp_prefix, prefix, tmp_cellar, cellar
+ end
+
+ prefix = cellar = nil
+ if relocatable
+ cellar = ':any'
+ else
+ if HOMEBREW_PREFIX.to_s != '/usr/local'
+ prefix = "'#{HOMEBREW_PREFIX}"
+ end
+ if HOMEBREW_CELLAR.to_s != '/usr/local/Cellar'
+ cellar = "'#{HOMEBREW_CELLAR}'"
+ end
+ end
+
puts "./#{filename}"
puts "bottle do"
+ puts " prefix #{prefix}" if prefix
puts " cellar #{cellar}" if cellar
puts " revision #{bottle_revision}" if bottle_revision > 0
puts " sha1 '#{sha1}' => :#{MacOS.cat}"
diff --git a/Library/Homebrew/formula_installer.rb b/Library/Homebrew/formula_installer.rb
index 9251fe487..767db6e63 100644
--- a/Library/Homebrew/formula_installer.rb
+++ b/Library/Homebrew/formula_installer.rb
@@ -96,13 +96,13 @@ class FormulaInstaller
begin
if pour_bottle?
pour
- poured_bottle = true
+ @poured_bottle = true
end
rescue
opoo "Bottle installation failed: building from source."
end
- unless poured_bottle
+ unless @poured_bottle
build
clean
end
@@ -353,6 +353,17 @@ class FormulaInstaller
def fix_install_names
Keg.new(f.prefix).fix_install_names
+ if @poured_bottle
+ old_prefix = f.bottle.prefix
+ new_prefix = HOMEBREW_PREFIX.to_s
+ old_cellar = f.bottle.cellar
+ new_cellar = HOMEBREW_CELLAR.to_s
+
+ if old_prefix != new_prefix or old_cellar != new_cellar
+ Keg.new(f.prefix).relocate_install_names \
+ old_prefix, new_prefix, old_cellar, new_cellar
+ end
+ end
rescue Exception => e
onoe "Failed to fix install names"
puts "The formula built, but you may encounter issues using it or linking other"
diff --git a/Library/Homebrew/formula_support.rb b/Library/Homebrew/formula_support.rb
index 4fa06c0e7..23472547f 100644
--- a/Library/Homebrew/formula_support.rb
+++ b/Library/Homebrew/formula_support.rb
@@ -85,6 +85,7 @@ class Bottle < SoftwareSpec
def initialize
super
@revision = 0
+ @prefix = '/usr/local'
@cellar = '/usr/local/Cellar'
@cat_without_underscores = false
end
@@ -117,6 +118,10 @@ class Bottle < SoftwareSpec
val.nil? ? @root_url : @root_url = val
end
+ def prefix val=nil
+ val.nil? ? @prefix : @prefix = val
+ end
+
def cellar val=nil
val.nil? ? @cellar : @cellar = val
end
diff --git a/Library/Homebrew/keg_fix_install_names.rb b/Library/Homebrew/keg_fix_install_names.rb
index dd647660a..bdb98286f 100644
--- a/Library/Homebrew/keg_fix_install_names.rb
+++ b/Library/Homebrew/keg_fix_install_names.rb
@@ -2,7 +2,7 @@ class Keg
def fix_install_names
return unless MACOS
mach_o_files.each do |file|
- bad_install_names_for file do |id, bad_names|
+ install_names_for file do |id, bad_names|
file.ensure_writable do
system MacOS.locate("install_name_tool"), "-id", id, file if file.dylib?
@@ -31,13 +31,50 @@ class Keg
end
end
+ def relocate_install_names old_prefix, new_prefix, old_cellar, new_cellar
+ mach_o_files.each do |file|
+ install_names_for(file, relocate_reject_proc(old_prefix)) do |id, old_prefix_names|
+ file.ensure_writable do
+ new_prefix_id = id.to_s.gsub old_prefix, new_prefix
+ system MacOS.locate("install_name_tool"), "-id", new_prefix_id, file if file.dylib?
+
+ old_prefix_names.each do |old_prefix_name|
+ new_prefix_name = old_prefix_name.to_s.gsub old_prefix, new_prefix
+ system MacOS.locate("install_name_tool"), "-change", old_prefix_name, new_prefix_name, file
+ end
+ end
+ end
+
+ install_names_for(file, relocate_reject_proc(old_cellar)) do |id, old_cellar_names|
+ file.ensure_writable do
+ old_cellar_names.each do |old_cellar_name|
+ new_cellar_name = old_cellar_name.to_s.gsub old_cellar, new_cellar
+ system MacOS.locate("install_name_tool"), "-change", old_cellar_name, new_cellar_name, file
+ end
+ end
+ end
+ end
+ end
+
private
OTOOL_RX = /\t(.*) \(compatibility version (\d+\.)*\d+, current version (\d+\.)*\d+\)/
def lib; join 'lib' end
- def bad_install_names_for file
+ def default_reject_proc
+ Proc.new do |fn|
+ # Don't fix absolute paths unless they are rooted in the build directory
+ tmp = ENV['HOMEBREW_TEMP'] ? Regexp.escape(ENV['HOMEBREW_TEMP']) : '/tmp'
+ fn[0,1] == '/' and not %r[^#{tmp}] === fn
+ end
+ end
+
+ def relocate_reject_proc(path)
+ Proc.new { |fn| not fn.start_with?(path) }
+ end
+
+ def install_names_for file, reject_proc=default_reject_proc
ENV['HOMEBREW_MACH_O_FILE'] = file.to_s # solves all shell escaping problems
install_names = `#{MacOS.locate("otool")} -L "$HOMEBREW_MACH_O_FILE"`.split "\n"
@@ -49,12 +86,7 @@ class Keg
install_names.compact!
install_names.reject!{ |fn| fn =~ /^@(loader_|executable_|r)path/ }
-
- # Don't fix absolute paths unless they are rooted in the build directory
- install_names.reject! do |fn|
- tmp = ENV['HOMEBREW_TEMP'] ? Regexp.escape(ENV['HOMEBREW_TEMP']) : '/tmp'
- fn[0,1] == '/' and not %r[^#{tmp}] === fn
- end
+ install_names.reject!{ |fn| reject_proc.call(fn) }
# the shortpath ensures that library upgrades don’t break installed tools
relative_path = Pathname.new(file).relative_path_from(self)
diff --git a/Library/Homebrew/test/testball.rb b/Library/Homebrew/test/testball.rb
index d3054810a..f685f5e2c 100644
--- a/Library/Homebrew/test/testball.rb
+++ b/Library/Homebrew/test/testball.rb
@@ -221,6 +221,7 @@ class AllCatsBottleSpecTestBall < Formula
sha1 '482e737739d946b7c8cbaf127d9ee9c148b999f5'
bottle do
+ prefix '/private/tmp/testbrew/prefix'
cellar '/private/tmp/testbrew/cellar'
sha1 'deadbeefdeadbeefdeadbeefdeadbeefdeadbeef' => :snow_leopard_32
sha1 'faceb00cfaceb00cfaceb00cfaceb00cfaceb00c' => :snow_leopard