aboutsummaryrefslogtreecommitdiffstats
path: root/Library/Homebrew
diff options
context:
space:
mode:
Diffstat (limited to 'Library/Homebrew')
-rw-r--r--Library/Homebrew/cleaner.rb4
-rw-r--r--Library/Homebrew/cmd/--config.rb21
-rw-r--r--Library/Homebrew/cmd/doctor.rb60
-rw-r--r--Library/Homebrew/extend/ENV.rb167
-rw-r--r--Library/Homebrew/global.rb5
-rw-r--r--Library/Homebrew/keg_fix_install_names.rb8
-rw-r--r--Library/Homebrew/utils.rb186
7 files changed, 337 insertions, 114 deletions
diff --git a/Library/Homebrew/cleaner.rb b/Library/Homebrew/cleaner.rb
index 3950cd846..b7e30c06f 100644
--- a/Library/Homebrew/cleaner.rb
+++ b/Library/Homebrew/cleaner.rb
@@ -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
diff --git a/Library/Homebrew/cmd/--config.rb b/Library/Homebrew/cmd/--config.rb
index 5fb455d23..a4431eb5e 100644
--- a/Library/Homebrew/cmd/--config.rb
+++ b/Library/Homebrew/cmd/--config.rb
@@ -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"}
diff --git a/Library/Homebrew/cmd/doctor.rb b/Library/Homebrew/cmd/doctor.rb
index 8aa229b28..a19a2d17e 100644
--- a/Library/Homebrew/cmd/doctor.rb
+++ b/Library/Homebrew/cmd/doctor.rb
@@ -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
- EOS
- else return <<-EOS.undent
- We couldn't detect any version of Xcode.
- The latest Xcode 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
+ 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.
+ 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!
- EOS
+ 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
diff --git a/Library/Homebrew/extend/ENV.rb b/Library/Homebrew/extend/ENV.rb
index 898da6237..ca0a51e99 100644
--- a/Library/Homebrew/extend/ENV.rb
+++ b/Library/Homebrew/extend/ENV.rb
@@ -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 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')
+
+ 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
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
- append 'CPPFLAGS', '-I/usr/include/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?
-
- # There are some config scripts (e.g. freetype) here that should go in the path
- 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', ':'
+ 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
+ # (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"
+ # 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
diff --git a/Library/Homebrew/global.rb b/Library/Homebrew/global.rb
index 92560859c..34ff785eb 100644
--- a/Library/Homebrew/global.rb
+++ b/Library/Homebrew/global.rb
@@ -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
diff --git a/Library/Homebrew/keg_fix_install_names.rb b/Library/Homebrew/keg_fix_install_names.rb
index e2582c688..82e43ac15 100644
--- a/Library/Homebrew/keg_fix_install_names.rb
+++ b/Library/Homebrew/keg_fix_install_names.rb
@@ -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 }
diff --git a/Library/Homebrew/utils.rb b/Library/Homebrew/utils.rb
index 1ee4232ec..21ce26940 100644
--- a/Library/Homebrew/utils.rb
+++ b/Library/Homebrew/utils.rb
@@ -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 xctools_fucked?
- # Xcode 4.3 tools hang if "/" is set
- `/usr/bin/xcode-select -print-path 2>/dev/null`.chomp == "/"
+ 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 default_cc
- cc = unless xctools_fucked?
- out = `/usr/bin/xcrun -find cc 2> /dev/null`.chomp
- out if $?.success?
+ 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
- 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"
+ 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
+ @xctools_fucked ||= `/usr/bin/xcode-select -print-path 2>/dev/null`.chomp == "/"
+ end
+
+ def default_cc
+ 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_version
+ 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