2012-06-27 12:09:57 -07:00
|
|
|
module MacOS extend self
|
2012-06-28 12:49:54 -05:00
|
|
|
|
2012-09-04 23:04:01 -05:00
|
|
|
# This can be compared to numerics, strings, or symbols
|
|
|
|
# using the standard Ruby Comparable methods.
|
2012-06-27 12:09:57 -07:00
|
|
|
def version
|
2012-08-04 00:26:59 -05:00
|
|
|
require 'version'
|
|
|
|
MacOSVersion.new(MACOS_VERSION.to_s)
|
2012-06-27 12:09:57 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
def cat
|
2012-08-14 11:37:29 -05:00
|
|
|
if version == :mountain_lion then :mountainlion
|
|
|
|
elsif version == :lion then :lion
|
|
|
|
elsif version == :snow_leopard then :snowleopard
|
|
|
|
elsif version == :leopard then :leopard
|
|
|
|
else nil
|
2012-06-27 12:09:57 -07:00
|
|
|
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.
|
2013-01-08 10:15:57 -06:00
|
|
|
(@locate ||= {}).fetch(tool.to_s) do
|
|
|
|
@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
|
2012-08-17 23:22:34 -05:00
|
|
|
|
2013-01-08 10:15:57 -06:00
|
|
|
paths = %W[#{xcrun_path}
|
|
|
|
#{dev_tools_path}/#{tool}
|
|
|
|
#{xctoolchain_path}/usr/bin/#{tool}]
|
|
|
|
paths.map { |p| Pathname.new(p) }.find { |p| p.executable? }
|
|
|
|
end
|
2012-06-27 12:09:57 -07:00
|
|
|
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"
|
2012-08-09 16:33:41 -05:00
|
|
|
# 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?
|
2012-06-27 12:09:57 -07:00
|
|
|
# Wherever "make" is there are the dev tools.
|
|
|
|
Pathname.new(`/usr/bin/xcrun -find make`.chomp).dirname
|
2012-07-09 14:58:34 -05:00
|
|
|
elsif File.exist? "#{Xcode.prefix}/usr/bin/make"
|
2012-06-27 12:09:57 -07:00
|
|
|
# cc stopped existing with Xcode 4.3, there are c89 and c99 options though
|
2012-07-09 14:58:34 -05:00
|
|
|
Pathname.new "#{Xcode.prefix}/usr/bin"
|
2012-06-27 12:09:57 -07:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def xctoolchain_path
|
2012-06-30 14:01:07 -05:00
|
|
|
# As of Xcode 4.3, some tools are located in the "xctoolchain" directory
|
2012-06-27 12:09:57 -07:00
|
|
|
@xctoolchain_path ||= begin
|
2012-07-09 14:58:34 -05:00
|
|
|
path = Pathname.new("#{Xcode.prefix}/Toolchains/XcodeDefault.xctoolchain")
|
2012-06-30 14:01:07 -05:00
|
|
|
# If only the CLT are installed, all tools will be under dev_tools_path,
|
2012-06-30 14:10:03 -05:00
|
|
|
# this path won't exist, and xctoolchain_path will be nil.
|
2012-06-30 14:01:07 -05:00
|
|
|
path if path.exist?
|
2012-06-27 12:09:57 -07:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-08-31 09:51:08 -04:00
|
|
|
def sdk_path(v = version)
|
2013-01-08 10:15:57 -06:00
|
|
|
(@sdk_path ||= {}).fetch(v.to_s) do
|
|
|
|
@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/MacOSX#{v}.sdk"
|
|
|
|
opts.map{|a| Pathname.new(a) }.detect { |p| p.directory? }
|
|
|
|
end
|
2012-06-27 12:09:57 -07:00
|
|
|
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 :(
|
2012-07-09 14:58:34 -05:00
|
|
|
if Xcode.version >= "4.3"
|
2012-06-27 12:09:57 -07:00
|
|
|
:clang
|
2012-07-09 14:58:34 -05:00
|
|
|
elsif Xcode.version >= "4.2"
|
2012-06-27 12:09:57 -07:00
|
|
|
:llvm
|
|
|
|
else
|
|
|
|
:gcc
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-06-28 12:50:10 -05:00
|
|
|
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
|
|
|
|
|
2012-06-27 12:09:57 -07:00
|
|
|
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
|
|
|
|
|
2012-12-17 17:05:53 -06:00
|
|
|
# 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
|
|
|
|
def macports_or_fink
|
|
|
|
paths = []
|
|
|
|
|
|
|
|
# First look in the path because MacPorts is relocatable and Fink
|
|
|
|
# may become relocatable in the future.
|
|
|
|
%w{port fink}.each do |ponk|
|
2012-06-27 12:09:57 -07:00
|
|
|
path = which(ponk)
|
2012-12-17 17:05:53 -06:00
|
|
|
paths << path unless path.nil?
|
2012-06-27 12:09:57 -07:00
|
|
|
end
|
|
|
|
|
2012-12-17 17:05:53 -06:00
|
|
|
# Look in the standard locations, because even if port or fink are
|
|
|
|
# not in the path they can still break builds if the build scripts
|
|
|
|
# have these paths baked in.
|
|
|
|
%w{/sw/bin/fink /opt/local/bin/port}.each do |ponk|
|
|
|
|
path = Pathname.new(ponk)
|
|
|
|
paths << path if path.exist?
|
2012-06-27 12:09:57 -07:00
|
|
|
end
|
|
|
|
|
2012-12-17 17:05:53 -06:00
|
|
|
# Finally, some users make their MacPorts or Fink directorie
|
|
|
|
# read-only in order to try out Homebrew, but this doens't work as
|
|
|
|
# some build scripts error out when trying to read from these now
|
|
|
|
# unreadable paths.
|
|
|
|
%w{/sw /opt/local}.map { |p| Pathname.new(p) }.each do |path|
|
|
|
|
paths << path if path.exist? && !path.readable?
|
2012-06-27 12:09:57 -07:00
|
|
|
end
|
|
|
|
|
2012-12-17 17:05:53 -06:00
|
|
|
paths.uniq
|
2012-06-27 12:09:57 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
def prefer_64_bit?
|
2012-08-14 11:37:29 -05:00
|
|
|
Hardware.is_64_bit? and version != :leopard
|
2012-06-27 12:09:57 -07:00
|
|
|
end
|
|
|
|
|
2012-10-15 18:16:18 -05:00
|
|
|
STANDARD_COMPILERS = {
|
|
|
|
"3.1.4" => { :gcc_40_build => 5493, :gcc_42_build => 5577 },
|
|
|
|
"3.2.6" => { :gcc_40_build => 5494, :gcc_42_build => 5666, :llvm_build => 2335, :clang => "1.7", :clang_build => 77 },
|
|
|
|
"4.0" => { :gcc_40_build => 5494, :gcc_42_build => 5666, :llvm_build => 2335, :clang => "2.0", :clang_build => 137 },
|
|
|
|
"4.0.1" => { :gcc_40_build => 5494, :gcc_42_build => 5666, :llvm_build => 2335, :clang => "2.0", :clang_build => 137 },
|
|
|
|
"4.0.2" => { :gcc_40_build => 5494, :gcc_42_build => 5666, :llvm_build => 2335, :clang => "2.0", :clang_build => 137 },
|
|
|
|
"4.2" => { :llvm_build => 2336, :clang => "3.0", :clang_build => 211 },
|
|
|
|
"4.3" => { :llvm_build => 2336, :clang => "3.1", :clang_build => 318 },
|
|
|
|
"4.3.1" => { :llvm_build => 2336, :clang => "3.1", :clang_build => 318 },
|
|
|
|
"4.3.2" => { :llvm_build => 2336, :clang => "3.1", :clang_build => 318 },
|
|
|
|
"4.3.3" => { :llvm_build => 2336, :clang => "3.1", :clang_build => 318 },
|
|
|
|
"4.4" => { :llvm_build => 2336, :clang => "4.0", :clang_build => 421 },
|
|
|
|
"4.4.1" => { :llvm_build => 2336, :clang => "4.0", :clang_build => 421 },
|
|
|
|
"4.5" => { :llvm_build => 2336, :clang => "4.1", :clang_build => 421 },
|
2012-11-01 14:13:26 -05:00
|
|
|
"4.5.1" => { :llvm_build => 2336, :clang => "4.1", :clang_build => 421 },
|
|
|
|
"4.5.2" => { :llvm_build => 2336, :clang => "4.1", :clang_build => 421 }
|
2012-06-27 12:09:57 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
def compilers_standard?
|
2012-07-09 14:58:34 -05:00
|
|
|
xcode = Xcode.version
|
2012-06-27 12:09:57 -07:00
|
|
|
|
2012-10-15 18:16:18 -05:00
|
|
|
unless STANDARD_COMPILERS.keys.include? xcode
|
2012-08-24 23:47:51 -05:00
|
|
|
onoe <<-EOS.undent
|
|
|
|
Homebrew doesn't know what compiler versions ship with your version of
|
2012-10-06 13:19:05 -05:00
|
|
|
Xcode. Please `brew update` and if that doesn't help, file an issue with
|
|
|
|
the output of `brew --config`:
|
2012-08-24 23:47:51 -05:00
|
|
|
https://github.com/mxcl/homebrew/issues
|
|
|
|
|
|
|
|
Thanks!
|
|
|
|
EOS
|
2012-09-14 16:58:38 -05:00
|
|
|
return
|
2012-08-24 23:47:51 -05:00
|
|
|
end
|
|
|
|
|
2012-10-15 18:16:18 -05:00
|
|
|
STANDARD_COMPILERS[xcode].all? do |method, build|
|
|
|
|
MacOS.send(:"#{method}_version") == build
|
|
|
|
end
|
2012-06-27 12:09:57 -07:00
|
|
|
end
|
2012-06-28 12:49:54 -05:00
|
|
|
|
|
|
|
def app_with_bundle_id id
|
superenv: build-environments that just work
1. A minimal build environment, we don't set CFLAGS, CPPFLAGS, LDFLAGS, etc. the rationale being, the less that is set, the less variables we are introducing that can break builds.
2. A set of scripts that replace cc, ld, etc. and inject the -I, -L, etc. flags we need into the args passed to the build-tools.
Because we now have complete control over compiler instantiations we do a variety of clean-up tasks, like removing bad flags, enforcing universal builds and ensuring makefiles don't try to change the order of library and include paths from ones that work to ones that don't.
The previous ENV-system is still available when --env=std is specified.
superenv applies to Xcode >= 4.3 only currently.
2012-08-11 12:30:51 -04:00
|
|
|
path = mdfind(id).first
|
|
|
|
Pathname.new(path) unless path.nil? or path.empty?
|
2012-06-28 12:49:54 -05:00
|
|
|
end
|
|
|
|
|
superenv: build-environments that just work
1. A minimal build environment, we don't set CFLAGS, CPPFLAGS, LDFLAGS, etc. the rationale being, the less that is set, the less variables we are introducing that can break builds.
2. A set of scripts that replace cc, ld, etc. and inject the -I, -L, etc. flags we need into the args passed to the build-tools.
Because we now have complete control over compiler instantiations we do a variety of clean-up tasks, like removing bad flags, enforcing universal builds and ensuring makefiles don't try to change the order of library and include paths from ones that work to ones that don't.
The previous ENV-system is still available when --env=std is specified.
superenv applies to Xcode >= 4.3 only currently.
2012-08-11 12:30:51 -04:00
|
|
|
def mdfind id
|
|
|
|
`/usr/bin/mdfind "kMDItemCFBundleIdentifier == '#{id}'"`.split("\n")
|
2012-06-28 12:49:54 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def pkgutil_info id
|
2012-08-27 12:36:50 -04:00
|
|
|
`/usr/sbin/pkgutil --pkg-info "#{id}" 2>/dev/null`.strip
|
2012-06-28 12:49:54 -05:00
|
|
|
end
|
2012-08-25 13:08:24 -07:00
|
|
|
|
2012-12-04 12:06:02 +00:00
|
|
|
def bottles_supported? raise_if_failed=false
|
2012-08-25 13:08:24 -07:00
|
|
|
# We support bottles on all versions of OS X except 32-bit Snow Leopard.
|
2012-12-12 00:47:02 +00:00
|
|
|
if Hardware.is_32_bit? and MacOS.version == :snow_leopard
|
2012-12-04 12:06:02 +00:00
|
|
|
return false unless raise_if_failed
|
|
|
|
raise "Bottles are not supported on 32-bit Snow Leopard."
|
|
|
|
end
|
|
|
|
|
|
|
|
unless HOMEBREW_PREFIX.to_s == '/usr/local'
|
|
|
|
return false unless raise_if_failed
|
|
|
|
raise "Bottles are only supported with a /usr/local prefix."
|
|
|
|
end
|
|
|
|
|
|
|
|
unless HOMEBREW_CELLAR.to_s == '/usr/local/Cellar'
|
|
|
|
return false unless raise_if_failed
|
|
|
|
raise "Bottles are only supported with a /usr/local/Cellar cellar."
|
|
|
|
end
|
|
|
|
|
|
|
|
true
|
2012-08-25 13:08:24 -07:00
|
|
|
end
|
2012-06-27 12:09:57 -07:00
|
|
|
end
|
2012-07-09 14:58:34 -05:00
|
|
|
|
2012-07-25 15:04:46 -05:00
|
|
|
require 'macos/xcode'
|
|
|
|
require 'macos/xquartz'
|