brew/Library/Homebrew/macos.rb
Max Howell 1555436f70 MacOS.sdk_path is unlicensed Xcode aware
Now we should get an sdk_path, but tools like xcodebuild, xcode-select and xcrun will still error out. But at least more of Homebrew will work.

Also putting the Xcode 3 path finder last. We get bug reports because newer Xcodes are installed in parallel to older Xcodes. We want to find and use the newer Xcode's first. Xcode.prefix is pretty smart about that.

Refs Homebrew/homebrew#14558.
2012-08-31 10:22:11 -04:00

232 lines
8.1 KiB
Ruby

module MacOS extend self
def version
require 'version'
MacOSVersion.new(MACOS_VERSION.to_s)
end
def cat
if version == :mountain_lion then :mountainlion
elsif version == :lion then :lion
elsif version == :snow_leopard then :snowleopard
elsif version == :leopard then :leopard
else nil
end
end
def locate tool
# Don't call tools (cc, make, strip, etc.) directly!
# Give the name of the binary you look for as a string to this method
# in order to get the full path back as a Pathname.
@locate ||= {}
@locate[tool.to_s] ||= if File.executable? "/usr/bin/#{tool}"
Pathname.new "/usr/bin/#{tool}"
else
# If the tool isn't in /usr/bin, then we first try to use xcrun to find
# it. If it's not there, or xcode-select is misconfigured, we have to
# look in dev_tools_path, and finally in xctoolchain_path, because the
# tools were split over two locations beginning with Xcode 4.3+.
xcrun_path = unless Xcode.bad_xcode_select_path?
`/usr/bin/xcrun -find #{tool} 2>/dev/null`.chomp
end
paths = %W[#{xcrun_path}
#{dev_tools_path}/#{tool}
#{xctoolchain_path}/usr/bin/#{tool}]
paths.map { |p| Pathname.new(p) }.find { |p| p.executable? }
end
end
def dev_tools_path
@dev_tools_path ||= if File.exist? "/usr/bin/cc" and File.exist? "/usr/bin/make"
# probably a safe enough assumption (the unix way)
Pathname.new "/usr/bin"
# Note that the exit status of system "xcrun foo" isn't always accurate
elsif not Xcode.bad_xcode_select_path? and not `/usr/bin/xcrun -find make 2>/dev/null`.empty?
# Wherever "make" is there are the dev tools.
Pathname.new(`/usr/bin/xcrun -find make`.chomp).dirname
elsif File.exist? "#{Xcode.prefix}/usr/bin/make"
# cc stopped existing with Xcode 4.3, there are c89 and c99 options though
Pathname.new "#{Xcode.prefix}/usr/bin"
else
# Since we are pretty unrelenting in finding Xcode no matter where
# it hides, we can now throw in the towel.
opoo "Could not locate developer tools. Consult `brew doctor`."
end
end
def xctoolchain_path
# As of Xcode 4.3, some tools are located in the "xctoolchain" directory
@xctoolchain_path ||= begin
path = Pathname.new("#{Xcode.prefix}/Toolchains/XcodeDefault.xctoolchain")
# If only the CLT are installed, all tools will be under dev_tools_path,
# this path won't exist, and xctoolchain_path will be nil.
path if path.exist?
end
end
def sdk_path(v = version)
@sdk_path ||= {}
@sdk_path[v.to_s] ||= begin
opts = []
# First query Xcode itself
opts << `#{locate('xcodebuild')} -version -sdk macosx#{v} Path 2>/dev/null`.chomp unless Xcode.bad_xcode_select_path?
# Xcode.prefix is pretty smart, so lets look inside to find the sdk
opts << "#{Xcode.prefix}/Platforms/MacOSX.platform/Developer/SDKs/MacOSX#{v}.sdk"
# Xcode < 4.3 style
opts << "/Developer/SDKs/MacOS#{v}.sdk"
opts.map{|a| Pathname.new(a) }.detect(&:directory?)
end
end
def default_cc
cc = locate 'cc'
Pathname.new(cc).realpath.basename.to_s rescue nil
end
def default_compiler
case default_cc
when /^gcc/ then :gcc
when /^llvm/ then :llvm
when "clang" then :clang
else
# guess :(
if Xcode.version >= "4.3"
:clang
elsif Xcode.version >= "4.2"
:llvm
else
:gcc
end
end
end
def gcc_40_build_version
@gcc_40_build_version ||= if locate("gcc-4.0")
`#{locate("gcc-4.0")} --version` =~ /build (\d{4,})/
$1.to_i
end
end
def gcc_42_build_version
@gcc_42_build_version ||= if locate("gcc-4.2") \
and not locate("gcc-4.2").realpath.basename.to_s =~ /^llvm/
`#{locate("gcc-4.2")} --version` =~ /build (\d{4,})/
$1.to_i
end
end
def llvm_build_version
# for Xcode 3 on OS X 10.5 this will not exist
# NOTE may not be true anymore but we can't test
@llvm_build_version ||= if locate("llvm-gcc")
`#{locate("llvm-gcc")} --version` =~ /LLVM build (\d{4,})/
$1.to_i
end
end
def clang_version
@clang_version ||= if locate("clang")
`#{locate("clang")} --version` =~ /clang version (\d\.\d)/
$1
end
end
def clang_build_version
@clang_build_version ||= if locate("clang")
`#{locate("clang")} --version` =~ %r[tags/Apple/clang-(\d{2,})]
$1.to_i
end
end
def macports_or_fink_installed?
# See these issues for some history:
# http://github.com/mxcl/homebrew/issues/#issue/13
# http://github.com/mxcl/homebrew/issues/#issue/41
# http://github.com/mxcl/homebrew/issues/#issue/48
return false unless MACOS
%w[port fink].each do |ponk|
path = which(ponk)
return ponk unless path.nil?
end
# we do the above check because macports can be relocated and fink may be
# able to be relocated in the future. This following check is because if
# fink and macports are not in the PATH but are still installed it can
# *still* break the build -- because some build scripts hardcode these paths:
%w[/sw/bin/fink /opt/local/bin/port].each do |ponk|
return ponk if File.exist? ponk
end
# finally, sometimes people make their MacPorts or Fink read-only so they
# can quickly test Homebrew out, but still in theory obey the README's
# advise to rename the root directory. This doesn't work, many build scripts
# error out when they try to read from these now unreadable directories.
%w[/sw /opt/local].each do |path|
path = Pathname.new(path)
return path if path.exist? and not path.readable?
end
false
end
def prefer_64_bit?
Hardware.is_64_bit? and version != :leopard
end
StandardCompilers = {
"3.1.4" => {:gcc_40_build_version=>5493, :gcc_42_build_version=>5577},
"3.2.6" => {:gcc_40_build_version=>5494, :gcc_42_build_version=>5666, :llvm_build_version=>2335, :clang_version=>"1.7", :clang_build_version=>77},
"4.0" => {:gcc_40_build_version=>5494, :gcc_42_build_version=>5666, :llvm_build_version=>2335, :clang_version=>"2.0", :clang_build_version=>137},
"4.0.1" => {:gcc_40_build_version=>5494, :gcc_42_build_version=>5666, :llvm_build_version=>2335, :clang_version=>"2.0", :clang_build_version=>137},
"4.0.2" => {:gcc_40_build_version=>5494, :gcc_42_build_version=>5666, :llvm_build_version=>2335, :clang_version=>"2.0", :clang_build_version=>137},
"4.2" => {:llvm_build_version=>2336, :clang_version=>"3.0", :clang_build_version=>211},
"4.3" => {:llvm_build_version=>2336, :clang_version=>"3.1", :clang_build_version=>318},
"4.3.1" => {:llvm_build_version=>2336, :clang_version=>"3.1", :clang_build_version=>318},
"4.3.2" => {:llvm_build_version=>2336, :clang_version=>"3.1", :clang_build_version=>318},
"4.3.3" => {:llvm_build_version=>2336, :clang_version=>"3.1", :clang_build_version=>318},
"4.4" => {:llvm_build_version=>2336, :clang_version=>"4.0", :clang_build_version=>421},
"4.4.1" => {:llvm_build_version=>2336, :clang_version=>"4.0", :clang_build_version=>421}
}
def compilers_standard?
xcode = Xcode.version
unless StandardCompilers.keys.include? xcode
onoe <<-EOS.undent
Homebrew doesn't know what compiler versions ship with your version of
Xcode. Please file an issue with the output of `brew --config`:
https://github.com/mxcl/homebrew/issues
Thanks!
EOS
end
StandardCompilers[xcode].all? { |method, build| MacOS.send(method) == build }
end
def app_with_bundle_id id
path = mdfind(id).first
Pathname.new(path) unless path.nil? or path.empty?
end
def mdfind id
`/usr/bin/mdfind "kMDItemCFBundleIdentifier == '#{id}'"`.split("\n")
end
def pkgutil_info id
`/usr/sbin/pkgutil --pkg-info "#{id}" 2>/dev/null`.strip
end
def bottles_supported?
# We support bottles on all versions of OS X except 32-bit Snow Leopard.
(Hardware.is_64_bit? or not MacOS.snow_leopard?) \
and HOMEBREW_PREFIX.to_s == '/usr/local' \
and HOMEBREW_CELLAR.to_s == '/usr/local/Cellar' \
end
end
require 'macos/xcode'
require 'macos/xquartz'