This revision was automatically updated to reflect the committed changes.
Closed by commit rG79feafa5147a: Add an internal bit to the XcodeSDK class.
(authored by aprantl).
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.
Changed prior to commit:
https://reviews.llvm.org/D78675?vs=259614&id=259973#toc
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D78675/new/
https://reviews.llvm.org/D78675
Files:
lldb/include/lldb/Utility/XcodeSDK.h
lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
lldb/source/Utility/XcodeSDK.cpp
lldb/unittests/Host/HostInfoTest.cpp
lldb/unittests/Utility/XcodeSDKTest.cpp
Index: lldb/unittests/Utility/XcodeSDKTest.cpp
===================================================================
--- lldb/unittests/Utility/XcodeSDKTest.cpp
+++ lldb/unittests/Utility/XcodeSDKTest.cpp
@@ -30,6 +30,11 @@
EXPECT_EQ(XcodeSDK("MacOSX.sdk").GetVersion(), llvm::VersionTuple());
EXPECT_EQ(XcodeSDK("MacOSX10.9.sdk").GetVersion(), llvm::VersionTuple(10, 9));
EXPECT_EQ(XcodeSDK("MacOSX10.15.4.sdk").GetVersion(), llvm::VersionTuple(10, 15));
+ EXPECT_EQ(XcodeSDK("MacOSX.sdk").IsAppleInternalSDK(), false);
+ EXPECT_EQ(XcodeSDK("MacOSX10.15.Internal.sdk").GetType(), XcodeSDK::MacOSX);
+ EXPECT_EQ(XcodeSDK("MacOSX10.15.Internal.sdk").GetVersion(),
+ llvm::VersionTuple(10, 15));
+ EXPECT_EQ(XcodeSDK("MacOSX10.15.Internal.sdk").IsAppleInternalSDK(), true);
EXPECT_EQ(XcodeSDK().GetType(), XcodeSDK::unknown);
EXPECT_EQ(XcodeSDK().GetVersion(), llvm::VersionTuple());
}
@@ -46,6 +51,12 @@
EXPECT_EQ(sdk.GetVersion(), llvm::VersionTuple(1, 1));
sdk.Merge(XcodeSDK("WatchOS2.0.sdk"));
EXPECT_EQ(sdk.GetVersion(), llvm::VersionTuple(2, 0));
+ sdk.Merge(XcodeSDK("WatchOS1.1.Internal.sdk"));
+ EXPECT_EQ(sdk.GetVersion(), llvm::VersionTuple(2, 0));
+ EXPECT_EQ(sdk.IsAppleInternalSDK(), true);
+ XcodeSDK empty;
+ empty.Merge(XcodeSDK("MacOSX10.14.Internal.sdk"));
+ EXPECT_EQ(empty.GetString(), llvm::StringRef("MacOSX10.14.Internal.sdk"));
}
TEST(XcodeSDKTest, SDKSupportsModules) {
@@ -55,6 +66,10 @@
FileSpec(
base +
"iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator12.0.sdk")));
+ EXPECT_TRUE(XcodeSDK::SDKSupportsModules(
+ XcodeSDK::Type::iPhoneSimulator,
+ FileSpec(base + "iPhoneSimulator.platform/Developer/SDKs/"
+ "iPhoneSimulator12.0.Internal.sdk")));
EXPECT_FALSE(XcodeSDK::SDKSupportsModules(
XcodeSDK::Type::iPhoneSimulator,
FileSpec(
@@ -68,19 +83,65 @@
FileSpec(base + "MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk")));
}
-TEST(XcodeSDKTest, GetSDKNameForType) {
- EXPECT_EQ("macosx", XcodeSDK::GetSDKNameForType(XcodeSDK::Type::MacOSX));
- EXPECT_EQ("iphonesimulator",
- XcodeSDK::GetSDKNameForType(XcodeSDK::Type::iPhoneSimulator));
- EXPECT_EQ("iphoneos", XcodeSDK::GetSDKNameForType(XcodeSDK::Type::iPhoneOS));
- EXPECT_EQ("appletvsimulator",
- XcodeSDK::GetSDKNameForType(XcodeSDK::Type::AppleTVSimulator));
- EXPECT_EQ("appletvos",
- XcodeSDK::GetSDKNameForType(XcodeSDK::Type::AppleTVOS));
- EXPECT_EQ("watchsimulator",
- XcodeSDK::GetSDKNameForType(XcodeSDK::Type::WatchSimulator));
- EXPECT_EQ("watchos", XcodeSDK::GetSDKNameForType(XcodeSDK::Type::watchOS));
- EXPECT_EQ("linux", XcodeSDK::GetSDKNameForType(XcodeSDK::Type::Linux));
- EXPECT_EQ("", XcodeSDK::GetSDKNameForType(XcodeSDK::Type::numSDKTypes));
- EXPECT_EQ("", XcodeSDK::GetSDKNameForType(XcodeSDK::Type::unknown));
+TEST(XcodeSDKTest, GetCanonicalName) {
+ XcodeSDK::Info info;
+ info.type = XcodeSDK::Type::MacOSX;
+ EXPECT_EQ("macosx", XcodeSDK::GetCanonicalName(info));
+
+ info.type = XcodeSDK::Type::iPhoneSimulator;
+ EXPECT_EQ("iphonesimulator", XcodeSDK::GetCanonicalName(info));
+
+ info.type = XcodeSDK::Type::iPhoneOS;
+ EXPECT_EQ("iphoneos", XcodeSDK::GetCanonicalName(info));
+
+ info.type = XcodeSDK::Type::AppleTVSimulator;
+ EXPECT_EQ("appletvsimulator", XcodeSDK::GetCanonicalName(info));
+
+ info.type = XcodeSDK::Type::AppleTVOS;
+ EXPECT_EQ("appletvos", XcodeSDK::GetCanonicalName(info));
+
+ info.type = XcodeSDK::Type::WatchSimulator;
+ EXPECT_EQ("watchsimulator", XcodeSDK::GetCanonicalName(info));
+
+ info.type = XcodeSDK::Type::watchOS;
+ EXPECT_EQ("watchos", XcodeSDK::GetCanonicalName(info));
+
+ info.type = XcodeSDK::Type::Linux;
+ EXPECT_EQ("linux", XcodeSDK::GetCanonicalName(info));
+
+ info.type = XcodeSDK::Type::numSDKTypes;
+ EXPECT_EQ("", XcodeSDK::GetCanonicalName(info));
+
+ info.type = XcodeSDK::Type::unknown;
+ EXPECT_EQ("", XcodeSDK::GetCanonicalName(info));
+
+ info.internal = true;
+ info.type = XcodeSDK::Type::MacOSX;
+ EXPECT_EQ("macosx.internal", XcodeSDK::GetCanonicalName(info));
+
+ info.type = XcodeSDK::Type::iPhoneSimulator;
+ EXPECT_EQ("iphonesimulator.internal", XcodeSDK::GetCanonicalName(info));
+
+ info.type = XcodeSDK::Type::iPhoneOS;
+ EXPECT_EQ("iphoneos.internal", XcodeSDK::GetCanonicalName(info));
+
+ info.type = XcodeSDK::Type::AppleTVSimulator;
+ EXPECT_EQ("appletvsimulator.internal", XcodeSDK::GetCanonicalName(info));
+
+ info.type = XcodeSDK::Type::AppleTVOS;
+ EXPECT_EQ("appletvos.internal", XcodeSDK::GetCanonicalName(info));
+
+ info.type = XcodeSDK::Type::WatchSimulator;
+ EXPECT_EQ("watchsimulator.internal", XcodeSDK::GetCanonicalName(info));
+
+ info.type = XcodeSDK::Type::watchOS;
+ EXPECT_EQ("watchos.internal", XcodeSDK::GetCanonicalName(info));
+
+ info.type = XcodeSDK::Type::MacOSX;
+ info.version = llvm::VersionTuple(10, 9);
+ EXPECT_EQ("macosx10.9.internal", XcodeSDK::GetCanonicalName(info));
+
+ info.type = XcodeSDK::Type::iPhoneOS;
+ info.version = llvm::VersionTuple(7, 0);
+ EXPECT_EQ("iphoneos7.0.internal", XcodeSDK::GetCanonicalName(info));
}
Index: lldb/unittests/Host/HostInfoTest.cpp
===================================================================
--- lldb/unittests/Host/HostInfoTest.cpp
+++ lldb/unittests/Host/HostInfoTest.cpp
@@ -50,3 +50,13 @@
std::string s("abc");
EXPECT_TRUE(HostInfo::GetHostname(s));
}
+
+#if defined(__APPLE__)
+TEST_F(HostInfoTest, GetXcodeSDK) {
+ EXPECT_FALSE(HostInfo::GetXcodeSDK(XcodeSDK("MacOSX.sdk")).empty());
+ // These are expected to fall back to an available version.
+ EXPECT_FALSE(HostInfo::GetXcodeSDK(XcodeSDK("MacOSX9999.sdk")).empty());
+ // This is expected to fail.
+ EXPECT_TRUE(HostInfo::GetXcodeSDK(XcodeSDK("CeciNestPasUnOS.sdk")).empty());
+}
+#endif
Index: lldb/source/Utility/XcodeSDK.cpp
===================================================================
--- lldb/source/Utility/XcodeSDK.cpp
+++ lldb/source/Utility/XcodeSDK.cpp
@@ -64,13 +64,24 @@
return version;
}
+static bool ParseAppleInternalSDK(llvm::StringRef &name) {
+ return name.consume_front("Internal.");
+}
+
+XcodeSDK::Info XcodeSDK::Parse() const {
+ XcodeSDK::Info info;
+ llvm::StringRef input(m_name);
+ info.type = ParseSDKName(input);
+ info.version = ParseSDKVersion(input);
+ info.internal = ParseAppleInternalSDK(input);
+ return info;
+}
-std::tuple<XcodeSDK::Type, llvm::VersionTuple> XcodeSDK::Parse() const {
+bool XcodeSDK::IsAppleInternalSDK() const {
llvm::StringRef input(m_name);
- XcodeSDK::Type sdk = ParseSDKName(input);
- llvm::VersionTuple version = ParseSDKVersion(input);
- return std::make_tuple<XcodeSDK::Type, llvm::VersionTuple>(
- std::move(sdk), std::move(version));
+ ParseSDKName(input);
+ ParseSDKVersion(input);
+ return ParseAppleInternalSDK(input);
}
llvm::VersionTuple XcodeSDK::GetVersion() const {
@@ -86,37 +97,64 @@
llvm::StringRef XcodeSDK::GetString() const { return m_name; }
+bool XcodeSDK::Info::operator<(const Info &other) const {
+ return std::tie(type, version, internal) <
+ std::tie(other.type, other.version, other.internal);
+}
void XcodeSDK::Merge(XcodeSDK other) {
// The "bigger" SDK always wins.
- if (Parse() < other.Parse())
+ auto l = Parse();
+ auto r = other.Parse();
+ if (l < r)
*this = other;
+ else {
+ // The Internal flag always wins.
+ if (llvm::StringRef(m_name).endswith(".sdk"))
+ if (!l.internal && r.internal)
+ m_name =
+ m_name.substr(0, m_name.size() - 3) + std::string("Internal.sdk");
+ }
}
-llvm::StringRef XcodeSDK::GetSDKNameForType(XcodeSDK::Type type) {
- switch (type) {
+std::string XcodeSDK::GetCanonicalName(XcodeSDK::Info info) {
+ std::string name;
+ switch (info.type) {
case MacOSX:
- return "macosx";
+ name = "macosx";
+ break;
case iPhoneSimulator:
- return "iphonesimulator";
+ name = "iphonesimulator";
+ break;
case iPhoneOS:
- return "iphoneos";
+ name = "iphoneos";
+ break;
case AppleTVSimulator:
- return "appletvsimulator";
+ name = "appletvsimulator";
+ break;
case AppleTVOS:
- return "appletvos";
+ name = "appletvos";
+ break;
case WatchSimulator:
- return "watchsimulator";
+ name = "watchsimulator";
+ break;
case watchOS:
- return "watchos";
+ name = "watchos";
+ break;
case bridgeOS:
- return "bridgeos";
+ name = "bridgeos";
+ break;
case Linux:
- return "linux";
+ name = "linux";
+ break;
case numSDKTypes:
case unknown:
- return "";
+ return {};
}
- llvm_unreachable("unhandled switch case");
+ if (!info.version.empty())
+ name += info.version.getAsString();
+ if (info.internal)
+ name += ".internal";
+ return name;
}
bool XcodeSDK::SDKSupportsModules(XcodeSDK::Type sdk_type,
@@ -147,12 +185,15 @@
const llvm::StringRef sdk_name = last_path_component.GetStringRef();
const std::string sdk_name_lower = sdk_name.lower();
- const llvm::StringRef sdk_string = GetSDKNameForType(desired_type);
+ Info info;
+ info.type = desired_type;
+ const llvm::StringRef sdk_string = GetCanonicalName(info);
if (!llvm::StringRef(sdk_name_lower).startswith(sdk_string))
return false;
auto version_part = sdk_name.drop_front(sdk_string.size());
version_part.consume_back(".sdk");
+ version_part.consume_back(".Internal");
llvm::VersionTuple version;
if (version.tryParse(version_part))
Index: lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
===================================================================
--- lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
+++ lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
@@ -298,37 +298,66 @@
}
std::string HostInfoMacOSX::GetXcodeSDK(XcodeSDK sdk) {
- std::string xcrun_cmd = "xcrun --show-sdk-path --sdk " +
- XcodeSDK::GetSDKNameForType(sdk.GetType()).str();
- llvm::VersionTuple version = sdk.GetVersion();
- if (!version.empty())
- xcrun_cmd += version.getAsString();
-
- int status = 0;
- int signo = 0;
- std::string output_str;
- lldb_private::Status error =
- Host::RunShellCommand(xcrun_cmd.c_str(), FileSpec(), &status, &signo,
- &output_str, std::chrono::seconds(15));
-
- // Check that xcrun return something useful.
- if (status != 0 || output_str.empty())
- return {};
-
- // Convert to a StringRef so we can manipulate the string without modifying
- // the underlying data.
- llvm::StringRef output(output_str);
-
- // Remove any trailing newline characters.
- output = output.rtrim();
+ XcodeSDK::Info info = sdk.Parse();
+ std::string sdk_name = XcodeSDK::GetCanonicalName(info);
+ auto find_sdk = [](std::string sdk_name) -> std::string {
+ std::string xcrun_cmd = "xcrun --show-sdk-path --sdk " + sdk_name;
+ int status = 0;
+ int signo = 0;
+ std::string output_str;
+ lldb_private::Status error =
+ Host::RunShellCommand(xcrun_cmd.c_str(), FileSpec(), &status, &signo,
+ &output_str, std::chrono::seconds(15));
+
+ // Check that xcrun return something useful.
+ if (status != 0 || output_str.empty())
+ return {};
+
+ // Convert to a StringRef so we can manipulate the string without modifying
+ // the underlying data.
+ llvm::StringRef output(output_str);
+
+ // Remove any trailing newline characters.
+ output = output.rtrim();
+
+ // Strip any leading newline characters and everything before them.
+ const size_t last_newline = output.rfind('\n');
+ if (last_newline != llvm::StringRef::npos)
+ output = output.substr(last_newline + 1);
+
+ return output.str();
+ };
+
+ std::string path = find_sdk(sdk_name);
+ while (path.empty()) {
+ // Try an alternate spelling of the name ("macosx10.9internal").
+ if (info.type == XcodeSDK::Type::MacOSX && !info.version.empty() &&
+ info.internal) {
+ llvm::StringRef fixed(sdk_name);
+ if (fixed.consume_back(".internal"))
+ sdk_name = fixed.str() + "internal";
+ path = find_sdk(sdk_name);
+ if (!path.empty())
+ break;
+ }
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ LLDB_LOGF(log, "Couldn't find SDK %s on host", sdk_name.c_str());
+
+ // Try without the version.
+ if (!info.version.empty()) {
+ info.version = {};
+ sdk_name = XcodeSDK::GetCanonicalName(info);
+ path = find_sdk(sdk_name);
+ if (!path.empty())
+ break;
+ }
- // Strip any leading newline characters and everything before them.
- const size_t last_newline = output.rfind('\n');
- if (last_newline != llvm::StringRef::npos)
- output = output.substr(last_newline + 1);
+ LLDB_LOGF(log, "Couldn't find any matching SDK on host");
+ return {};
+ }
// Whatever is left in output should be a valid path.
- if (!FileSystem::Instance().Exists(output))
+ if (!FileSystem::Instance().Exists(path))
return {};
- return output.str();
+ return path;
}
Index: lldb/include/lldb/Utility/XcodeSDK.h
===================================================================
--- lldb/include/lldb/Utility/XcodeSDK.h
+++ lldb/include/lldb/Utility/XcodeSDK.h
@@ -22,6 +22,9 @@
public:
XcodeSDK() = default;
+ /// Initialize an XcodeSDK object with an SDK name. The SDK name is the last
+ /// directory component of a path one would pass to clang's -isysroot
+ /// parameter. For example, "MacOSX.10.14.sdk".
XcodeSDK(std::string &&name) : m_name(std::move(name)) {}
static XcodeSDK GetAnyMacOS() { return XcodeSDK("MacOSX.sdk"); }
@@ -38,7 +41,6 @@
numSDKTypes,
unknown = -1
};
- static llvm::StringRef GetNameForType(Type type);
/// The merge function follows a strict order to maintain monotonicity:
/// 1. SDK with the higher SDKType wins.
@@ -49,15 +51,27 @@
XcodeSDK(const XcodeSDK&) = default;
bool operator==(XcodeSDK other);
- /// Return parsed SDK number, and SDK version number.
- std::tuple<Type, llvm::VersionTuple> Parse() const;
+ /// A parsed SDK directory name.
+ struct Info {
+ Type type = unknown;
+ llvm::VersionTuple version;
+ bool internal = false;
+
+ Info() = default;
+ bool operator<(const Info &other) const;
+ };
+
+ /// Return parsed SDK type and version number.
+ Info Parse() const;
+ bool IsAppleInternalSDK() const;
llvm::VersionTuple GetVersion() const;
Type GetType() const;
llvm::StringRef GetString() const;
static bool SDKSupportsModules(Type type, llvm::VersionTuple version);
static bool SDKSupportsModules(Type desired_type, const FileSpec &sdk_path);
- static llvm::StringRef GetSDKNameForType(Type type);
+ /// Return the canonical SDK name, such as "macosx" for the macOS SDK.
+ static std::string GetCanonicalName(Info info);
};
} // namespace lldb_private
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits