11e05d7b3SAdrian Prantl //===-- XcodeSDK.cpp ------------------------------------------------------===// 21e05d7b3SAdrian Prantl // 31e05d7b3SAdrian Prantl // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 41e05d7b3SAdrian Prantl // See https://llvm.org/LICENSE.txt for license information. 51e05d7b3SAdrian Prantl // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 61e05d7b3SAdrian Prantl // 71e05d7b3SAdrian Prantl //===----------------------------------------------------------------------===// 81e05d7b3SAdrian Prantl 91e05d7b3SAdrian Prantl #include "lldb/Utility/XcodeSDK.h" 106e95d51eSAdrian Prantl #include "lldb/Utility/FileSpec.h" 111e05d7b3SAdrian Prantl 121e05d7b3SAdrian Prantl #include "lldb/lldb-types.h" 136e95d51eSAdrian Prantl 146e95d51eSAdrian Prantl #include "llvm/ADT/Triple.h" 156e95d51eSAdrian Prantl 166a9edce2SEric Christopher #include <string> 171e05d7b3SAdrian Prantl 181e05d7b3SAdrian Prantl using namespace lldb; 191e05d7b3SAdrian Prantl using namespace lldb_private; 201e05d7b3SAdrian Prantl 211e05d7b3SAdrian Prantl XcodeSDK &XcodeSDK::operator=(XcodeSDK other) { 221e05d7b3SAdrian Prantl m_name = other.m_name; 231e05d7b3SAdrian Prantl return *this; 241e05d7b3SAdrian Prantl } 251e05d7b3SAdrian Prantl 261e05d7b3SAdrian Prantl bool XcodeSDK::operator==(XcodeSDK other) { 271e05d7b3SAdrian Prantl return m_name == other.m_name; 281e05d7b3SAdrian Prantl } 291e05d7b3SAdrian Prantl 301e05d7b3SAdrian Prantl static XcodeSDK::Type ParseSDKName(llvm::StringRef &name) { 311e05d7b3SAdrian Prantl if (name.consume_front("MacOSX")) 321e05d7b3SAdrian Prantl return XcodeSDK::MacOSX; 331e05d7b3SAdrian Prantl if (name.consume_front("iPhoneSimulator")) 341e05d7b3SAdrian Prantl return XcodeSDK::iPhoneSimulator; 351e05d7b3SAdrian Prantl if (name.consume_front("iPhoneOS")) 361e05d7b3SAdrian Prantl return XcodeSDK::iPhoneOS; 371e05d7b3SAdrian Prantl if (name.consume_front("AppleTVSimulator")) 381e05d7b3SAdrian Prantl return XcodeSDK::AppleTVSimulator; 391e05d7b3SAdrian Prantl if (name.consume_front("AppleTVOS")) 401e05d7b3SAdrian Prantl return XcodeSDK::AppleTVOS; 411e05d7b3SAdrian Prantl if (name.consume_front("WatchSimulator")) 421e05d7b3SAdrian Prantl return XcodeSDK::WatchSimulator; 431e05d7b3SAdrian Prantl if (name.consume_front("WatchOS")) 441e05d7b3SAdrian Prantl return XcodeSDK::watchOS; 451e05d7b3SAdrian Prantl if (name.consume_front("bridgeOS")) 461e05d7b3SAdrian Prantl return XcodeSDK::bridgeOS; 471e05d7b3SAdrian Prantl if (name.consume_front("Linux")) 481e05d7b3SAdrian Prantl return XcodeSDK::Linux; 491e05d7b3SAdrian Prantl static_assert(XcodeSDK::Linux == XcodeSDK::numSDKTypes - 1, 501e05d7b3SAdrian Prantl "New SDK type was added, update this list!"); 511e05d7b3SAdrian Prantl return XcodeSDK::unknown; 521e05d7b3SAdrian Prantl } 531e05d7b3SAdrian Prantl 541e05d7b3SAdrian Prantl static llvm::VersionTuple ParseSDKVersion(llvm::StringRef &name) { 551e05d7b3SAdrian Prantl unsigned i = 0; 561e05d7b3SAdrian Prantl while (i < name.size() && name[i] >= '0' && name[i] <= '9') 571e05d7b3SAdrian Prantl ++i; 581e05d7b3SAdrian Prantl if (i == name.size() || name[i++] != '.') 591e05d7b3SAdrian Prantl return {}; 601e05d7b3SAdrian Prantl while (i < name.size() && name[i] >= '0' && name[i] <= '9') 611e05d7b3SAdrian Prantl ++i; 621e05d7b3SAdrian Prantl if (i == name.size() || name[i++] != '.') 631e05d7b3SAdrian Prantl return {}; 641e05d7b3SAdrian Prantl 651e05d7b3SAdrian Prantl llvm::VersionTuple version; 661e05d7b3SAdrian Prantl version.tryParse(name.slice(0, i - 1)); 671e05d7b3SAdrian Prantl name = name.drop_front(i); 681e05d7b3SAdrian Prantl return version; 691e05d7b3SAdrian Prantl } 701e05d7b3SAdrian Prantl 7179feafa5SAdrian Prantl static bool ParseAppleInternalSDK(llvm::StringRef &name) { 7279feafa5SAdrian Prantl return name.consume_front("Internal."); 7379feafa5SAdrian Prantl } 741e05d7b3SAdrian Prantl 7579feafa5SAdrian Prantl XcodeSDK::Info XcodeSDK::Parse() const { 7679feafa5SAdrian Prantl XcodeSDK::Info info; 771e05d7b3SAdrian Prantl llvm::StringRef input(m_name); 7879feafa5SAdrian Prantl info.type = ParseSDKName(input); 7979feafa5SAdrian Prantl info.version = ParseSDKVersion(input); 8079feafa5SAdrian Prantl info.internal = ParseAppleInternalSDK(input); 8179feafa5SAdrian Prantl return info; 8279feafa5SAdrian Prantl } 8379feafa5SAdrian Prantl 8479feafa5SAdrian Prantl bool XcodeSDK::IsAppleInternalSDK() const { 8579feafa5SAdrian Prantl llvm::StringRef input(m_name); 8679feafa5SAdrian Prantl ParseSDKName(input); 8779feafa5SAdrian Prantl ParseSDKVersion(input); 8879feafa5SAdrian Prantl return ParseAppleInternalSDK(input); 891e05d7b3SAdrian Prantl } 901e05d7b3SAdrian Prantl 911e05d7b3SAdrian Prantl llvm::VersionTuple XcodeSDK::GetVersion() const { 921e05d7b3SAdrian Prantl llvm::StringRef input(m_name); 931e05d7b3SAdrian Prantl ParseSDKName(input); 941e05d7b3SAdrian Prantl return ParseSDKVersion(input); 951e05d7b3SAdrian Prantl } 961e05d7b3SAdrian Prantl 971e05d7b3SAdrian Prantl XcodeSDK::Type XcodeSDK::GetType() const { 981e05d7b3SAdrian Prantl llvm::StringRef input(m_name); 991e05d7b3SAdrian Prantl return ParseSDKName(input); 1001e05d7b3SAdrian Prantl } 1011e05d7b3SAdrian Prantl 1021e05d7b3SAdrian Prantl llvm::StringRef XcodeSDK::GetString() const { return m_name; } 1031e05d7b3SAdrian Prantl 10479feafa5SAdrian Prantl bool XcodeSDK::Info::operator<(const Info &other) const { 10579feafa5SAdrian Prantl return std::tie(type, version, internal) < 10679feafa5SAdrian Prantl std::tie(other.type, other.version, other.internal); 10779feafa5SAdrian Prantl } 1081e05d7b3SAdrian Prantl void XcodeSDK::Merge(XcodeSDK other) { 1091e05d7b3SAdrian Prantl // The "bigger" SDK always wins. 11079feafa5SAdrian Prantl auto l = Parse(); 11179feafa5SAdrian Prantl auto r = other.Parse(); 11279feafa5SAdrian Prantl if (l < r) 1131e05d7b3SAdrian Prantl *this = other; 11479feafa5SAdrian Prantl else { 11579feafa5SAdrian Prantl // The Internal flag always wins. 11679feafa5SAdrian Prantl if (llvm::StringRef(m_name).endswith(".sdk")) 11779feafa5SAdrian Prantl if (!l.internal && r.internal) 11879feafa5SAdrian Prantl m_name = 11979feafa5SAdrian Prantl m_name.substr(0, m_name.size() - 3) + std::string("Internal.sdk"); 12079feafa5SAdrian Prantl } 1211e05d7b3SAdrian Prantl } 1221e05d7b3SAdrian Prantl 12379feafa5SAdrian Prantl std::string XcodeSDK::GetCanonicalName(XcodeSDK::Info info) { 12479feafa5SAdrian Prantl std::string name; 12579feafa5SAdrian Prantl switch (info.type) { 1261e05d7b3SAdrian Prantl case MacOSX: 12779feafa5SAdrian Prantl name = "macosx"; 12879feafa5SAdrian Prantl break; 1291e05d7b3SAdrian Prantl case iPhoneSimulator: 13079feafa5SAdrian Prantl name = "iphonesimulator"; 13179feafa5SAdrian Prantl break; 1321e05d7b3SAdrian Prantl case iPhoneOS: 13379feafa5SAdrian Prantl name = "iphoneos"; 13479feafa5SAdrian Prantl break; 1351e05d7b3SAdrian Prantl case AppleTVSimulator: 13679feafa5SAdrian Prantl name = "appletvsimulator"; 13779feafa5SAdrian Prantl break; 1381e05d7b3SAdrian Prantl case AppleTVOS: 13979feafa5SAdrian Prantl name = "appletvos"; 14079feafa5SAdrian Prantl break; 1411e05d7b3SAdrian Prantl case WatchSimulator: 14279feafa5SAdrian Prantl name = "watchsimulator"; 14379feafa5SAdrian Prantl break; 1441e05d7b3SAdrian Prantl case watchOS: 14579feafa5SAdrian Prantl name = "watchos"; 14679feafa5SAdrian Prantl break; 1471e05d7b3SAdrian Prantl case bridgeOS: 14879feafa5SAdrian Prantl name = "bridgeos"; 14979feafa5SAdrian Prantl break; 1501e05d7b3SAdrian Prantl case Linux: 15179feafa5SAdrian Prantl name = "linux"; 15279feafa5SAdrian Prantl break; 1531e05d7b3SAdrian Prantl case numSDKTypes: 1541e05d7b3SAdrian Prantl case unknown: 15579feafa5SAdrian Prantl return {}; 1561e05d7b3SAdrian Prantl } 15779feafa5SAdrian Prantl if (!info.version.empty()) 15879feafa5SAdrian Prantl name += info.version.getAsString(); 15979feafa5SAdrian Prantl if (info.internal) 16079feafa5SAdrian Prantl name += ".internal"; 16179feafa5SAdrian Prantl return name; 1621e05d7b3SAdrian Prantl } 1631e05d7b3SAdrian Prantl 1641e05d7b3SAdrian Prantl bool XcodeSDK::SDKSupportsModules(XcodeSDK::Type sdk_type, 1651e05d7b3SAdrian Prantl llvm::VersionTuple version) { 1661e05d7b3SAdrian Prantl switch (sdk_type) { 1671e05d7b3SAdrian Prantl case Type::MacOSX: 1681e05d7b3SAdrian Prantl return version >= llvm::VersionTuple(10, 10); 1691e05d7b3SAdrian Prantl case Type::iPhoneOS: 1701e05d7b3SAdrian Prantl case Type::iPhoneSimulator: 1711e05d7b3SAdrian Prantl case Type::AppleTVOS: 1721e05d7b3SAdrian Prantl case Type::AppleTVSimulator: 1731e05d7b3SAdrian Prantl return version >= llvm::VersionTuple(8); 1741e05d7b3SAdrian Prantl case Type::watchOS: 1751e05d7b3SAdrian Prantl case Type::WatchSimulator: 1761e05d7b3SAdrian Prantl return version >= llvm::VersionTuple(6); 1771e05d7b3SAdrian Prantl default: 1781e05d7b3SAdrian Prantl return false; 1791e05d7b3SAdrian Prantl } 1801e05d7b3SAdrian Prantl 1811e05d7b3SAdrian Prantl return false; 1821e05d7b3SAdrian Prantl } 1831e05d7b3SAdrian Prantl 184*dec1c94eSAdrian Prantl bool XcodeSDK::SupportsSwift() const { 185*dec1c94eSAdrian Prantl XcodeSDK::Info info = Parse(); 186*dec1c94eSAdrian Prantl switch (info.type) { 187*dec1c94eSAdrian Prantl case Type::MacOSX: 188*dec1c94eSAdrian Prantl return info.version.empty() || info.version >= llvm::VersionTuple(10, 10); 189*dec1c94eSAdrian Prantl case Type::iPhoneOS: 190*dec1c94eSAdrian Prantl case Type::iPhoneSimulator: 191*dec1c94eSAdrian Prantl return info.version.empty() || info.version >= llvm::VersionTuple(8); 192*dec1c94eSAdrian Prantl case Type::AppleTVSimulator: 193*dec1c94eSAdrian Prantl case Type::AppleTVOS: 194*dec1c94eSAdrian Prantl return info.version.empty() || info.version >= llvm::VersionTuple(9); 195*dec1c94eSAdrian Prantl case Type::WatchSimulator: 196*dec1c94eSAdrian Prantl case Type::watchOS: 197*dec1c94eSAdrian Prantl return info.version.empty() || info.version >= llvm::VersionTuple(2); 198*dec1c94eSAdrian Prantl case Type::Linux: 199*dec1c94eSAdrian Prantl return true; 200*dec1c94eSAdrian Prantl default: 201*dec1c94eSAdrian Prantl return false; 202*dec1c94eSAdrian Prantl } 203*dec1c94eSAdrian Prantl } 204*dec1c94eSAdrian Prantl 2051e05d7b3SAdrian Prantl bool XcodeSDK::SDKSupportsModules(XcodeSDK::Type desired_type, 2061e05d7b3SAdrian Prantl const FileSpec &sdk_path) { 2071e05d7b3SAdrian Prantl ConstString last_path_component = sdk_path.GetLastPathComponent(); 2081e05d7b3SAdrian Prantl 2094356aa20SAdrian Prantl if (!last_path_component) 2101e05d7b3SAdrian Prantl return false; 2111e05d7b3SAdrian Prantl 2124356aa20SAdrian Prantl XcodeSDK sdk(last_path_component.GetStringRef().str()); 2134356aa20SAdrian Prantl if (sdk.GetType() != desired_type) 2141e05d7b3SAdrian Prantl return false; 2154356aa20SAdrian Prantl return SDKSupportsModules(sdk.GetType(), sdk.GetVersion()); 2161e05d7b3SAdrian Prantl } 2176e95d51eSAdrian Prantl 2186e95d51eSAdrian Prantl XcodeSDK::Type XcodeSDK::GetSDKTypeForTriple(const llvm::Triple &triple) { 2196e95d51eSAdrian Prantl using namespace llvm; 2206e95d51eSAdrian Prantl switch (triple.getOS()) { 2216e95d51eSAdrian Prantl case Triple::MacOSX: 2226e95d51eSAdrian Prantl case Triple::Darwin: 2236e95d51eSAdrian Prantl return XcodeSDK::MacOSX; 2246e95d51eSAdrian Prantl case Triple::IOS: 2256e95d51eSAdrian Prantl switch (triple.getEnvironment()) { 2266e95d51eSAdrian Prantl case Triple::MacABI: 2276e95d51eSAdrian Prantl return XcodeSDK::MacOSX; 2286e95d51eSAdrian Prantl case Triple::Simulator: 2296e95d51eSAdrian Prantl return XcodeSDK::iPhoneSimulator; 2306e95d51eSAdrian Prantl default: 2316e95d51eSAdrian Prantl return XcodeSDK::iPhoneOS; 2326e95d51eSAdrian Prantl } 2336e95d51eSAdrian Prantl case Triple::TvOS: 2346e95d51eSAdrian Prantl if (triple.getEnvironment() == Triple::Simulator) 2356e95d51eSAdrian Prantl return XcodeSDK::AppleTVSimulator; 2366e95d51eSAdrian Prantl return XcodeSDK::AppleTVOS; 2376e95d51eSAdrian Prantl case Triple::WatchOS: 2386e95d51eSAdrian Prantl if (triple.getEnvironment() == Triple::Simulator) 2396e95d51eSAdrian Prantl return XcodeSDK::WatchSimulator; 2406e95d51eSAdrian Prantl return XcodeSDK::watchOS; 2416e95d51eSAdrian Prantl case Triple::Linux: 2426e95d51eSAdrian Prantl return XcodeSDK::Linux; 2436e95d51eSAdrian Prantl default: 2446e95d51eSAdrian Prantl return XcodeSDK::unknown; 2456e95d51eSAdrian Prantl } 2466e95d51eSAdrian Prantl } 247