Split Xcode and CLT methods into separate modules

Signed-off-by: Jack Nagel <jacknagel@gmail.com>
This commit is contained in:
Jack Nagel 2012-07-09 14:58:34 -05:00
parent 02f48dd7d8
commit 62482504a9
6 changed files with 222 additions and 190 deletions

View File

@ -32,17 +32,17 @@ module Homebrew extend self
else '/Applications/Xcode.app/Contents/Developer' else '/Applications/Xcode.app/Contents/Developer'
end end
guess = '(guessed)' unless MacOS.xcode_installed? guess = '(guessed)' unless MacOS::Xcode.installed?
prefix = if MacOS.xcode_installed? prefix = if MacOS::Xcode.installed?
"=> #{MacOS.xcode_prefix}" unless MacOS.xcode_prefix.to_s == default_prefix "=> #{MacOS::Xcode.prefix}" unless MacOS::Xcode.prefix.to_s == default_prefix
end end
[MacOS.xcode_version, guess, prefix].compact.join(' ') [MacOS::Xcode.version, guess, prefix].compact.join(' ')
end end
end end
def describe_clt def describe_clt
@describe_clt ||= if MacOS.clt_installed? then MacOS.clt_version else 'N/A' end @describe_clt ||= if MacOS::CLT.installed? then MacOS::CLT.version else 'N/A' end
end end
def head def head
@ -92,7 +92,7 @@ module Homebrew extend self
puts hardware puts hardware
puts "OS X: #{MACOS_FULL_VERSION}-#{kernel}" puts "OS X: #{MACOS_FULL_VERSION}-#{kernel}"
puts "Xcode: #{describe_xcode}" puts "Xcode: #{describe_xcode}"
puts "CLT: #{describe_clt}" if MacOS.xcode_version.to_f >= 4.3 puts "CLT: #{describe_clt}" if MacOS::Xcode.version.to_f >= 4.3
puts "/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby:\n #{RUBY_VERSION}-#{RUBY_PATCHLEVEL}" if RUBY_VERSION.to_f != 1.8 puts "/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby:\n #{RUBY_VERSION}-#{RUBY_PATCHLEVEL}" if RUBY_VERSION.to_f != 1.8
unless MacOS.compilers_standard? unless MacOS.compilers_standard?
@ -119,7 +119,7 @@ module Homebrew extend self
Xcode: #{describe_xcode} Xcode: #{describe_xcode}
EOS EOS
config_s << "CLT: #{describe_clt}\n" if MacOS.xcode_version.to_f >= 4.3 config_s << "CLT: #{describe_clt}\n" if MacOS::Xcode.version.to_f >= 4.3
config_s << <<-EOS.undent config_s << <<-EOS.undent
GCC-4.0: #{gcc_40 ? "build #{gcc_40}" : "N/A"} GCC-4.0: #{gcc_40 ? "build #{gcc_40}" : "N/A"}

View File

@ -207,10 +207,10 @@ def check_for_broken_symlinks
end end
def check_for_latest_xcode def check_for_latest_xcode
if not MacOS.xcode_installed? if not MacOS::Xcode.installed?
# no Xcode, now it depends on the OS X version... # no Xcode, now it depends on the OS X version...
if MacOS.version >= 10.7 then if MacOS.version >= 10.7 then
if not MacOS.clt_installed? if not MacOS::CLT.installed?
return <<-EOS.undent return <<-EOS.undent
No Xcode version found! No Xcode version found!
No compiler found in /usr/bin! No compiler found in /usr/bin!
@ -248,16 +248,16 @@ def check_for_latest_xcode
Not sure what version of Xcode is the latest for OS X #{MacOS.version}. Not sure what version of Xcode is the latest for OS X #{MacOS.version}.
EOS EOS
end end
if MacOS.xcode_installed? and MacOS.xcode_version < latest_xcode then <<-EOS.undent if MacOS::Xcode.installed? and MacOS::Xcode.version < latest_xcode then <<-EOS.undent
You have Xcode-#{MacOS.xcode_version}, which is outdated. You have Xcode-#{MacOS::Xcode.version}, which is outdated.
Please install Xcode #{latest_xcode}. Please install Xcode #{latest_xcode}.
EOS EOS
end end
end end
def check_cc def check_cc
unless MacOS.clt_installed? unless MacOS::CLT.installed?
if MacOS.xcode_version >= "4.3" if MacOS::Xcode.version >= "4.3"
return <<-EOS.undent return <<-EOS.undent
Experimental support for using Xcode without the "Command Line Tools". Experimental support for using Xcode without the "Command Line Tools".
EOS EOS
@ -389,7 +389,7 @@ def check_homebrew_prefix
end end
def check_xcode_prefix def check_xcode_prefix
prefix = MacOS.xcode_prefix prefix = MacOS::Xcode.prefix
return if prefix.nil? return if prefix.nil?
if prefix.to_s.match(' ') if prefix.to_s.match(' ')
<<-EOS.undent <<-EOS.undent
@ -401,9 +401,9 @@ end
def check_xcode_select_path def check_xcode_select_path
# with the advent of CLT-only support, we don't need xcode-select # with the advent of CLT-only support, we don't need xcode-select
return if MacOS.clt_installed? return if MacOS::CLT.installed?
unless File.file? "#{MacOS.xcode_folder}/usr/bin/xcodebuild" and not MacOS.xctools_fucked? unless File.file? "#{MacOS::Xcode.folder}/usr/bin/xcodebuild" and not MacOS::Xcode.xctools_fucked?
path = MacOS.app_with_bundle_id(MacOS::XCODE_4_BUNDLE_ID) || MacOS.app_with_bundle_id(MacOS::XCODE_3_BUNDLE_ID) path = MacOS.app_with_bundle_id(MacOS::Xcode::V4_BUNDLE_ID) || MacOS.app_with_bundle_id(MacOS::Xcode::V3_BUNDLE_ID)
path = '/Developer' if path.nil? or not path.directory? path = '/Developer' if path.nil? or not path.directory?
<<-EOS.undent <<-EOS.undent
Your Xcode is configured with an invalid path. Your Xcode is configured with an invalid path.
@ -677,7 +677,7 @@ def check_git_newline_settings
end end
def check_for_autoconf def check_for_autoconf
return if MacOS.xcode_version >= "4.3" return if MacOS::Xcode.version >= "4.3"
autoconf = which('autoconf') autoconf = which('autoconf')
safe_autoconfs = %w[/usr/bin/autoconf /Developer/usr/bin/autoconf] safe_autoconfs = %w[/usr/bin/autoconf /Developer/usr/bin/autoconf]

View File

@ -137,7 +137,7 @@ class FailsWithLLVM
# latest version we have tested against so we will switch to GCC and # latest version we have tested against so we will switch to GCC and
# bump this integer when Xcode 4.3 is released. TODO do that! # bump this integer when Xcode 4.3 is released. TODO do that!
if build.to_i >= 2336 if build.to_i >= 2336
if MacOS.xcode_version < "4.2" if MacOS::Xcode.version < "4.2"
opoo "Formula will not build with LLVM, using GCC" opoo "Formula will not build with LLVM, using GCC"
ENV.gcc ENV.gcc
else else
@ -156,7 +156,7 @@ class FailsWithLLVM
that we can update the formula accordingly. Thanks! that we can update the formula accordingly. Thanks!
EOS EOS
puts puts
if MacOS.xcode_version < "4.2" if MacOS::Xcode.version < "4.2"
puts "If it doesn't work you can: brew install --use-gcc" puts "If it doesn't work you can: brew install --use-gcc"
else else
puts "If it doesn't work you can try: brew install --use-clang" puts "If it doesn't work you can try: brew install --use-clang"
@ -164,3 +164,29 @@ class FailsWithLLVM
puts puts
end end
end end
module MacOS extend self
def xcode_folder
Xcode.folder
end
def xcode_prefix
Xcode.prefix
end
def xcode_installed?
Xcode.installed?
end
def xcode_version
Xcode.version
end
def clt_installed?
CLT.installed?
end
def clt_version?
CLT.version
end
end

View File

@ -10,7 +10,7 @@ module HomebrewEnvExtension
remove_cc_etc remove_cc_etc
# make any aclocal stuff installed in Homebrew available # make any aclocal stuff installed in Homebrew available
self['ACLOCAL_PATH'] = "#{HOMEBREW_PREFIX}/share/aclocal" if MacOS.xcode_version < "4.3" self['ACLOCAL_PATH'] = "#{HOMEBREW_PREFIX}/share/aclocal" if MacOS::Xcode.version < "4.3"
self['MAKEFLAGS'] = "-j#{self.make_jobs}" self['MAKEFLAGS'] = "-j#{self.make_jobs}"
@ -47,7 +47,7 @@ module HomebrewEnvExtension
macosxsdk MacOS.version macosxsdk MacOS.version
# For Xcode 4.3 (*without* the "Command Line Tools for Xcode") compiler and tools inside of Xcode: # For Xcode 4.3 (*without* the "Command Line Tools for Xcode") compiler and tools inside of Xcode:
if not MacOS.clt_installed? and MacOS.xcode_installed? and MacOS.xcode_version >= "4.3" if not MacOS::CLT.installed? and MacOS::Xcode.installed? and MacOS::Xcode.version >= "4.3"
# Some tools (clang, etc.) are in the xctoolchain dir of Xcode # Some tools (clang, etc.) are in the xctoolchain dir of Xcode
append 'PATH', "#{MacOS.xctoolchain_path}/usr/bin", ":" if MacOS.xctoolchain_path append 'PATH', "#{MacOS.xctoolchain_path}/usr/bin", ":" if MacOS.xctoolchain_path
# Others are now at /Applications/Xcode.app/Contents/Developer/usr/bin # Others are now at /Applications/Xcode.app/Contents/Developer/usr/bin
@ -231,7 +231,7 @@ Please take one of the following actions:
remove 'CPPFLAGS', "-isystem #{HOMEBREW_PREFIX}/include" remove 'CPPFLAGS', "-isystem #{HOMEBREW_PREFIX}/include"
remove 'LDFLAGS', "-L#{HOMEBREW_PREFIX}/lib" remove 'LDFLAGS', "-L#{HOMEBREW_PREFIX}/lib"
sdk = MacOS.sdk_path(v) sdk = MacOS.sdk_path(v)
unless sdk.nil? or MacOS.clt_installed? unless sdk.nil? or MacOS::CLT.installed?
self['SDKROOT'] = nil self['SDKROOT'] = nil
remove 'CPPFLAGS', "-isysroot #{sdk}" remove 'CPPFLAGS', "-isysroot #{sdk}"
remove 'CPPFLAGS', "-isystem #{sdk}/usr/include" remove 'CPPFLAGS', "-isystem #{sdk}/usr/include"
@ -261,7 +261,7 @@ Please take one of the following actions:
append 'CPPFLAGS', "-isystem #{HOMEBREW_PREFIX}/include" append 'CPPFLAGS', "-isystem #{HOMEBREW_PREFIX}/include"
prepend 'LDFLAGS', "-L#{HOMEBREW_PREFIX}/lib" prepend 'LDFLAGS', "-L#{HOMEBREW_PREFIX}/lib"
sdk = MacOS.sdk_path(v) sdk = MacOS.sdk_path(v)
unless sdk.nil? or MacOS.clt_installed? unless sdk.nil? or MacOS::CLT.installed?
# Extra setup to support Xcode 4.3+ without CLT. # Extra setup to support Xcode 4.3+ without CLT.
self['SDKROOT'] = sdk self['SDKROOT'] = sdk
# Teach the preprocessor and compiler (some don't respect CPPFLAGS) # Teach the preprocessor and compiler (some don't respect CPPFLAGS)
@ -286,16 +286,16 @@ Please take one of the following actions:
def minimal_optimization def minimal_optimization
self['CFLAGS'] = self['CXXFLAGS'] = "-Os #{SAFE_CFLAGS_FLAGS}" self['CFLAGS'] = self['CXXFLAGS'] = "-Os #{SAFE_CFLAGS_FLAGS}"
macosxsdk unless MacOS.clt_installed? macosxsdk unless MacOS::CLT.installed?
end end
def no_optimization def no_optimization
self['CFLAGS'] = self['CXXFLAGS'] = SAFE_CFLAGS_FLAGS self['CFLAGS'] = self['CXXFLAGS'] = SAFE_CFLAGS_FLAGS
macosxsdk unless MacOS.clt_installed? macosxsdk unless MacOS::CLT.installed?
end end
# Some configure scripts won't find libxml2 without help # Some configure scripts won't find libxml2 without help
def libxml2 def libxml2
if MacOS.clt_installed? if MacOS::CLT.installed?
append 'CPPFLAGS', '-I/usr/include/libxml2' append 'CPPFLAGS', '-I/usr/include/libxml2'
else else
# Use the includes form the sdk # Use the includes form the sdk
@ -319,7 +319,7 @@ Please take one of the following actions:
# We prefer XQuartz if it is installed. Otherwise, we look for Apple's # We prefer XQuartz if it is installed. Otherwise, we look for Apple's
# X11. For Xcode-only systems, the headers are found in the SDK. # X11. For Xcode-only systems, the headers are found in the SDK.
prefix = if MacOS.x11_prefix.to_s == '/opt/X11' or MacOS.clt_installed? prefix = if MacOS.x11_prefix.to_s == '/opt/X11' or MacOS::CLT.installed?
MacOS.x11_prefix MacOS.x11_prefix
else else
MacOS.sdk_path/'usr/X11' MacOS.sdk_path/'usr/X11'
@ -330,7 +330,7 @@ Please take one of the following actions:
append 'CMAKE_PREFIX_PATH', prefix, ':' append 'CMAKE_PREFIX_PATH', prefix, ':'
append 'CMAKE_INCLUDE_PATH', prefix/'include', ':' append 'CMAKE_INCLUDE_PATH', prefix/'include', ':'
unless MacOS.clt_installed? unless MacOS::CLT.installed?
append 'CPPFLAGS', "-I#{prefix}/include/freetype2" append 'CPPFLAGS', "-I#{prefix}/include/freetype2"
append 'CFLAGS', "-I#{prefix}/include" append 'CFLAGS', "-I#{prefix}/include"
end end

View File

@ -377,7 +377,7 @@ class FormulaInstaller
def check_m4 def check_m4
# Newer versions of Xcode don't come with autotools # Newer versions of Xcode don't come with autotools
return if MacOS.xcode_version.to_f >= 4.3 return if MacOS::Xcode.version.to_f >= 4.3
# If the user has added our path to dirlist, don't complain # If the user has added our path to dirlist, don't complain
return if File.open("/usr/share/aclocal/dirlist") do |dirlist| return if File.open("/usr/share/aclocal/dirlist") do |dirlist|

View File

@ -1,12 +1,6 @@
module MacOS extend self module MacOS extend self
MDITEM_BUNDLE_ID_KEY = "kMDItemCFBundleIdentifier" MDITEM_BUNDLE_ID_KEY = "kMDItemCFBundleIdentifier"
XCODE_4_BUNDLE_ID = "com.apple.dt.Xcode"
XCODE_3_BUNDLE_ID = "com.apple.Xcode"
XCODE_4_BUNDLE_PATH = Pathname.new("/Applications/Xcode.app")
XCODE_3_BUNDLE_PATH = Pathname.new("/Developer/Applications/Xcode.app")
CLT_STANDALONE_PKG_ID = "com.apple.pkg.DeveloperToolsCLILeo"
CLT_FROM_XCODE_PKG_ID = "com.apple.pkg.DeveloperToolsCLI"
APPLE_X11_BUNDLE_ID = "org.x.X11" APPLE_X11_BUNDLE_ID = "org.x.X11"
XQUARTZ_BUNDLE_ID = "org.macosforge.xquartz.X11" XQUARTZ_BUNDLE_ID = "org.macosforge.xquartz.X11"
@ -28,44 +22,6 @@ module MacOS extend self
end end
end end
# This is true ift he standard UNIX tools are present under /usr. For
# Xcode < 4.3, this is the standard location. Otherwise, it means that
# the user has installed the "Command Line Tools for Xcode" package.
def clt_installed?
dev_tools_path == Pathname.new("/usr/bin")
end
def clt_version
# Version string (a pretty damn long one) of the CLT package.
# Note, that different ways to install the CLTs lead to different
# version numbers.
@clt_version ||= begin
standalone = pkgutil_info(CLT_STANDALONE_PKG_ID)
from_xcode = pkgutil_info(CLT_FROM_XCODE_PKG_ID)
if not standalone.empty?
standalone =~ /version: (.*)$/
$1
elsif not from_xcode.empty?
from_xcode =~ /version: (.*)$/
$1
else
nil
end
end
end
# Locate the "current Xcode folder" via xcode-select. See:
# man xcode-select
def xcode_folder
@xcode_folder ||= `xcode-select -print-path 2>/dev/null`.strip
end
# Xcode 4.3 tools hang if "/" is set
def xctools_fucked?
xcode_folder == "/"
end
def locate tool def locate tool
# Don't call tools (cc, make, strip, etc.) directly! # Don't call tools (cc, make, strip, etc.) directly!
# Give the name of the binary you look for as a string to this method # Give the name of the binary you look for as a string to this method
@ -80,7 +36,7 @@ module MacOS extend self
else else
# Xcrun was provided first with Xcode 4.3 and allows us to proxy # Xcrun was provided first with Xcode 4.3 and allows us to proxy
# tool usage thus avoiding various bugs. # tool usage thus avoiding various bugs.
p = `/usr/bin/xcrun -find #{tool} 2>/dev/null`.chomp unless xctools_fucked? p = `/usr/bin/xcrun -find #{tool} 2>/dev/null`.chomp unless Xcode.xctools_fucked?
if !p.nil? and !p.empty? and File.executable? p if !p.nil? and !p.empty? and File.executable? p
path = Pathname.new p path = Pathname.new p
else else
@ -111,12 +67,12 @@ module MacOS extend self
@dev_tools_path ||= if File.exist? "/usr/bin/cc" and File.exist? "/usr/bin/make" @dev_tools_path ||= if File.exist? "/usr/bin/cc" and File.exist? "/usr/bin/make"
# probably a safe enough assumption (the unix way) # probably a safe enough assumption (the unix way)
Pathname.new "/usr/bin" Pathname.new "/usr/bin"
elsif not xctools_fucked? and system "/usr/bin/xcrun -find make 1>/dev/null 2>&1" elsif not Xcode.xctools_fucked? and system "/usr/bin/xcrun -find make 1>/dev/null 2>&1"
# Wherever "make" is there are the dev tools. # Wherever "make" is there are the dev tools.
Pathname.new(`/usr/bin/xcrun -find make`.chomp).dirname Pathname.new(`/usr/bin/xcrun -find make`.chomp).dirname
elsif File.exist? "#{xcode_prefix}/usr/bin/make" elsif File.exist? "#{Xcode.prefix}/usr/bin/make"
# cc stopped existing with Xcode 4.3, there are c89 and c99 options though # cc stopped existing with Xcode 4.3, there are c89 and c99 options though
Pathname.new "#{xcode_prefix}/usr/bin" Pathname.new "#{Xcode.prefix}/usr/bin"
else else
# Since we are pretty unrelenting in finding Xcode no matter where # Since we are pretty unrelenting in finding Xcode no matter where
# it hides, we can now throw in the towel. # it hides, we can now throw in the towel.
@ -128,7 +84,7 @@ module MacOS extend self
def xctoolchain_path def xctoolchain_path
# As of Xcode 4.3, some tools are located in the "xctoolchain" directory # As of Xcode 4.3, some tools are located in the "xctoolchain" directory
@xctoolchain_path ||= begin @xctoolchain_path ||= begin
path = Pathname.new("#{xcode_prefix}/Toolchains/XcodeDefault.xctoolchain") path = Pathname.new("#{Xcode.prefix}/Toolchains/XcodeDefault.xctoolchain")
# If only the CLT are installed, all tools will be under dev_tools_path, # 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. # this path won't exist, and xctoolchain_path will be nil.
path if path.exist? path if path.exist?
@ -137,14 +93,14 @@ module MacOS extend self
def sdk_path v=version def sdk_path v=version
@sdk_path ||= begin @sdk_path ||= begin
path = if not xctools_fucked? and File.executable? "#{xcode_folder}/usr/bin/make" path = if not Xcode.xctools_fucked? and File.executable? "#{Xcode.folder}/usr/bin/make"
`#{locate('xcodebuild')} -version -sdk macosx#{v} Path 2>/dev/null`.strip `#{locate('xcodebuild')} -version -sdk macosx#{v} Path 2>/dev/null`.strip
elsif File.directory? '/Developer/SDKs/MacOS#{v}.sdk' elsif File.directory? '/Developer/SDKs/MacOS#{v}.sdk'
# the old default (or wild wild west style) # the old default (or wild wild west style)
"/Developer/SDKs/MacOS#{v}.sdk" "/Developer/SDKs/MacOS#{v}.sdk"
elsif File.directory? "#{xcode_prefix}/Platforms/MacOSX.platform/Developer/SDKs/MacOSX#{v}.sdk" elsif File.directory? "#{Xcode.prefix}/Platforms/MacOSX.platform/Developer/SDKs/MacOSX#{v}.sdk"
# xcode_prefix is pretty smart, so lets look inside to find the sdk # Xcode.prefix is pretty smart, so lets look inside to find the sdk
"#{xcode_prefix}/Platforms/MacOSX.platform/Developer/SDKs/MacOSX#{v}.sdk" "#{Xcode.prefix}/Platforms/MacOSX.platform/Developer/SDKs/MacOSX#{v}.sdk"
end end
Pathname.new(path) unless path.nil? or path.empty? or not File.directory? path Pathname.new(path) unless path.nil? or path.empty? or not File.directory? path
@ -163,9 +119,9 @@ module MacOS extend self
when "clang" then :clang when "clang" then :clang
else else
# guess :( # guess :(
if xcode_version >= "4.3" if Xcode.version >= "4.3"
:clang :clang
elsif xcode_version >= "4.2" elsif Xcode.version >= "4.2"
:llvm :llvm
else else
:gcc :gcc
@ -173,108 +129,6 @@ module MacOS extend self
end end
end end
def xcode_prefix
@xcode_prefix ||= begin
path = Pathname.new xcode_folder
if path.absolute? and (path/'usr/bin/make').executable?
path
elsif File.executable? '/Developer/usr/bin/make'
# we do this to support cowboys who insist on installing
# only a subset of Xcode
Pathname.new '/Developer'
elsif (XCODE_4_BUNDLE_PATH/'Contents/Developer/usr/bin/make').executable?
# fallback for broken Xcode 4.3 installs
XCODE_4_BUNDLE_PATH/'Contents/Developer'
else
# Ask Spotlight where Xcode is. If the user didn't install the
# helper tools and installed Xcode in a non-conventional place, this
# is our only option. See: http://superuser.com/questions/390757
path = app_with_bundle_id(XCODE_4_BUNDLE_ID) || app_with_bundle_id(XCODE_3_BUNDLE_ID)
unless path.nil?
path += "Contents/Developer"
path if (path/'usr/bin/make').executable?
end
end
end
end
def xcode_installed?
# Telling us whether the Xcode.app is installed or not.
@xcode_installed ||= XCODE_4_BUNDLE_PATH.exist? ||
XCODE_3_BUNDLE_PATH.exist? ||
app_with_bundle_id(XCODE_4_BUNDLE_ID) ||
app_with_bundle_id(XCODE_3_BUNDLE_ID) ||
false
end
def xcode_version
# may return a version string
# that is guessed based on the compiler, so do not
# use it in order to check if Xcode is installed.
@xcode_version ||= begin
return "0" unless MACOS
# this shortcut makes xcode_version work for people who don't realise you
# need to install the CLI tools
xcode43build = "#{XCODE_4_BUNDLE_PATH}/Contents/Developer/usr/bin/xcodebuild"
if File.file? xcode43build
`#{xcode43build} -version 2>/dev/null` =~ /Xcode (\d(\.\d)*)/
return $1 if $1
end
# Xcode 4.3 xc* tools hang indefinately if xcode-select path is set thus
raise if xctools_fucked?
raise unless which "xcodebuild"
`xcodebuild -version 2>/dev/null` =~ /Xcode (\d(\.\d)*)/
raise if $1.nil? or not $?.success?
$1
rescue
# For people who's xcode-select is unset, or who have installed
# xcode-gcc-installer or whatever other combinations we can try and
# supprt. See https://github.com/mxcl/homebrew/wiki/Xcode
case llvm_build_version.to_i
when 1..2063 then "3.1.0"
when 2064..2065 then "3.1.4"
when 2366..2325
# we have no data for this range so we are guessing
"3.2.0"
when 2326
# also applies to "3.2.3"
"3.2.4"
when 2327..2333 then "3.2.5"
when 2335
# this build number applies to 3.2.6, 4.0 and 4.1
# https://github.com/mxcl/homebrew/wiki/Xcode
"4.0"
else
case (clang_version.to_f * 10).to_i
when 0
"dunno"
when 1..14
"3.2.2"
when 15
"3.2.4"
when 16
"3.2.5"
when 17..20
"4.0"
when 21
"4.1"
when 22..30
"4.2"
when 31
"4.3"
when 40
"4.4"
else
"4.4"
end
end
end
end
def gcc_40_build_version def gcc_40_build_version
@gcc_40_build_version ||= if locate("gcc-4.0") @gcc_40_build_version ||= if locate("gcc-4.0")
`#{locate("gcc-4.0")} --version` =~ /build (\d{4,})/ `#{locate("gcc-4.0")} --version` =~ /build (\d{4,})/
@ -402,7 +256,7 @@ module MacOS extend self
} }
def compilers_standard? def compilers_standard?
xcode = xcode_version xcode = Xcode.version
# Assume compilers are okay if Xcode version not in hash # Assume compilers are okay if Xcode version not in hash
return true unless StandardCompilers.keys.include? xcode return true unless StandardCompilers.keys.include? xcode
@ -413,8 +267,6 @@ module MacOS extend self
mdfind(MDITEM_BUNDLE_ID_KEY, id) mdfind(MDITEM_BUNDLE_ID_KEY, id)
end end
private
def mdfind attribute, id def mdfind attribute, id
path = `mdfind "#{attribute} == '#{id}'"`.strip path = `mdfind "#{attribute} == '#{id}'"`.strip
Pathname.new(path) unless path.empty? Pathname.new(path) unless path.empty?
@ -424,3 +276,157 @@ module MacOS extend self
`pkgutil --pkg-info #{id} 2>/dev/null`.strip `pkgutil --pkg-info #{id} 2>/dev/null`.strip
end end
end end
module MacOS::Xcode extend self
V4_BUNDLE_ID = "com.apple.dt.Xcode"
V3_BUNDLE_ID = "com.apple.Xcode"
V4_BUNDLE_PATH = Pathname.new("/Applications/Xcode.app")
V3_BUNDLE_PATH = Pathname.new("/Developer/Applications/Xcode.app")
# Locate the "current Xcode folder" via xcode-select. See:
# man xcode-select
def folder
@folder ||= `xcode-select -print-path 2>/dev/null`.strip
end
# Xcode 4.3 tools hang if "/" is set
def xctools_fucked?
folder == "/"
end
def prefix
@prefix ||= begin
path = Pathname.new folder
if path.absolute? and (path/'usr/bin/make').executable?
path
elsif File.executable? '/Developer/usr/bin/make'
# we do this to support cowboys who insist on installing
# only a subset of Xcode
Pathname.new '/Developer'
elsif (V4_BUNDLE_PATH/'Contents/Developer/usr/bin/make').executable?
# fallback for broken Xcode 4.3 installs
V4_BUNDLE_PATH/'Contents/Developer'
else
# Ask Spotlight where Xcode is. If the user didn't install the
# helper tools and installed Xcode in a non-conventional place, this
# is our only option. See: http://superuser.com/questions/390757
path = MacOS.app_with_bundle_id(V4_BUNDLE_ID) ||
MacOS.app_with_bundle_id(V3_BUNDLE_ID)
unless path.nil?
path += "Contents/Developer"
path if (path/'usr/bin/make').executable?
end
end
end
end
def installed?
# Telling us whether the Xcode.app is installed or not.
@installed ||= V4_BUNDLE_PATH.exist? ||
V3_BUNDLE_PATH.exist? ||
MacOS.app_with_bundle_id(V4_BUNDLE_ID) ||
MacOS.app_with_bundle_id(V3_BUNDLE_ID) ||
false
end
def version
# may return a version string
# that is guessed based on the compiler, so do not
# use it in order to check if Xcode is installed.
@version ||= begin
return "0" unless MACOS
# this shortcut makes version work for people who don't realise you
# need to install the CLI tools
xcode43build = "#{V4_BUNDLE_PATH}/Contents/Developer/usr/bin/xcodebuild"
if File.file? xcode43build
`#{xcode43build} -version 2>/dev/null` =~ /Xcode (\d(\.\d)*)/
return $1 if $1
end
# Xcode 4.3 xc* tools hang indefinately if xcode-select path is set thus
raise if xctools_fucked?
raise unless which "xcodebuild"
`xcodebuild -version 2>/dev/null` =~ /Xcode (\d(\.\d)*)/
raise if $1.nil? or not $?.success?
$1
rescue
# For people who's xcode-select is unset, or who have installed
# xcode-gcc-installer or whatever other combinations we can try and
# supprt. See https://github.com/mxcl/homebrew/wiki/Xcode
case llvm_build_version.to_i
when 1..2063 then "3.1.0"
when 2064..2065 then "3.1.4"
when 2366..2325
# we have no data for this range so we are guessing
"3.2.0"
when 2326
# also applies to "3.2.3"
"3.2.4"
when 2327..2333 then "3.2.5"
when 2335
# this build number applies to 3.2.6, 4.0 and 4.1
# https://github.com/mxcl/homebrew/wiki/Xcode
"4.0"
else
case (clang_version.to_f * 10).to_i
when 0
"dunno"
when 1..14
"3.2.2"
when 15
"3.2.4"
when 16
"3.2.5"
when 17..20
"4.0"
when 21
"4.1"
when 22..30
"4.2"
when 31
"4.3"
when 40
"4.4"
else
"4.4"
end
end
end
end
end
module MacOS::CLT extend self
STANDALONE_PKG_ID = "com.apple.pkg.DeveloperToolsCLILeo"
FROM_XCODE_PKG_ID = "com.apple.pkg.DeveloperToolsCLI"
# This is true ift he standard UNIX tools are present under /usr. For
# Xcode < 4.3, this is the standard location. Otherwise, it means that
# the user has installed the "Command Line Tools for Xcode" package.
def installed?
MacOS.dev_tools_path == Pathname.new("/usr/bin")
end
def version
# Version string (a pretty damn long one) of the CLT package.
# Note, that different ways to install the CLTs lead to different
# version numbers.
@version ||= begin
standalone = MacOS.pkgutil_info(CLT_STANDALONE_PKG_ID)
from_xcode = MacOS.pkgutil_info(CLT_FROM_XCODE_PKG_ID)
if not standalone.empty?
standalone =~ /version: (.*)$/
$1
elsif not from_xcode.empty?
from_xcode =~ /version: (.*)$/
$1
else
nil
end
end
end
end