| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  | module OS | 
					
						
							|  |  |  |   module Mac | 
					
						
							|  |  |  |     module Xcode | 
					
						
							|  |  |  |       extend self | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       V4_BUNDLE_ID = "com.apple.dt.Xcode" | 
					
						
							|  |  |  |       V3_BUNDLE_ID = "com.apple.Xcode" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def latest_version | 
					
						
							|  |  |  |         case MacOS.version | 
					
						
							| 
									
										
										
										
											2014-08-09 22:00:06 -05:00
										 |  |  |         when "10.4"  then "2.5" | 
					
						
							|  |  |  |         when "10.5"  then "3.1.4" | 
					
						
							|  |  |  |         when "10.6"  then "3.2.6" | 
					
						
							|  |  |  |         when "10.7"  then "4.6.3" | 
					
						
							|  |  |  |         when "10.8"  then "5.1.1" | 
					
						
							| 
									
										
										
										
											2015-03-10 00:08:43 +00:00
										 |  |  |         when "10.9"  then "6.2" | 
					
						
							| 
									
										
										
										
											2016-02-07 19:30:51 +00:00
										 |  |  |         when "10.10" then "7.2.1" | 
					
						
							|  |  |  |         when "10.11" then "7.2.1" | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |         else | 
					
						
							|  |  |  |           # Default to newest known version of Xcode for unreleased OSX versions. | 
					
						
							| 
									
										
										
										
											2015-10-23 00:07:12 +02:00
										 |  |  |           if OS::Mac.prerelease? | 
					
						
							| 
									
										
										
										
											2016-02-07 19:30:51 +00:00
										 |  |  |             "7.2.1" | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |           else | 
					
						
							| 
									
										
										
										
											2015-06-16 20:02:10 -04:00
										 |  |  |             raise "OS X '#{MacOS.version}' is invalid" | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2013-06-04 13:58:08 +01:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2012-08-17 17:18:17 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |       def outdated? | 
					
						
							|  |  |  |         version < latest_version | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2013-05-22 22:26:09 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |       def without_clt? | 
					
						
							|  |  |  |         installed? && version >= "4.3" && !MacOS::CLT.installed? | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2013-08-09 20:47:28 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-16 22:51:39 -07:00
										 |  |  |       # Returns a Pathname object corresponding to Xcode.app's Developer | 
					
						
							|  |  |  |       # directory or nil if Xcode.app is not installed | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |       def prefix | 
					
						
							| 
									
										
										
										
											2014-05-02 16:48:59 -05:00
										 |  |  |         @prefix ||= | 
					
						
							|  |  |  |           begin | 
					
						
							|  |  |  |             dir = MacOS.active_developer_dir | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if dir.empty? || dir == CLT::MAVERICKS_PKG_PATH || !File.directory?(dir) | 
					
						
							|  |  |  |               path = bundle_path | 
					
						
							|  |  |  |               path.join("Contents", "Developer") if path | 
					
						
							|  |  |  |             else | 
					
						
							| 
									
										
										
										
											2016-03-15 23:40:59 -07:00
										 |  |  |               # Use cleanpath to avoid pathological trailing slash | 
					
						
							|  |  |  |               Pathname.new(dir).cleanpath | 
					
						
							| 
									
										
										
										
											2014-05-02 16:48:59 -05:00
										 |  |  |             end | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |           end | 
					
						
							| 
									
										
										
										
											2012-07-09 15:18:02 -05:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-01 18:36:46 -05:00
										 |  |  |       def toolchain_path | 
					
						
							| 
									
										
										
										
											2016-03-16 22:09:41 -07:00
										 |  |  |         Pathname.new("#{prefix}/Toolchains/XcodeDefault.xctoolchain") if installed? && version >= "4.3" | 
					
						
							| 
									
										
										
										
											2014-05-01 18:36:46 -05:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |       # Ask Spotlight where Xcode is. If the user didn't install the | 
					
						
							|  |  |  |       # helper tools and installed Xcode in a non-conventional place, this | 
					
						
							| 
									
										
										
										
											2015-01-04 05:02:27 +01:00
										 |  |  |       # is our only option. See: https://superuser.com/questions/390757 | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |       def bundle_path | 
					
						
							| 
									
										
										
										
											2014-04-01 20:47:26 -05:00
										 |  |  |         MacOS.app_with_bundle_id(V4_BUNDLE_ID, V3_BUNDLE_ID) | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2013-07-21 16:41:51 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |       def installed? | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |         !prefix.nil? | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2012-07-09 15:18:02 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |       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 ||= uncached_version | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2012-07-09 15:18:02 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |       def uncached_version | 
					
						
							|  |  |  |         # This is a separate function as you can't cache the value out of a block | 
					
						
							|  |  |  |         # if return is used in the middle, which we do many times in here. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return "0" unless OS.mac? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-26 16:49:16 -04:00
										 |  |  |         return nil if !MacOS::Xcode.installed? && !MacOS::CLT.installed? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-16 22:09:41 -07:00
										 |  |  |         %W[#{prefix}/usr/bin/xcodebuild #{which("xcodebuild")}].uniq.each do |path| | 
					
						
							|  |  |  |           if File.file? path | 
					
						
							| 
									
										
										
										
											2014-12-16 15:27:36 -05:00
										 |  |  |             Utils.popen_read(path, "-version") =~ /Xcode (\d(\.\d)*)/ | 
					
						
							| 
									
										
										
										
											2014-04-15 14:18:45 -05:00
										 |  |  |             return $1 if $1 | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-15 14:25:27 -05:00
										 |  |  |         # The remaining logic provides a fake Xcode version for CLT-only | 
					
						
							|  |  |  |         # systems. This behavior only exists because Homebrew used to assume | 
					
						
							|  |  |  |         # Xcode.version would always be non-nil. This is deprecated, and will | 
					
						
							|  |  |  |         # be removed in a future version. To remain compatible, guard usage of | 
					
						
							|  |  |  |         # Xcode.version with an Xcode.installed? check. | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |         case MacOS.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 | 
					
						
							| 
									
										
										
										
											2014-10-26 14:54:36 +00:00
										 |  |  |           # https://github.com/Homebrew/homebrew/blob/master/share/doc/homebrew/Xcode.md | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |           "4.0" | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           case (MacOS.clang_version.to_f * 10).to_i | 
					
						
							|  |  |  |           when 0       then "dunno" | 
					
						
							|  |  |  |           when 1..14   then "3.2.2" | 
					
						
							|  |  |  |           when 15      then "3.2.4" | 
					
						
							|  |  |  |           when 16      then "3.2.5" | 
					
						
							|  |  |  |           when 17..20  then "4.0" | 
					
						
							|  |  |  |           when 21      then "4.1" | 
					
						
							|  |  |  |           when 22..30  then "4.2" | 
					
						
							|  |  |  |           when 31      then "4.3" | 
					
						
							|  |  |  |           when 40      then "4.4" | 
					
						
							|  |  |  |           when 41      then "4.5" | 
					
						
							|  |  |  |           when 42      then "4.6" | 
					
						
							|  |  |  |           when 50      then "5.0" | 
					
						
							| 
									
										
										
										
											2014-03-10 15:26:19 -05:00
										 |  |  |           when 51      then "5.1" | 
					
						
							| 
									
										
										
										
											2014-08-07 23:43:05 +01:00
										 |  |  |           when 60      then "6.0" | 
					
						
							| 
									
										
										
										
											2015-04-09 00:55:37 +01:00
										 |  |  |           when 61      then "6.1" | 
					
						
							| 
									
										
										
										
											2015-06-26 06:10:00 +01:00
										 |  |  |           when 70      then "7.0" | 
					
						
							|  |  |  |           else "7.0" | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2012-08-06 13:46:02 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |       def provides_autotools? | 
					
						
							| 
									
										
										
										
											2013-10-22 20:48:22 -05:00
										 |  |  |         version < "4.3" | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2012-07-09 15:18:02 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |       def provides_gcc? | 
					
						
							| 
									
										
										
										
											2013-10-22 20:48:22 -05:00
										 |  |  |         version < "4.3" | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2012-08-06 13:46:02 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-04 01:10:11 -06:00
										 |  |  |       def provides_cvs? | 
					
						
							|  |  |  |         version < "5.0" | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |       def default_prefix? | 
					
						
							| 
									
										
										
										
											2013-10-22 20:48:22 -05:00
										 |  |  |         if version < "4.3" | 
					
						
							| 
									
										
										
										
											2016-01-14 13:57:18 +01:00
										 |  |  |           prefix.to_s.start_with? "/Developer" | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |         else | 
					
						
							| 
									
										
										
										
											2016-03-15 23:50:08 -07:00
										 |  |  |           prefix.to_s == "/Applications/Xcode.app/Contents/Developer" | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2012-07-09 15:18:02 -05:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2012-07-09 15:19:30 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |     module CLT | 
					
						
							|  |  |  |       extend self | 
					
						
							| 
									
										
										
										
											2012-07-10 21:01:16 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |       STANDALONE_PKG_ID = "com.apple.pkg.DeveloperToolsCLILeo" | 
					
						
							|  |  |  |       FROM_XCODE_PKG_ID = "com.apple.pkg.DeveloperToolsCLI" | 
					
						
							| 
									
										
										
										
											2014-06-20 12:18:28 +01:00
										 |  |  |       MAVERICKS_PKG_ID = "com.apple.pkg.CLTools_Executables" | 
					
						
							| 
									
										
										
										
											2014-10-10 13:06:50 -05:00
										 |  |  |       MAVERICKS_NEW_PKG_ID = "com.apple.pkg.CLTools_Base" # obsolete | 
					
						
							| 
									
										
										
										
											2014-05-02 16:48:59 -05:00
										 |  |  |       MAVERICKS_PKG_PATH = "/Library/Developer/CommandLineTools" | 
					
						
							| 
									
										
										
										
											2012-09-14 13:24:28 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-26 10:35:30 -07:00
										 |  |  |       # Returns true even if outdated tools are installed, e.g. | 
					
						
							|  |  |  |       # tools from Xcode 4.x on 10.9 | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |       def installed? | 
					
						
							| 
									
										
										
										
											2014-03-26 10:35:30 -07:00
										 |  |  |         !!detect_version | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2013-07-21 16:41:50 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-01 16:16:01 -05:00
										 |  |  |       def latest_version | 
					
						
							| 
									
										
										
										
											2014-09-18 10:09:14 -05:00
										 |  |  |         case MacOS.version | 
					
						
							| 
									
										
										
										
											2015-12-09 05:06:00 +00:00
										 |  |  |         when "10.11" then "700.1.81" | 
					
						
							|  |  |  |         when "10.10" then "700.1.81" | 
					
						
							| 
									
										
										
										
											2015-03-10 00:08:43 +00:00
										 |  |  |         when "10.9"  then "600.0.57" | 
					
						
							| 
									
										
										
										
											2014-09-18 10:09:14 -05:00
										 |  |  |         when "10.8"  then "503.0.40" | 
					
						
							| 
									
										
										
										
											2013-11-01 16:16:01 -05:00
										 |  |  |         else | 
					
						
							|  |  |  |           "425.0.28" | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2012-08-17 17:18:17 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |       def outdated? | 
					
						
							| 
									
										
										
										
											2014-05-12 14:33:41 -05:00
										 |  |  |         if MacOS.version >= :mavericks | 
					
						
							|  |  |  |           version = `#{MAVERICKS_PKG_PATH}/usr/bin/clang --version` | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           version = `/usr/bin/clang --version` | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |         version = version[/clang-(\d+\.\d+\.\d+(\.\d+)?)/, 1] || "0" | 
					
						
							| 
									
										
										
										
											2013-11-01 16:16:01 -05:00
										 |  |  |         version < latest_version | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2013-05-22 22:26:09 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-22 10:14:20 +00:00
										 |  |  |       # Version string (a pretty long one) of the CLT package. | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |       # Note, that different ways to install the CLTs lead to different | 
					
						
							|  |  |  |       # version numbers. | 
					
						
							|  |  |  |       def version | 
					
						
							|  |  |  |         @version ||= detect_version | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2013-07-21 20:09:55 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |       def detect_version | 
					
						
							| 
									
										
										
										
											2014-10-10 13:06:50 -05:00
										 |  |  |         [MAVERICKS_PKG_ID, MAVERICKS_NEW_PKG_ID, STANDALONE_PKG_ID, FROM_XCODE_PKG_ID].find do |id| | 
					
						
							| 
									
										
										
										
											2014-10-17 19:36:25 +01:00
										 |  |  |           if MacOS.version >= :mavericks | 
					
						
							|  |  |  |             next unless File.exist?("#{MAVERICKS_PKG_PATH}/usr/bin/clang") | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2013-10-18 12:56:51 -05:00
										 |  |  |           version = MacOS.pkgutil_info(id)[/version: (.+)$/, 1] | 
					
						
							|  |  |  |           return version if version | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2013-07-21 20:09:55 -05:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2012-07-09 15:18:02 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | end |