diff options
Diffstat (limited to 'Library/Homebrew')
| -rw-r--r-- | Library/Homebrew/cleaner.rb | 4 | ||||
| -rw-r--r-- | Library/Homebrew/cmd/--config.rb | 21 | ||||
| -rw-r--r-- | Library/Homebrew/cmd/doctor.rb | 60 | ||||
| -rw-r--r-- | Library/Homebrew/extend/ENV.rb | 167 | ||||
| -rw-r--r-- | Library/Homebrew/global.rb | 5 | ||||
| -rw-r--r-- | Library/Homebrew/keg_fix_install_names.rb | 8 | ||||
| -rw-r--r-- | Library/Homebrew/utils.rb | 186 |
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 |
