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
This commit is contained in:
parent
7b26c585c2
commit
3a1d7e7259
@ -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
|
||||
|
59
Library/Homebrew/os/mac/sdk.rb
Normal file
59
Library/Homebrew/os/mac/sdk.rb
Normal file
@ -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
|
Loading…
x
Reference in New Issue
Block a user