diff options
| author | Misty De Meo | 2015-12-04 13:58:22 -0800 | 
|---|---|---|
| committer | Misty De Meo | 2015-12-07 13:17:43 -0800 | 
| commit | 3a1d7e7259440abe61cc1cc9319d179caba4e8b6 (patch) | |
| tree | 41f94c87303c6af4494a2ccd809bb218deeb44da | |
| parent | 7b26c585c2a26ec0dad201852ca4934c77fcc493 (diff) | |
| download | brew-3a1d7e7259440abe61cc1cc9319d179caba4e8b6.tar.bz2 | |
MacOS: refactor sdk_path lookup
* Pull SDK lookup code into a new `locator` class, which caches its
  results
* SDKLocator only queries one SDK location, not all SDK locations
* Build a map of all installed SDKs inside that location, instead of
  just the requested SDK
* Ask xcrun for --show-sdk-platform-path first so that all SDKs can be
  found, instead of asking xcodebuild for a specific SDK
* Add a new `SDK` class, which tracks the version and the prefix; add a
  new `MacOS.sdk` method which returns an `SDK` instance instead of a
  bare path; MacOS.sdk_path still returns a bare path
| -rw-r--r-- | Library/Homebrew/os/mac.rb | 26 | ||||
| -rw-r--r-- | Library/Homebrew/os/mac/sdk.rb | 59 | 
2 files changed, 75 insertions, 10 deletions
diff --git a/Library/Homebrew/os/mac.rb b/Library/Homebrew/os/mac.rb index c4916a955..893eb6ddf 100644 --- a/Library/Homebrew/os/mac.rb +++ b/Library/Homebrew/os/mac.rb @@ -3,6 +3,7 @@ require "os/mac/version"  require "os/mac/xcode"  require "os/mac/xquartz"  require "os/mac/pathname" +require "os/mac/sdk"  module OS    module Mac @@ -79,19 +80,24 @@ module OS        @active_developer_dir ||= Utils.popen_read("/usr/bin/xcode-select", "-print-path").strip      end -    def sdk_path(v = version) -      (@sdk_path ||= {}).fetch(v.to_s) do |key| -        opts = [] -        # First query Xcode itself -        opts << Utils.popen_read(locate("xcodebuild"), "-version", "-sdk", "macosx#{v}", "Path").chomp -        # Xcode.prefix is pretty smart, so lets look inside to find the sdk -        opts << "#{Xcode.prefix}/Platforms/MacOSX.platform/Developer/SDKs/MacOSX#{v}.sdk" -        # Xcode < 4.3 style -        opts << "/Developer/SDKs/MacOSX#{v}.sdk" -        @sdk_path[key] = opts.map { |a| Pathname.new(a) }.detect(&:directory?) +    # Returns the requested SDK, if installed. +    # If the requested SDK is not installed returns either: +    # a) The newest SDK (if any SDKs are available), or +    # b) nil +    def sdk(v = version) +      @locator ||= SDKLocator.new +      begin +        @locator.sdk_for v +      rescue SDKLocator::NoSDKError        end      end +    # Returns the path to an SDK or nil, following the rules set by #sdk. +    def sdk_path(v = version) +      s = sdk(v) +      s.path unless s.nil? +    end +      def default_cc        cc = locate "cc"        cc.realpath.basename.to_s rescue nil diff --git a/Library/Homebrew/os/mac/sdk.rb b/Library/Homebrew/os/mac/sdk.rb new file mode 100644 index 000000000..8ba5f4329 --- /dev/null +++ b/Library/Homebrew/os/mac/sdk.rb @@ -0,0 +1,59 @@ +require "os/mac/version" + +module OS +  module Mac +    class SDK +      attr_reader :version, :path + +      def initialize(version, path) +        @version = OS::Mac::Version.new version +        @path = Pathname.new(path) +      end +    end + +    class SDKLocator +      class NoSDKError < StandardError; end + +      def sdk_for(v) +        path = sdk_paths[v] +        raise NoSDKError if path.nil? + +        SDK.new v, path +      end + +      def latest_sdk +        return if sdk_paths.empty? + +        v, path = sdk_paths.max {|a, b| OS::Mac::Version.new(a[0]) <=> OS::Mac::Version.new(b[0])} +        SDK.new v, path +      end + +      private + +      def sdk_paths +        @sdk_paths ||= begin +          # Xcode.prefix is pretty smart, so let's look inside to find the sdk +          sdk_prefix = "#{Xcode.prefix}/Platforms/MacOSX.platform/Developer/SDKs" +          # Xcode < 4.3 style +          sdk_prefix = "/Developer/SDKs" unless File.directory? sdk_prefix +          # Finally query Xcode itself (this is slow, so check it last) +          sdk_prefix = File.join(Utils.popen_read(OS::Mac.locate("xcrun"), "--show-sdk-platform-path").chomp, "Developer", "SDKs") unless File.directory? sdk_prefix + +          # Bail out if there is no SDK prefix at all +          if !File.directory? sdk_prefix +            {} +          else +            paths = {} + +            Dir[File.join(sdk_prefix, "MacOSX*.sdk")].each do |sdk_path| +              version = sdk_path[/MacOSX(\d+\.\d+)u?.sdk$/, 1] +              paths[version] = sdk_path unless version.nil? +            end + +            paths +          end +        end +      end +    end +  end +end  | 
