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 21ae920a81SAdrian Prantl static llvm::StringRef GetName(XcodeSDK::Type type) { 22ae920a81SAdrian Prantl switch (type) { 23ae920a81SAdrian Prantl case XcodeSDK::MacOSX: 24ae920a81SAdrian Prantl return "MacOSX"; 25ae920a81SAdrian Prantl case XcodeSDK::iPhoneSimulator: 26ae920a81SAdrian Prantl return "iPhoneSimulator"; 27ae920a81SAdrian Prantl case XcodeSDK::iPhoneOS: 28ae920a81SAdrian Prantl return "iPhoneOS"; 29ae920a81SAdrian Prantl case XcodeSDK::AppleTVSimulator: 30ae920a81SAdrian Prantl return "AppleTVSimulator"; 31ae920a81SAdrian Prantl case XcodeSDK::AppleTVOS: 32ae920a81SAdrian Prantl return "AppleTVOS"; 33ae920a81SAdrian Prantl case XcodeSDK::WatchSimulator: 34ae920a81SAdrian Prantl return "WatchSimulator"; 35ae920a81SAdrian Prantl case XcodeSDK::watchOS: 36ae920a81SAdrian Prantl return "WatchOS"; 37ae920a81SAdrian Prantl case XcodeSDK::bridgeOS: 38ae920a81SAdrian Prantl return "bridgeOS"; 39ae920a81SAdrian Prantl case XcodeSDK::Linux: 40ae920a81SAdrian Prantl return "Linux"; 41ae920a81SAdrian Prantl case XcodeSDK::unknown: 42ae920a81SAdrian Prantl return {}; 43ae920a81SAdrian Prantl } 44*dac6e9caSPavel Labath llvm_unreachable("Unhandled sdk type!"); 45ae920a81SAdrian Prantl } 46ae920a81SAdrian Prantl 47ae920a81SAdrian Prantl XcodeSDK::XcodeSDK(XcodeSDK::Info info) : m_name(GetName(info.type).str()) { 48ae920a81SAdrian Prantl if (!m_name.empty()) { 49ae920a81SAdrian Prantl if (!info.version.empty()) 50ae920a81SAdrian Prantl m_name += info.version.getAsString(); 51ae920a81SAdrian Prantl if (info.internal) 52ae920a81SAdrian Prantl m_name += ".Internal"; 53ae920a81SAdrian Prantl m_name += ".sdk"; 54ae920a81SAdrian Prantl } 55ae920a81SAdrian Prantl } 56ae920a81SAdrian Prantl 571e05d7b3SAdrian Prantl XcodeSDK &XcodeSDK::operator=(XcodeSDK other) { 581e05d7b3SAdrian Prantl m_name = other.m_name; 591e05d7b3SAdrian Prantl return *this; 601e05d7b3SAdrian Prantl } 611e05d7b3SAdrian Prantl 621e05d7b3SAdrian Prantl bool XcodeSDK::operator==(XcodeSDK other) { 631e05d7b3SAdrian Prantl return m_name == other.m_name; 641e05d7b3SAdrian Prantl } 651e05d7b3SAdrian Prantl 661e05d7b3SAdrian Prantl static XcodeSDK::Type ParseSDKName(llvm::StringRef &name) { 671e05d7b3SAdrian Prantl if (name.consume_front("MacOSX")) 681e05d7b3SAdrian Prantl return XcodeSDK::MacOSX; 691e05d7b3SAdrian Prantl if (name.consume_front("iPhoneSimulator")) 701e05d7b3SAdrian Prantl return XcodeSDK::iPhoneSimulator; 711e05d7b3SAdrian Prantl if (name.consume_front("iPhoneOS")) 721e05d7b3SAdrian Prantl return XcodeSDK::iPhoneOS; 731e05d7b3SAdrian Prantl if (name.consume_front("AppleTVSimulator")) 741e05d7b3SAdrian Prantl return XcodeSDK::AppleTVSimulator; 751e05d7b3SAdrian Prantl if (name.consume_front("AppleTVOS")) 761e05d7b3SAdrian Prantl return XcodeSDK::AppleTVOS; 771e05d7b3SAdrian Prantl if (name.consume_front("WatchSimulator")) 781e05d7b3SAdrian Prantl return XcodeSDK::WatchSimulator; 791e05d7b3SAdrian Prantl if (name.consume_front("WatchOS")) 801e05d7b3SAdrian Prantl return XcodeSDK::watchOS; 811e05d7b3SAdrian Prantl if (name.consume_front("bridgeOS")) 821e05d7b3SAdrian Prantl return XcodeSDK::bridgeOS; 831e05d7b3SAdrian Prantl if (name.consume_front("Linux")) 841e05d7b3SAdrian Prantl return XcodeSDK::Linux; 851e05d7b3SAdrian Prantl static_assert(XcodeSDK::Linux == XcodeSDK::numSDKTypes - 1, 861e05d7b3SAdrian Prantl "New SDK type was added, update this list!"); 871e05d7b3SAdrian Prantl return XcodeSDK::unknown; 881e05d7b3SAdrian Prantl } 891e05d7b3SAdrian Prantl 901e05d7b3SAdrian Prantl static llvm::VersionTuple ParseSDKVersion(llvm::StringRef &name) { 911e05d7b3SAdrian Prantl unsigned i = 0; 921e05d7b3SAdrian Prantl while (i < name.size() && name[i] >= '0' && name[i] <= '9') 931e05d7b3SAdrian Prantl ++i; 941e05d7b3SAdrian Prantl if (i == name.size() || name[i++] != '.') 951e05d7b3SAdrian Prantl return {}; 961e05d7b3SAdrian Prantl while (i < name.size() && name[i] >= '0' && name[i] <= '9') 971e05d7b3SAdrian Prantl ++i; 981e05d7b3SAdrian Prantl if (i == name.size() || name[i++] != '.') 991e05d7b3SAdrian Prantl return {}; 1001e05d7b3SAdrian Prantl 1011e05d7b3SAdrian Prantl llvm::VersionTuple version; 1021e05d7b3SAdrian Prantl version.tryParse(name.slice(0, i - 1)); 1031e05d7b3SAdrian Prantl name = name.drop_front(i); 1041e05d7b3SAdrian Prantl return version; 1051e05d7b3SAdrian Prantl } 1061e05d7b3SAdrian Prantl 10779feafa5SAdrian Prantl static bool ParseAppleInternalSDK(llvm::StringRef &name) { 108ae920a81SAdrian Prantl return name.consume_front("Internal.") || name.consume_front(".Internal."); 10979feafa5SAdrian Prantl } 1101e05d7b3SAdrian Prantl 11179feafa5SAdrian Prantl XcodeSDK::Info XcodeSDK::Parse() const { 11279feafa5SAdrian Prantl XcodeSDK::Info info; 1131e05d7b3SAdrian Prantl llvm::StringRef input(m_name); 11479feafa5SAdrian Prantl info.type = ParseSDKName(input); 11579feafa5SAdrian Prantl info.version = ParseSDKVersion(input); 11679feafa5SAdrian Prantl info.internal = ParseAppleInternalSDK(input); 11779feafa5SAdrian Prantl return info; 11879feafa5SAdrian Prantl } 11979feafa5SAdrian Prantl 12079feafa5SAdrian Prantl bool XcodeSDK::IsAppleInternalSDK() const { 12179feafa5SAdrian Prantl llvm::StringRef input(m_name); 12279feafa5SAdrian Prantl ParseSDKName(input); 12379feafa5SAdrian Prantl ParseSDKVersion(input); 12479feafa5SAdrian Prantl return ParseAppleInternalSDK(input); 1251e05d7b3SAdrian Prantl } 1261e05d7b3SAdrian Prantl 1271e05d7b3SAdrian Prantl llvm::VersionTuple XcodeSDK::GetVersion() const { 1281e05d7b3SAdrian Prantl llvm::StringRef input(m_name); 1291e05d7b3SAdrian Prantl ParseSDKName(input); 1301e05d7b3SAdrian Prantl return ParseSDKVersion(input); 1311e05d7b3SAdrian Prantl } 1321e05d7b3SAdrian Prantl 1331e05d7b3SAdrian Prantl XcodeSDK::Type XcodeSDK::GetType() const { 1341e05d7b3SAdrian Prantl llvm::StringRef input(m_name); 1351e05d7b3SAdrian Prantl return ParseSDKName(input); 1361e05d7b3SAdrian Prantl } 1371e05d7b3SAdrian Prantl 1381e05d7b3SAdrian Prantl llvm::StringRef XcodeSDK::GetString() const { return m_name; } 1391e05d7b3SAdrian Prantl 14079feafa5SAdrian Prantl bool XcodeSDK::Info::operator<(const Info &other) const { 14179feafa5SAdrian Prantl return std::tie(type, version, internal) < 14279feafa5SAdrian Prantl std::tie(other.type, other.version, other.internal); 14379feafa5SAdrian Prantl } 144ae920a81SAdrian Prantl 145ae920a81SAdrian Prantl bool XcodeSDK::Info::operator==(const Info &other) const { 146ae920a81SAdrian Prantl return std::tie(type, version, internal) == 147ae920a81SAdrian Prantl std::tie(other.type, other.version, other.internal); 148ae920a81SAdrian Prantl } 149ae920a81SAdrian Prantl 1501e05d7b3SAdrian Prantl void XcodeSDK::Merge(XcodeSDK other) { 1511e05d7b3SAdrian Prantl // The "bigger" SDK always wins. 15279feafa5SAdrian Prantl auto l = Parse(); 15379feafa5SAdrian Prantl auto r = other.Parse(); 15479feafa5SAdrian Prantl if (l < r) 1551e05d7b3SAdrian Prantl *this = other; 15679feafa5SAdrian Prantl else { 15779feafa5SAdrian Prantl // The Internal flag always wins. 15879feafa5SAdrian Prantl if (llvm::StringRef(m_name).endswith(".sdk")) 15979feafa5SAdrian Prantl if (!l.internal && r.internal) 16079feafa5SAdrian Prantl m_name = 16179feafa5SAdrian Prantl m_name.substr(0, m_name.size() - 3) + std::string("Internal.sdk"); 16279feafa5SAdrian Prantl } 1631e05d7b3SAdrian Prantl } 1641e05d7b3SAdrian Prantl 16579feafa5SAdrian Prantl std::string XcodeSDK::GetCanonicalName(XcodeSDK::Info info) { 16679feafa5SAdrian Prantl std::string name; 16779feafa5SAdrian Prantl switch (info.type) { 1681e05d7b3SAdrian Prantl case MacOSX: 16979feafa5SAdrian Prantl name = "macosx"; 17079feafa5SAdrian Prantl break; 1711e05d7b3SAdrian Prantl case iPhoneSimulator: 17279feafa5SAdrian Prantl name = "iphonesimulator"; 17379feafa5SAdrian Prantl break; 1741e05d7b3SAdrian Prantl case iPhoneOS: 17579feafa5SAdrian Prantl name = "iphoneos"; 17679feafa5SAdrian Prantl break; 1771e05d7b3SAdrian Prantl case AppleTVSimulator: 17879feafa5SAdrian Prantl name = "appletvsimulator"; 17979feafa5SAdrian Prantl break; 1801e05d7b3SAdrian Prantl case AppleTVOS: 18179feafa5SAdrian Prantl name = "appletvos"; 18279feafa5SAdrian Prantl break; 1831e05d7b3SAdrian Prantl case WatchSimulator: 18479feafa5SAdrian Prantl name = "watchsimulator"; 18579feafa5SAdrian Prantl break; 1861e05d7b3SAdrian Prantl case watchOS: 18779feafa5SAdrian Prantl name = "watchos"; 18879feafa5SAdrian Prantl break; 1891e05d7b3SAdrian Prantl case bridgeOS: 19079feafa5SAdrian Prantl name = "bridgeos"; 19179feafa5SAdrian Prantl break; 1921e05d7b3SAdrian Prantl case Linux: 19379feafa5SAdrian Prantl name = "linux"; 19479feafa5SAdrian Prantl break; 1951e05d7b3SAdrian Prantl case unknown: 19679feafa5SAdrian Prantl return {}; 1971e05d7b3SAdrian Prantl } 19879feafa5SAdrian Prantl if (!info.version.empty()) 19979feafa5SAdrian Prantl name += info.version.getAsString(); 20079feafa5SAdrian Prantl if (info.internal) 20179feafa5SAdrian Prantl name += ".internal"; 20279feafa5SAdrian Prantl return name; 2031e05d7b3SAdrian Prantl } 2041e05d7b3SAdrian Prantl 2051e05d7b3SAdrian Prantl bool XcodeSDK::SDKSupportsModules(XcodeSDK::Type sdk_type, 2061e05d7b3SAdrian Prantl llvm::VersionTuple version) { 2071e05d7b3SAdrian Prantl switch (sdk_type) { 2081e05d7b3SAdrian Prantl case Type::MacOSX: 2091e05d7b3SAdrian Prantl return version >= llvm::VersionTuple(10, 10); 2101e05d7b3SAdrian Prantl case Type::iPhoneOS: 2111e05d7b3SAdrian Prantl case Type::iPhoneSimulator: 2121e05d7b3SAdrian Prantl case Type::AppleTVOS: 2131e05d7b3SAdrian Prantl case Type::AppleTVSimulator: 2141e05d7b3SAdrian Prantl return version >= llvm::VersionTuple(8); 2151e05d7b3SAdrian Prantl case Type::watchOS: 2161e05d7b3SAdrian Prantl case Type::WatchSimulator: 2171e05d7b3SAdrian Prantl return version >= llvm::VersionTuple(6); 2181e05d7b3SAdrian Prantl default: 2191e05d7b3SAdrian Prantl return false; 2201e05d7b3SAdrian Prantl } 2211e05d7b3SAdrian Prantl 2221e05d7b3SAdrian Prantl return false; 2231e05d7b3SAdrian Prantl } 2241e05d7b3SAdrian Prantl 225dec1c94eSAdrian Prantl bool XcodeSDK::SupportsSwift() const { 226dec1c94eSAdrian Prantl XcodeSDK::Info info = Parse(); 227dec1c94eSAdrian Prantl switch (info.type) { 228dec1c94eSAdrian Prantl case Type::MacOSX: 229dec1c94eSAdrian Prantl return info.version.empty() || info.version >= llvm::VersionTuple(10, 10); 230dec1c94eSAdrian Prantl case Type::iPhoneOS: 231dec1c94eSAdrian Prantl case Type::iPhoneSimulator: 232dec1c94eSAdrian Prantl return info.version.empty() || info.version >= llvm::VersionTuple(8); 233dec1c94eSAdrian Prantl case Type::AppleTVSimulator: 234dec1c94eSAdrian Prantl case Type::AppleTVOS: 235dec1c94eSAdrian Prantl return info.version.empty() || info.version >= llvm::VersionTuple(9); 236dec1c94eSAdrian Prantl case Type::WatchSimulator: 237dec1c94eSAdrian Prantl case Type::watchOS: 238dec1c94eSAdrian Prantl return info.version.empty() || info.version >= llvm::VersionTuple(2); 239dec1c94eSAdrian Prantl case Type::Linux: 240dec1c94eSAdrian Prantl return true; 241dec1c94eSAdrian Prantl default: 242dec1c94eSAdrian Prantl return false; 243dec1c94eSAdrian Prantl } 244dec1c94eSAdrian Prantl } 245dec1c94eSAdrian Prantl 2461e05d7b3SAdrian Prantl bool XcodeSDK::SDKSupportsModules(XcodeSDK::Type desired_type, 2471e05d7b3SAdrian Prantl const FileSpec &sdk_path) { 2481e05d7b3SAdrian Prantl ConstString last_path_component = sdk_path.GetLastPathComponent(); 2491e05d7b3SAdrian Prantl 2504356aa20SAdrian Prantl if (!last_path_component) 2511e05d7b3SAdrian Prantl return false; 2521e05d7b3SAdrian Prantl 2534356aa20SAdrian Prantl XcodeSDK sdk(last_path_component.GetStringRef().str()); 2544356aa20SAdrian Prantl if (sdk.GetType() != desired_type) 2551e05d7b3SAdrian Prantl return false; 2564356aa20SAdrian Prantl return SDKSupportsModules(sdk.GetType(), sdk.GetVersion()); 2571e05d7b3SAdrian Prantl } 2586e95d51eSAdrian Prantl 2596e95d51eSAdrian Prantl XcodeSDK::Type XcodeSDK::GetSDKTypeForTriple(const llvm::Triple &triple) { 2606e95d51eSAdrian Prantl using namespace llvm; 2616e95d51eSAdrian Prantl switch (triple.getOS()) { 2626e95d51eSAdrian Prantl case Triple::MacOSX: 2636e95d51eSAdrian Prantl case Triple::Darwin: 2646e95d51eSAdrian Prantl return XcodeSDK::MacOSX; 2656e95d51eSAdrian Prantl case Triple::IOS: 2666e95d51eSAdrian Prantl switch (triple.getEnvironment()) { 2676e95d51eSAdrian Prantl case Triple::MacABI: 2686e95d51eSAdrian Prantl return XcodeSDK::MacOSX; 2696e95d51eSAdrian Prantl case Triple::Simulator: 2706e95d51eSAdrian Prantl return XcodeSDK::iPhoneSimulator; 2716e95d51eSAdrian Prantl default: 2726e95d51eSAdrian Prantl return XcodeSDK::iPhoneOS; 2736e95d51eSAdrian Prantl } 2746e95d51eSAdrian Prantl case Triple::TvOS: 2756e95d51eSAdrian Prantl if (triple.getEnvironment() == Triple::Simulator) 2766e95d51eSAdrian Prantl return XcodeSDK::AppleTVSimulator; 2776e95d51eSAdrian Prantl return XcodeSDK::AppleTVOS; 2786e95d51eSAdrian Prantl case Triple::WatchOS: 2796e95d51eSAdrian Prantl if (triple.getEnvironment() == Triple::Simulator) 2806e95d51eSAdrian Prantl return XcodeSDK::WatchSimulator; 2816e95d51eSAdrian Prantl return XcodeSDK::watchOS; 2826e95d51eSAdrian Prantl case Triple::Linux: 2836e95d51eSAdrian Prantl return XcodeSDK::Linux; 2846e95d51eSAdrian Prantl default: 2856e95d51eSAdrian Prantl return XcodeSDK::unknown; 2866e95d51eSAdrian Prantl } 2876e95d51eSAdrian Prantl } 288