brew/Library/Homebrew/keg_fix_install_names.rb
samueljohn 725feb3db1 Core change: XCode only install, with CLT or both
Allow XCode without the Command Line Tools to
work with homebrew, so it's not necessary
to register an Apple Dev ID and/or go to the
XCode prefs and download the CLT. Yay!

Further, this commit allows to use the CLT
solely (without the need for XCode).
Saves quite some megs.
(Some furmulae require xcodebuild)

Of course XCode together with the CLT is still
fine and has been tested on 10.7 and 10.6
with Xcode 4 and Xcode 3.

Only on Lion or above, tell the user about the options,
which are
- Xcode without CLT
- CLT without Xcode
- both (ok, it's not directly stated, but implicit)
So if no Xcode is found and we are on Lion or above,
we don't fail but check for the CLTs now.
For older Macs, the old message that Xcode is needed
and the installer should be run is still displayed.
If the CLT are not found but Xcode is, then we
print out about the experimental status of this setup.

Closes Homebrew/homebrew#10510.

Signed-off-by: Adam Vandenberg <flangy@gmail.com>
2012-06-24 19:11:06 -07:00

78 lines
2.6 KiB
Ruby
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

require 'find'
class Keg
def fix_install_names
mach_o_files.each do |file|
bad_install_names_for file do |id, bad_names|
file.ensure_writable do
system MacOS.locate("install_name_tool"), "-id", id, file if file.dylib?
bad_names.each do |bad_name|
new_name = bad_name
new_name = Pathname.new(bad_name).basename unless (file.parent + new_name).exist?
# First check to see if the dylib is present in the current
# directory, so we can skip the more expensive search.
if (file.parent + new_name).exist?
system MacOS.locate("install_name_tool"), "-change", bad_name, "@loader_path/#{new_name}", file
else
# Otherwise, try and locate the appropriate dylib by walking
# the entire 'lib' tree recursively.
abs_name = (self+'lib').find do |pn|
break pn if pn.basename == Pathname.new(new_name)
end
if abs_name and abs_name.exist?
system MacOS.locate("install_name_tool"), "-change", bad_name, abs_name, file
else
opoo "Could not fix install names for #{file}"
end
end
end
end
end
end
end
private
OTOOL_RX = /\t(.*) \(compatibility version (\d+\.)*\d+, current version (\d+\.)*\d+\)/
def bad_install_names_for file
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"
install_names.shift # first line is fluff
install_names.map!{ |s| OTOOL_RX =~ s && $1 }
# Bundles don't have an ID
id = install_names.shift unless file.mach_o_bundle?
install_names.compact!
install_names.reject!{ |fn| fn =~ /^@(loader|executable)_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
# the shortpath ensures that library upgrades dont break installed tools
shortpath = HOMEBREW_PREFIX + Pathname.new(file).relative_path_from(self)
id = if shortpath.exist? then shortpath else file end
yield id, install_names
end
def mach_o_files
mach_o_files = []
if (lib = join 'lib').directory?
lib.find do |pn|
next if pn.symlink? or pn.directory?
mach_o_files << pn if pn.dylib? or pn.mach_o_bundle?
end
end
mach_o_files
end
end