brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.4 KiB · 89e05de Raw
314 lines · cpp
1//===-- XcodeSDK.cpp ------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "lldb/Utility/XcodeSDK.h"10#include "lldb/Utility/FileSpec.h"11 12#include "lldb/lldb-types.h"13 14#include "llvm/TargetParser/Triple.h"15 16#include <string>17 18using namespace lldb;19using namespace lldb_private;20 21static llvm::StringRef GetName(XcodeSDK::Type type) {22  switch (type) {23  case XcodeSDK::MacOSX:24    return "MacOSX";25  case XcodeSDK::iPhoneSimulator:26    return "iPhoneSimulator";27  case XcodeSDK::iPhoneOS:28    return "iPhoneOS";29  case XcodeSDK::AppleTVSimulator:30    return "AppleTVSimulator";31  case XcodeSDK::AppleTVOS:32    return "AppleTVOS";33  case XcodeSDK::WatchSimulator:34    return "WatchSimulator";35  case XcodeSDK::watchOS:36    return "WatchOS";37  case XcodeSDK::XRSimulator:38    return "XRSimulator";39  case XcodeSDK::XROS:40    return "XROS";41  case XcodeSDK::BridgeOS:42    return "BridgeOS";43  case XcodeSDK::Linux:44    return "Linux";45  case XcodeSDK::unknown:46    return {};47  }48  llvm_unreachable("Unhandled sdk type!");49}50 51XcodeSDK::XcodeSDK(XcodeSDK::Info info) : m_name(GetName(info.type).str()) {52  if (!m_name.empty()) {53    if (!info.version.empty())54      m_name += info.version.getAsString();55    if (info.internal)56      m_name += ".Internal";57    m_name += ".sdk";58  }59}60 61XcodeSDK &XcodeSDK::operator=(const XcodeSDK &other) = default;62 63bool XcodeSDK::operator==(const XcodeSDK &other) const {64  return m_name == other.m_name;65}66 67static XcodeSDK::Type ParseSDKName(llvm::StringRef &name) {68  if (name.consume_front("MacOSX"))69    return XcodeSDK::MacOSX;70  if (name.consume_front("iPhoneSimulator"))71    return XcodeSDK::iPhoneSimulator;72  if (name.consume_front("iPhoneOS"))73    return XcodeSDK::iPhoneOS;74  if (name.consume_front("AppleTVSimulator"))75    return XcodeSDK::AppleTVSimulator;76  if (name.consume_front("AppleTVOS"))77    return XcodeSDK::AppleTVOS;78  if (name.consume_front("WatchSimulator"))79    return XcodeSDK::WatchSimulator;80  if (name.consume_front("WatchOS"))81    return XcodeSDK::watchOS;82  if (name.consume_front("XRSimulator"))83    return XcodeSDK::XRSimulator;84  if (name.consume_front("XROS"))85    return XcodeSDK::XROS;86  if (name.consume_front("BridgeOS"))87    return XcodeSDK::BridgeOS;88  if (name.consume_front("Linux"))89    return XcodeSDK::Linux;90  static_assert(XcodeSDK::Linux == XcodeSDK::numSDKTypes - 1,91                "New SDK type was added, update this list!");92  return XcodeSDK::unknown;93}94 95static llvm::VersionTuple ParseSDKVersion(llvm::StringRef &name) {96  unsigned i = 0;97  while (i < name.size() && name[i] >= '0' && name[i] <= '9')98    ++i;99  if (i == name.size() || name[i++] != '.')100    return {};101  while (i < name.size() && name[i] >= '0' && name[i] <= '9')102    ++i;103  if (i == name.size() || name[i++] != '.')104    return {};105 106  llvm::VersionTuple version;107  version.tryParse(name.slice(0, i - 1));108  name = name.drop_front(i);109  return version;110}111 112static bool ParseAppleInternalSDK(llvm::StringRef &name) {113  return name.consume_front("Internal.") || name.consume_front(".Internal.");114}115 116XcodeSDK::Info XcodeSDK::Parse() const {117  XcodeSDK::Info info;118  llvm::StringRef input(m_name);119  info.type = ParseSDKName(input);120  info.version = ParseSDKVersion(input);121  info.internal = ParseAppleInternalSDK(input);122  return info;123}124 125bool XcodeSDK::IsAppleInternalSDK() const {126  llvm::StringRef input(m_name);127  ParseSDKName(input);128  ParseSDKVersion(input);129  return ParseAppleInternalSDK(input);130}131 132llvm::VersionTuple XcodeSDK::GetVersion() const {133  llvm::StringRef input(m_name);134  ParseSDKName(input);135  return ParseSDKVersion(input);136}137 138XcodeSDK::Type XcodeSDK::GetType() const {139  llvm::StringRef input(m_name);140  return ParseSDKName(input);141}142 143llvm::StringRef XcodeSDK::GetString() const { return m_name; }144 145const FileSpec &XcodeSDK::GetSysroot() const { return m_sysroot; }146 147bool XcodeSDK::Info::operator<(const Info &other) const {148  return std::tie(type, version, internal) <149         std::tie(other.type, other.version, other.internal);150}151 152bool XcodeSDK::Info::operator==(const Info &other) const {153  return std::tie(type, version, internal) ==154         std::tie(other.type, other.version, other.internal);155}156 157void XcodeSDK::Merge(const XcodeSDK &other) {158  // The "bigger" SDK always wins.159  auto l = Parse();160  auto r = other.Parse();161  if (l < r)162    *this = other;163  else {164    // The Internal flag always wins.165    if (!l.internal && r.internal) {166      if (llvm::StringRef(m_name).ends_with(".sdk"))167        m_name =168            m_name.substr(0, m_name.size() - 3) + std::string("Internal.sdk");169    }170  }171 172  // We changed the SDK name. Adjust the sysroot accordingly.173  if (m_sysroot && m_sysroot.GetFilename().GetStringRef() != m_name)174    m_sysroot.SetFilename(m_name);175}176 177std::string XcodeSDK::GetCanonicalName(XcodeSDK::Info info) {178  std::string name;179  switch (info.type) {180  case MacOSX:181    name = "macosx";182    break;183  case iPhoneSimulator:184    name = "iphonesimulator";185    break;186  case iPhoneOS:187    name = "iphoneos";188    break;189  case AppleTVSimulator:190    name = "appletvsimulator";191    break;192  case AppleTVOS:193    name = "appletvos";194    break;195  case WatchSimulator:196    name = "watchsimulator";197    break;198  case watchOS:199    name = "watchos";200    break;201  case XRSimulator:202    name = "xrsimulator";203    break;204  case XROS:205    name = "xros";206    break;207  case BridgeOS:208    name = "bridgeos";209    break;210  case Linux:211    name = "linux";212    break;213  case unknown:214    return {};215  }216  if (!info.version.empty())217    name += info.version.getAsString();218  if (info.internal)219    name += ".internal";220  return name;221}222 223bool XcodeSDK::SDKSupportsModules(XcodeSDK::Type sdk_type,224                                  llvm::VersionTuple version) {225  switch (sdk_type) {226  case Type::MacOSX:227    return version >= llvm::VersionTuple(10, 10);228  case Type::iPhoneOS:229  case Type::iPhoneSimulator:230  case Type::AppleTVOS:231  case Type::AppleTVSimulator:232    return version >= llvm::VersionTuple(8);233  case Type::watchOS:234  case Type::WatchSimulator:235    return version >= llvm::VersionTuple(6);236  case Type::XROS:237  case Type::XRSimulator:238    return true;239  default:240    return false;241  }242 243  return false;244}245 246bool XcodeSDK::SDKSupportsModules(XcodeSDK::Type desired_type,247                                  const FileSpec &sdk_path) {248  ConstString last_path_component = sdk_path.GetFilename();249 250  if (!last_path_component)251    return false;252 253  XcodeSDK sdk(last_path_component.GetStringRef().str());254  if (sdk.GetType() != desired_type)255    return false;256  return SDKSupportsModules(sdk.GetType(), sdk.GetVersion());257}258 259XcodeSDK::Type XcodeSDK::GetSDKTypeForTriple(const llvm::Triple &triple) {260  using namespace llvm;261  switch (triple.getOS()) {262  case Triple::MacOSX:263  case Triple::Darwin:264    return XcodeSDK::MacOSX;265  case Triple::IOS:266    switch (triple.getEnvironment()) {267    case Triple::MacABI:268      return XcodeSDK::MacOSX;269    case Triple::Simulator:270      return XcodeSDK::iPhoneSimulator;271    default:272      return XcodeSDK::iPhoneOS;273    }274  case Triple::TvOS:275    if (triple.getEnvironment() == Triple::Simulator)276      return XcodeSDK::AppleTVSimulator;277    return XcodeSDK::AppleTVOS;278  case Triple::WatchOS:279    if (triple.getEnvironment() == Triple::Simulator)280      return XcodeSDK::WatchSimulator;281    return XcodeSDK::watchOS;282  case Triple::XROS:283    if (triple.getEnvironment() == Triple::Simulator)284      return XcodeSDK::XRSimulator;285    return XcodeSDK::XROS;286  case Triple::Linux:287    return XcodeSDK::Linux;288  default:289    return XcodeSDK::unknown;290  }291}292 293std::string XcodeSDK::FindXcodeContentsDirectoryInPath(llvm::StringRef path) {294  auto begin = llvm::sys::path::begin(path);295  auto end = llvm::sys::path::end(path);296 297  // Iterate over the path components until we find something that ends with298  // .app. If the next component is Contents then we've found the Contents299  // directory.300  for (auto it = begin; it != end; ++it) {301    if (it->ends_with(".app")) {302      auto next = it;303      if (++next != end && *next == "Contents") {304        llvm::SmallString<128> buffer;305        llvm::sys::path::append(buffer, begin, ++next,306                                llvm::sys::path::Style::posix);307        return buffer.str().str();308      }309    }310  }311 312  return {};313}314