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>
This commit is contained in:
samueljohn 2012-02-26 21:04:15 +01:00 committed by Adam Vandenberg
parent 3147dd134a
commit 725feb3db1
7 changed files with 336 additions and 113 deletions

View File

@ -37,7 +37,7 @@ class Cleaner
puts "strip #{path}" if ARGV.verbose?
path.chmod 0644 # so we can strip
unless path.stat.nlink > 1
system "/usr/bin/strip", *(args+path)
system "#{MacOS.locate('strip')}", *(args+path)
else
path = path.to_s.gsub ' ', '\\ '
@ -45,7 +45,7 @@ class Cleaner
# is this expected behaviour? patch does it too… still, this fixes it
tmp = `/usr/bin/mktemp -t homebrew_strip`.chomp
begin
`/usr/bin/strip #{args} -o #{tmp} #{path}`
`#{MacOS.locate('strip')} #{args} -o #{tmp} #{path}`
`/bin/cat #{tmp} > #{path}`
ensure
FileUtils.rm tmp

View File

@ -25,8 +25,21 @@ module Homebrew extend self
@clang_build ||= MacOS.clang_build_version
end
def xcode_version
@xcode_version || MacOS.xcode_version
def describe_xcode
@describe_xcode ||= begin
xcode = MacOS.xcode_version
if MacOS.xcode_installed?
xcode += " in '#{MacOS.xcode_prefix}'" unless MacOS.xcode_prefix.to_s == '/Applications/Xcode.app/Contents/Developer'
else
xcode += ' (guessed)' unless MacOS.xcode_installed?
end
xcode += ", CLT #{MacOS.clt_version}" if MacOS.clt_installed?
xcode
end
end
def describe_default_sdk
@describe_default_sdk ||= if MacOS.sdk_path.nil? then "N/A" else MacOS.sdk_path end
end
def sha
@ -90,7 +103,7 @@ module Homebrew extend self
puts "HOMEBREW_CELLAR: #{HOMEBREW_CELLAR}" if HOMEBREW_CELLAR.to_s != "#{HOMEBREW_PREFIX}/Cellar"
puts hardware
puts "MacOS: #{MACOS_FULL_VERSION}-#{kernel}"
puts "Xcode: #{xcode_version}"
puts "Xcode: #{describe_xcode}"
puts "/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby:\n #{RUBY_VERSION}-#{RUBY_PATCHLEVEL}" if RUBY_VERSION.to_f != 1.8
ponk = macports_or_fink_installed?
@ -108,7 +121,7 @@ module Homebrew extend self
#{hardware}
OS X: #{MACOS_FULL_VERSION}
Kernel Architecture: #{kernel}
Xcode: #{xcode_version}
Xcode: #{describe_xcode}
GCC-4.0: #{gcc_40 ? "build #{gcc_40}" : "N/A"}
GCC-4.2: #{gcc_42 ? "build #{gcc_42}" : "N/A"}
LLVM: #{llvm ? "build #{llvm}" : "N/A"}

View File

@ -217,16 +217,31 @@ def check_for_broken_symlinks
end
def check_for_latest_xcode
if MacOS.xcode_version.nil?
if MacOS.version >= 10.7 then return <<-EOS.undent
We couldn't detect any version of Xcode.
The latest Xcode can be obtained from the Mac App Store.
Alternatively, the Command Line Tools package can be obtained from
http://connect.apple.com
if not MacOS.xcode_installed?
# no Xcode, now it depends on the OS X version...
if MacOS.version >= 10.7 then
if not MacOS.clt_installed?
return <<-EOS.undent
No Xcode version found!
No compiler found in /usr/bin!
To fix this, either:
- Install the "Command Line Tools for Xcode" from http://connect.apple.com/
Homebrew does not require all of Xcode, you only need the CLI tools package!
(However, you need a (free) Apple Developer ID.)
- Install Xcode from the Mac App Store. (Normal Apple ID is sufficient, here)
EOS
else return <<-EOS.undent
else
return <<-EOS.undent
Experimental support for using the "Command Line Tools" without Xcode.
Some formulae need Xcode to be installed (for the Frameworks not in the CLT.)
EOS
end
else
# older Mac systems should just install their old Xcode. We don't advertize the CLT.
return <<-EOS.undent
We couldn't detect any version of Xcode.
The latest Xcode can be obtained from http://connect.apple.com
If you downloaded Xcode from the App Store, you may need to run the installer.
EOS
end
end
@ -236,21 +251,24 @@ def check_for_latest_xcode
when 10.6 then "3.2.6"
else "4.3"
end
if MacOS.xcode_version < latest_xcode then <<-EOS.undent
You have Xcode #{MacOS.xcode_version}, which is outdated.
if MacOS.xcode_installed? and MacOS.xcode_version < latest_xcode then <<-EOS.undent
You have Xcode-#{MacOS.xcode_version}, which is outdated.
Please install Xcode #{latest_xcode}.
EOS
end
end
def check_cc
unless File.exist? '/usr/bin/cc' then <<-EOS.undent
You have no /usr/bin/cc.
This means you probably can't build *anything*. You need to install the Command
Line Tools for Xcode. You can either download this from http://connect.apple.com
or install them from inside Xcode's Download preferences. Homebrew does not
require all of Xcode! You only need the Command Line Tools package!
unless MacOS.clt_installed?
if MacOS.xcode_version >= "4.3"
return <<-EOS.undent
Experimental support for using Xcode without the "Command Line Tools".
EOS
else
return <<-EOS.undent
No compiler found in /usr/bin!
EOS
end
end
end
@ -386,7 +404,9 @@ end
def check_xcode_select_path
path = `xcode-select -print-path 2>/dev/null`.chomp
unless File.directory? path and File.file? "#{path}/usr/bin/xcodebuild"
# with the advent of CLT-only support, we don't need xcode-select
return if MacOS.clt_installed?
unless File.directory? path and File.file? "#{path}/usr/bin/xcodebuild" and not MacOS.xctools_fucked?
# won't guess at the path they should use because it's too hard to get right
# We specify /Applications/Xcode.app/Contents/Developer even though
# /Applications/Xcode.app should work because people don't install the new CLI

View File

@ -32,8 +32,8 @@ module HomebrewEnvExtension
unless self['CC']
@compiler = MacOS.default_compiler
self.send @compiler
self['CC'] = '/usr/bin/cc'
self['CXX'] = '/usr/bin/c++'
self['CC'] = MacOS.locate("cc")
self['CXX'] = MacOS.locate("c++")
self['OBJC'] = self['CC']
end
@ -42,6 +42,17 @@ module HomebrewEnvExtension
# build more successfully because we are changing CC and many build systems
# don't react properly to that.
self['LD'] = self['CC']
# Add lib and include etc. from the current macosxsdk to compiler flags:
macosxsdk MacOS.version
# 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"
# Some tools (clang, etc.) are in the xctoolchain dir of Xcode
append 'PATH', "#{MacOS.xctoolchain_path}/usr/bin", ":" if MacOS.xctoolchain_path
# Others are now at /Applications/Xcode.app/Contents/Developer/usr/bin
append 'PATH', "#{MacOS.dev_tools_path}", ":"
end
end
def deparallelize
@ -86,7 +97,7 @@ module HomebrewEnvExtension
end
def gcc_4_0_1
# we don't use xcrun because gcc 4.0 has not been provided since Xcode 4
# we don't use locate because gcc 4.0 has not been provided since Xcode 4
self['CC'] = "#{MacOS.dev_tools_path}/gcc-4.0"
self['LD'] = self['CC']
self['CXX'] = "#{MacOS.dev_tools_path}/g++-4.0"
@ -97,33 +108,6 @@ module HomebrewEnvExtension
end
alias_method :gcc_4_0, :gcc_4_0_1
def xcrun tool
if File.executable? "/usr/bin/#{tool}"
"/usr/bin/#{tool}"
elsif not MacOS.xctools_fucked? and system "/usr/bin/xcrun -find #{tool} 1>/dev/null 2>&1"
# xcrun was provided first with Xcode 4.3 and allows us to proxy
# tool usage thus avoiding various bugs
"/usr/bin/xcrun #{tool}"
else
# otherwise lets try and figure it out ourselves
fn = "#{MacOS.dev_tools_path}/#{tool}"
if File.executable? fn
fn
else
# This is for the use-case where xcode-select is not set up with
# Xcode 4.3. The tools in Xcode 4.3 are split over two locations,
# usually xcrun would figure that out for us, but it won't work if
# xcode-select is not configured properly.
fn = "#{MacOS.xcode_prefix}/Toolchains/XcodeDefault.xctoolchain/usr/bin/#{tool}"
if File.executable? fn
fn
else
nil
end
end
end
end
# if your formula doesn't like CC having spaces use this
def expand_xcrun
self['CC'] =~ %r{/usr/bin/xcrun (.*)}
@ -139,9 +123,9 @@ module HomebrewEnvExtension
# However they still provide a gcc symlink to llvm
# But we don't want LLVM of course.
self['CC'] = xcrun "gcc-4.2"
self['CC'] = MacOS.locate "gcc-4.2"
self['LD'] = self['CC']
self['CXX'] = xcrun "g++-4.2"
self['CXX'] = MacOS.locate "g++-4.2"
self['OBJC'] = self['CC']
unless self['CC']
@ -149,7 +133,7 @@ module HomebrewEnvExtension
self['LD'] = self['CC']
self['CXX'] = "#{HOMEBREW_PREFIX}/bin/g++-4.2"
self['OBJC'] = self['CC']
raise "GCC could not be found" if not File.exist? self['CC']
raise "GCC could not be found" unless File.exist? self['CC']
end
if not self['CC'] =~ %r{^/usr/bin/xcrun }
@ -163,18 +147,18 @@ module HomebrewEnvExtension
alias_method :gcc_4_2, :gcc
def llvm
self['CC'] = xcrun "llvm-gcc"
self['CC'] = MacOS.locate "llvm-gcc"
self['LD'] = self['CC']
self['CXX'] = xcrun "llvm-g++"
self['CXX'] = MacOS.locate "llvm-g++"
self['OBJC'] = self['CC']
set_cpu_cflags 'core2 -msse4', :penryn => 'core2 -msse4.1', :core2 => 'core2', :core => 'prescott'
@compiler = :llvm
end
def clang
self['CC'] = xcrun "clang"
self['CC'] = MacOS.locate "clang"
self['LD'] = self['CC']
self['CXX'] = xcrun "clang++"
self['CXX'] = MacOS.locate "clang++"
self['OBJC'] = self['CC']
replace_in_cflags(/-Xarch_i386 (-march=\S*)/, '\1')
# Clang mistakenly enables AES-NI on plain Nehalem
@ -238,39 +222,114 @@ Please take one of the following actions:
end
end
def osx_10_4
self['MACOSX_DEPLOYMENT_TARGET']="10.4"
def remove_macosxsdk v=MacOS.version
# Clear all lib and include dirs from CFLAGS, CPPFLAGS, LDFLAGS that were
# previously added by macosxsdk
v = v.to_s
remove_from_cflags(/ ?-mmacosx-version-min=10\.\d/)
append_to_cflags('-mmacosx-version-min=10.4')
self['MACOSX_DEPLOYMENT_TARGET'] = nil
remove 'CPPFLAGS', "-isystem #{HOMEBREW_PREFIX}/include"
remove 'LDFLAGS', "-L#{HOMEBREW_PREFIX}/lib"
sdk = MacOS.sdk_path(v)
unless sdk.nil?
self['SDKROOT'] = nil
remove 'CPPFLAGS', "-isysroot #{sdk}"
remove 'CPPFLAGS', "-isystem #{sdk}/usr/include"
remove 'CPPFLAGS', "-I#{sdk}/usr/include"
remove_from_cflags "-isystem #{sdk}/usr/include"
remove_from_cflags "-isysroot #{sdk}"
remove_from_cflags "-L#{sdk}/usr/lib"
remove_from_cflags "-I#{sdk}/usr/include"
remove 'LDFLAGS', "-L#{sdk}/usr/lib"
remove 'LDFLAGS', "-I#{sdk}/usr/include"
if HOMEBREW_PREFIX.to_s == '/usr/local'
self['CMAKE_PREFIX_PATH'] = nil
else
# It was set in setup_build_environment, so we have to restore it here.
self['CMAKE_PREFIX_PATH'] = "#{HOMEBREW_PREFIX}"
end
remove 'CMAKE_FRAMEWORK_PATH', "#{sdk}/System/Library/Frameworks"
end
end
def macosxsdk v=MacOS.version
# Sets all needed lib and include dirs to CFLAGS, CPPFLAGS, LDFLAGS.
remove_macosxsdk
# Allow cool style of ENV.macosxsdk 10.8 here (no "" :)
v = v.to_s
append_to_cflags("-mmacosx-version-min=#{v}")
self['MACOSX_DEPLOYMENT_TARGET'] = v
append 'CPPFLAGS', "-isystem #{HOMEBREW_PREFIX}/include"
prepend 'LDFLAGS', "-L#{HOMEBREW_PREFIX}/lib"
sdk = MacOS.sdk_path(v)
unless sdk.nil?
# Extra setup to support Xcode 4.3+ without CLT.
self['SDKROOT'] = sdk
# Teach the preprocessor and compiler (some don't respect CPPFLAGS)
# where system includes are:
append 'CPPFLAGS', "-isysroot #{sdk}"
append_to_cflags "-isysroot #{sdk}"
append 'CPPFLAGS', "-isystem #{sdk}/usr/include"
# Suggested by mxcl (https://github.com/mxcl/homebrew/pull/10510#issuecomment-4187996):
append_to_cflags "-isystem #{sdk}/usr/include"
# Some software needs this (e.g. python shows error: /usr/include/zlib.h: No such file or directory)
append 'CPPFLAGS', "-I#{sdk}/usr/include"
# Needed because CC passes this to the linker and some projects
# forget to use the LDFLAGS explicitly:
append_to_cflags "-L#{sdk}/usr/lib"
# And finally the "normal" things one expects for the CFLAGS and LDFLAGS:
append_to_cflags "-I#{sdk}/usr/include"
prepend 'LDFLAGS', "-L#{sdk}/usr/lib"
# Believe it or not, sometime only the LDFLAGS are used :/
prepend 'LDFLAGS', "-I#{sdk}/usr/include"
# Needed to build cmake itself and perhaps some cmake projects:
append 'CMAKE_PREFIX_PATH', "#{sdk}/usr", ':'
append 'CMAKE_FRAMEWORK_PATH', "#{sdk}/System/Library/Frameworks", ':'
end
def osx_10_5
self['MACOSX_DEPLOYMENT_TARGET']="10.5"
remove_from_cflags(/ ?-mmacosx-version-min=10\.\d/)
append_to_cflags('-mmacosx-version-min=10.5')
end
def minimal_optimization
self['CFLAGS'] = self['CXXFLAGS'] = "-Os #{SAFE_CFLAGS_FLAGS}"
macosxsdk unless MacOS.clt_installed?
end
def no_optimization
self['CFLAGS'] = self['CXXFLAGS'] = SAFE_CFLAGS_FLAGS
macosxsdk unless MacOS.clt_installed?
end
# Some configure scripts won't find libxml2 without help
def libxml2
if MacOS.clt_installed?
append 'CPPFLAGS', '-I/usr/include/libxml2'
else
# Use the includes form the sdk
append 'CPPFLAGS', "-I#{MacOS.sdk_path}/usr/include/libxml2"
end
end
def x11
opoo "You do not have X11 installed, this formula may not build." if not MacOS.x11_installed?
opoo "You do not have X11 installed, this formula may not build." unless MacOS.x11_installed?
if MacOS.clt_installed?
# For Xcode < 4.3 clt_installed? is true. So here is the old style /usr/X11:
# There are some config scripts (e.g. freetype) here that should go in the path
prepend 'PATH', '/usr/X11/bin', ':'
# (note we don't use MacOS.sdk_path here, because there is no ./usr/bin in there)
prepend 'PATH', "/usr/X11/bin", ':'
# CPPFLAGS are the C-PreProcessor flags, *not* C++!
append 'CPPFLAGS', '-I/usr/X11/include'
append 'LDFLAGS', '-L/usr/X11/lib'
# CMake ignores the variables above
append 'CMAKE_PREFIX_PATH', '/usr/X11', ':'
append 'CPPFLAGS', "-I/usr/X11/include"
# Even without Xcode or the CLTs, /usr/X11/lib is there
append 'LDFLAGS', "-L/usr/X11/lib"
else
# For Xcode 4.3 and above *without* CLT, we find the includes in the SDK:
# Only the SDK has got include files. (they are no longer in /usr/X11/include !)
# Todo: do we need to add cairo, fontconfig, GL, libpng15, pixman-1, VG, xcb, too?
append 'CFLAGS', "-I#{MacOS.sdk_path}/usr/X11/include"
append 'CPPFLAGS', "-I#{MacOS.sdk_path}/usr/X11/include"
append 'CPPFLAGS', "-I#{MacOS.sdk_path}/usr/X11/include/freetype2"
# The libs are still in /usr/X11/lib but to be consistent with the includes, we use the SDK, right?
append 'LDFLAGS', "-L#{MacOS.sdk_path}/usr/X11/lib"
append 'CMAKE_INCLUDE_PATH', "#{MacOS.sdk_path}/usr/X11/include", ':'
end
end
alias_method :libpng, :x11

View File

@ -91,3 +91,8 @@ unless ARGV.include? "--no-compat" or ENV['HOMEBREW_NO_COMPAT']
$:.unshift(File.expand_path("#{__FILE__}/../compat"))
require 'compatibility'
end
# For Xcode-only installs, we add the path of the included unix tools (like git)
if MacOS.dev_tools_path.to_s != '/usr/bin'
ENV['PATH'] = ENV['PATH'].to_s + ':' + MacOS.dev_tools_path
end

View File

@ -5,7 +5,7 @@ class Keg
mach_o_files.each do |file|
bad_install_names_for file do |id, bad_names|
file.ensure_writable do
system "install_name_tool", "-id", id, file if file.dylib?
system MacOS.locate("install_name_tool"), "-id", id, file if file.dylib?
bad_names.each do |bad_name|
new_name = bad_name
@ -14,7 +14,7 @@ class Keg
# 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 "install_name_tool", "-change", bad_name, "@loader_path/#{new_name}", file
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.
@ -23,7 +23,7 @@ class Keg
end
if abs_name and abs_name.exist?
system "install_name_tool", "-change", bad_name, abs_name, file
system MacOS.locate("install_name_tool"), "-change", bad_name, abs_name, file
else
opoo "Could not fix install names for #{file}"
end
@ -40,7 +40,7 @@ class Keg
def bad_install_names_for file
ENV['HOMEBREW_MACH_O_FILE'] = file.to_s # solves all shell escaping problems
install_names = `otool -L "$HOMEBREW_MACH_O_FILE"`.split "\n"
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 }

View File

@ -254,41 +254,139 @@ module MacOS extend self
end
end
def clt_installed?
# If the command line tools are installed, most unix standard
# tools, libs and headers are in /usr.
# Returns true, also for older Xcode/OSX versions that had everything in /usr
# Beginning with Xcode 4.3, the dev tools are no longer installed
# in /usr and SDKs no longer in /Developer by default.
# But Apple provides an optional "Command Line Tools for Xcode" package.
not clt_version.empty? or 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
# CLT installed via stand-alone website download
clt_pkginfo_stand_alone = `pkgutil --pkg-info com.apple.pkg.DeveloperToolsCLILeo 2>/dev/null`.strip
# CLT installed via preferences from within Xcode
clt_pkginfo_from_xcode = `pkgutil --pkg-info com.apple.pkg.DeveloperToolsCLI 2>/dev/null`.strip
if not clt_pkginfo_stand_alone.empty?
clt_pkginfo_stand_alone =~ /version: (.*)$/
$1
elsif not clt_pkginfo_from_xcode.empty?
clt_pkginfo_from_xcode =~ /version: (.*)$/
$1
else
# We return "" instead of nil because we want clt_installed? to be true on older Macs.
# So clt_version.empty? does not mean there are no unix tools in /usr, it just means
# that the "Command Line Tools for Xcode" package is not installed
"" # No CLT or recipe available to pkgutil.
end
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.
tool = tool.to_s
@locate_cache ||= {}
return @locate_cache[tool] if @locate_cache.has_key? tool
if File.executable? "/usr/bin/#{tool}"
path = Pathname.new "/usr/bin/#{tool}"
elsif not MacOS.xctools_fucked? and system "/usr/bin/xcrun -find #{tool} 1>/dev/null 2>&1"
# xcrun was provided first with Xcode 4.3 and allows us to proxy
# tool usage thus avoiding various bugs
p = `/usr/bin/xcrun -find #{tool}`.chomp
if File.executable? p
path = Pathname.new p
else
path = nil
end
else
# otherwise lets try and figure it out ourselves
p = "#{MacOS.dev_tools_path}/#{tool}"
if File.executable? p
path = Pathname.new p
else
# This is for the use-case where xcode-select is not set up with
# Xcode 4.3+. The tools in Xcode 4.3+ are split over two locations,
# usually xcrun would figure that out for us, but it won't work if
# xcode-select is not configured properly (i.e. xctools_fucked?).
p = "#{MacOS.xcode_prefix}/Toolchains/XcodeDefault.xctoolchain/usr/bin/#{tool}"
if File.executable? p
path Pathname.new p
else
path = nil
end
end
end
@locate_cache[tool] = path
return path
end
def dev_tools_path
@dev_tools_path ||= if File.file? "/usr/bin/cc" and File.file? "/usr/bin/make"
# probably a safe enough assumption
"/usr/bin"
elsif File.file? "#{xcode_prefix}/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)
Pathname.new "/usr/bin"
elsif not xctools_fucked?
# The new way of finding stuff via locate:
Pathname.new(locate 'make').dirname
elsif File.exist? "#{xcode_prefix}/usr/bin/make"
# cc stopped existing with Xcode 4.3, there are c89 and c99 options though
"#{xcode_prefix}/usr/bin"
Pathname.new "#{xcode_prefix}/usr/bin"
else
# yes this seems dumb, but we can't throw because the existance of
# dev tools is not mandatory for installing formula. Eventually we
# should make formula specify if they need dev tools or not.
"/usr/bin"
Pathname.new "/usr/bin"
end
end
def xctoolchain_path
# Beginning with Xcode 4.3, clang and some other tools are located in a xctoolchain dir.
@xctoolchain_path ||= begin
path = Pathname.new("#{MacOS.xcode_prefix}/Toolchains/XcodeDefault.xctoolchain")
if path.exist?
path
else
# ok, there are no Toolchains in xcode_prefix
# and that's ok as long as everything is in dev_tools_path="/usr/bin" (i.e. clt_installed?)
nil
end
end
end
def sdk_path(v=MacOS.version)
# The path of the MacOSX SDK.
if not MacOS.xctools_fucked?
path = `#{locate('xcodebuild')} -version -sdk macosx#{v} Path 2>/dev/null`.chomp
elsif File.directory? '/Developer/SDKs/MacOS#{v}.sdk'
# the old default (or wild wild west style)
path = "/Developer/SDKs/MacOS#{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
path = "#{xcode_prefix}/Platforms/MacOSX.platform/Developer/SDKs/MacOSX#{v}.sdk"
end
if path.nil? or path.empty? or not File.directory? path
nil
else
Pathname.new path
end
end
def xctools_fucked?
# Xcode 4.3 tools hang if "/" is set
`/usr/bin/xcode-select -print-path 2>/dev/null`.chomp == "/"
@xctools_fucked ||= `/usr/bin/xcode-select -print-path 2>/dev/null`.chomp == "/"
end
def default_cc
cc = unless xctools_fucked?
out = `/usr/bin/xcrun -find cc 2> /dev/null`.chomp
out if $?.success?
end
cc = "#{dev_tools_path}/cc" if cc.nil? or cc.empty?
unless File.executable? cc
# If xcode-select isn't setup then xcrun fails and on Xcode 4.3
# the cc binary is not at #{dev_tools_path}. This return is almost
# worthless however since in this particular setup nothing much builds
# but I wrote the code now and maybe we'll fix the other issues later.
cc = "#{xcode_prefix}/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc"
end
cc = locate 'cc'
Pathname.new(cc).realpath.basename.to_s rescue nil
end
@ -341,18 +439,45 @@ module MacOS extend self
# 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 = `mdfind "kMDItemDisplayName==Xcode&&kMDItemKind==Application"`
path = `mdfind "kMDItemCFBundleIdentifier == 'com.apple.dt.Xcode'"`.strip
if path.empty?
# Xcode 3 had a different identifier
path = `mdfind "kMDItemCFBundleIdentifier == 'com.apple.Xcode'"`.strip
end
path = "#{path}/Contents/Developer"
if path.empty? or not File.directory? path
nil
else
path
Pathname.new path
end
end
end
end
def xcode_installed?
# Telling us whether the Xcode.app is installed or not.
@xcode_installed ||= begin
if File.directory? '/Applications/Xcode.app'
true
elsif File.directory? '/Developer/Applications/Xcode.app' # old style
true
elsif not `mdfind "kMDItemCFBundleIdentifier == 'com.apple.dt.Xcode'"`.strip.empty?
# Xcode 4
true
elsif not `mdfind "kMDItemCFBundleIdentifier == 'com.apple.Xcode'"`.strip.empty?
# Xcode 3
true
else
false
end
end
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
@ -417,27 +542,28 @@ module MacOS extend self
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 File.exist? "#{dev_tools_path}/llvm-gcc"
`#{dev_tools_path}/llvm-gcc --version` =~ /LLVM build (\d{4,})/
@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 File.exist? "#{dev_tools_path}/clang"
`#{dev_tools_path}/clang --version` =~ /clang version (\d\.\d)/
@clang_version ||= if locate("clang")
`#{locate("clang")} --version` =~ /clang version (\d\.\d)/
$1
end
end
def clang_build_version
@clang_build_version ||= if File.exist? "#{dev_tools_path}/clang"
`#{dev_tools_path}/clang --version` =~ %r[tags/Apple/clang-(\d{2,})]
@clang_build_version ||= if locate("clang")
`#{locate("clang")} --version` =~ %r[tags/Apple/clang-(\d{2,})]
$1.to_i
end
end
def x11_installed?
# Even if only Xcode (without CLT) is installed, this dylib is there.
Pathname.new('/usr/X11/lib/libpng.dylib').exist?
end