| 1 | //===-- XcodeSDKTest.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-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | |
| 9 | #include "gtest/gtest.h" |
| 10 | |
| 11 | #include "lldb/Utility/FileSpec.h" |
| 12 | #include "lldb/Utility/XcodeSDK.h" |
| 13 | |
| 14 | #include "llvm/ADT/StringRef.h" |
| 15 | #include "llvm/TargetParser/Triple.h" |
| 16 | |
| 17 | #include <tuple> |
| 18 | |
| 19 | using namespace lldb_private; |
| 20 | |
| 21 | TEST(XcodeSDKTest, ParseTest) { |
| 22 | EXPECT_EQ(XcodeSDK::GetAnyMacOS().GetType(), XcodeSDK::MacOSX); |
| 23 | EXPECT_EQ(XcodeSDK("MacOSX.sdk" ).GetType(), XcodeSDK::MacOSX); |
| 24 | EXPECT_EQ(XcodeSDK("iPhoneSimulator.sdk" ).GetType(), XcodeSDK::iPhoneSimulator); |
| 25 | EXPECT_EQ(XcodeSDK("iPhoneOS.sdk" ).GetType(), XcodeSDK::iPhoneOS); |
| 26 | EXPECT_EQ(XcodeSDK("AppleTVSimulator.sdk" ).GetType(), XcodeSDK::AppleTVSimulator); |
| 27 | EXPECT_EQ(XcodeSDK("AppleTVOS.sdk" ).GetType(), XcodeSDK::AppleTVOS); |
| 28 | EXPECT_EQ(XcodeSDK("WatchSimulator.sdk" ).GetType(), XcodeSDK::WatchSimulator); |
| 29 | EXPECT_EQ(XcodeSDK("WatchOS.sdk" ).GetType(), XcodeSDK::watchOS); |
| 30 | EXPECT_EQ(XcodeSDK("XRSimulator.sdk" ).GetType(), XcodeSDK::XRSimulator); |
| 31 | EXPECT_EQ(XcodeSDK("XROS.sdk" ).GetType(), XcodeSDK::XROS); |
| 32 | EXPECT_EQ(XcodeSDK("Linux.sdk" ).GetType(), XcodeSDK::Linux); |
| 33 | EXPECT_EQ(XcodeSDK("MacOSX.sdk" ).GetVersion(), llvm::VersionTuple()); |
| 34 | EXPECT_EQ(XcodeSDK("MacOSX10.9.sdk" ).GetVersion(), llvm::VersionTuple(10, 9)); |
| 35 | EXPECT_EQ(XcodeSDK("MacOSX10.15.4.sdk" ).GetVersion(), llvm::VersionTuple(10, 15)); |
| 36 | EXPECT_EQ(XcodeSDK("MacOSX.sdk" ).IsAppleInternalSDK(), false); |
| 37 | EXPECT_EQ( |
| 38 | XcodeSDK("MacOSX.sdk" , FileSpec{"/Path/To/MacOSX.sdk" }).GetSysroot(), |
| 39 | FileSpec("/Path/To/MacOSX.sdk" )); |
| 40 | EXPECT_EQ(XcodeSDK("MacOSX10.15.Internal.sdk" ).GetType(), XcodeSDK::MacOSX); |
| 41 | EXPECT_EQ(XcodeSDK("MacOSX10.15.Internal.sdk" ).GetVersion(), |
| 42 | llvm::VersionTuple(10, 15)); |
| 43 | EXPECT_EQ(XcodeSDK("MacOSX10.15.Internal.sdk" ).IsAppleInternalSDK(), true); |
| 44 | EXPECT_FALSE(XcodeSDK("MacOSX10.15.Internal.sdk" ).GetSysroot()); |
| 45 | EXPECT_EQ(XcodeSDK().GetType(), XcodeSDK::unknown); |
| 46 | EXPECT_EQ(XcodeSDK().GetVersion(), llvm::VersionTuple()); |
| 47 | EXPECT_FALSE(XcodeSDK().GetSysroot()); |
| 48 | } |
| 49 | |
| 50 | TEST(XcodeSDKTest, MergeTest) { |
| 51 | XcodeSDK sdk("MacOSX.sdk" ); |
| 52 | sdk.Merge(other: XcodeSDK("WatchOS.sdk" )); |
| 53 | // This doesn't make any particular sense and shouldn't happen in practice, we |
| 54 | // just want to guarantee a well-defined behavior when choosing one |
| 55 | // SDK to fit all CUs in an lldb::Module. |
| 56 | // -> The higher number wins. |
| 57 | EXPECT_EQ(sdk.GetType(), XcodeSDK::watchOS); |
| 58 | sdk.Merge(other: XcodeSDK("WatchOS1.1.sdk" )); |
| 59 | EXPECT_EQ(sdk.GetVersion(), llvm::VersionTuple(1, 1)); |
| 60 | sdk.Merge(other: XcodeSDK("WatchOS2.0.sdk" )); |
| 61 | EXPECT_EQ(sdk.GetVersion(), llvm::VersionTuple(2, 0)); |
| 62 | sdk.Merge(other: XcodeSDK("WatchOS1.1.Internal.sdk" )); |
| 63 | EXPECT_EQ(sdk.GetVersion(), llvm::VersionTuple(2, 0)); |
| 64 | EXPECT_EQ(sdk.IsAppleInternalSDK(), true); |
| 65 | XcodeSDK empty; |
| 66 | empty.Merge(other: XcodeSDK("MacOSX10.14.Internal.sdk" )); |
| 67 | EXPECT_EQ(empty.GetString(), llvm::StringRef("MacOSX10.14.Internal.sdk" )); |
| 68 | EXPECT_FALSE(empty.GetSysroot()); |
| 69 | empty.Merge(other: XcodeSDK("MacOSX9.5.Internal.sdk" , |
| 70 | FileSpec{"/Path/To/MacOSX9.5.Internal.sdk" })); |
| 71 | EXPECT_FALSE(empty.GetSysroot()); |
| 72 | empty.Merge(other: XcodeSDK("MacOSX12.5.sdk" , FileSpec{"/Path/To/MacOSX12.5.sdk" })); |
| 73 | EXPECT_EQ(empty.GetSysroot(), FileSpec{"/Path/To/MacOSX12.5.sdk" }); |
| 74 | empty.Merge(other: XcodeSDK("MacOSX11.5.Internal.sdk" , |
| 75 | FileSpec{"/Path/To/MacOSX11.5.Internal.sdk" })); |
| 76 | EXPECT_EQ(empty.GetSysroot(), FileSpec{"/Path/To/MacOSX12.5.Internal.sdk" }); |
| 77 | } |
| 78 | |
| 79 | #ifndef _WIN32 |
| 80 | TEST(XcodeSDKTest, SDKSupportsModules) { |
| 81 | std::string base = "/Applications/Xcode.app/Contents/Developer/Platforms/" ; |
| 82 | EXPECT_TRUE(XcodeSDK::SDKSupportsModules( |
| 83 | XcodeSDK::Type::iPhoneSimulator, |
| 84 | FileSpec( |
| 85 | base + |
| 86 | "iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator12.0.sdk" ))); |
| 87 | EXPECT_TRUE(XcodeSDK::SDKSupportsModules( |
| 88 | XcodeSDK::Type::iPhoneSimulator, |
| 89 | FileSpec(base + "iPhoneSimulator.platform/Developer/SDKs/" |
| 90 | "iPhoneSimulator12.0.Internal.sdk" ))); |
| 91 | EXPECT_FALSE(XcodeSDK::SDKSupportsModules( |
| 92 | XcodeSDK::Type::iPhoneSimulator, |
| 93 | FileSpec( |
| 94 | base + |
| 95 | "iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.2.sdk" ))); |
| 96 | EXPECT_TRUE(XcodeSDK::SDKSupportsModules( |
| 97 | XcodeSDK::Type::MacOSX, |
| 98 | FileSpec(base + "MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk" ))); |
| 99 | EXPECT_FALSE(XcodeSDK::SDKSupportsModules( |
| 100 | XcodeSDK::Type::MacOSX, |
| 101 | FileSpec(base + "MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk" ))); |
| 102 | } |
| 103 | #endif |
| 104 | |
| 105 | TEST(XcodeSDKTest, SDKSupportsSwift) { |
| 106 | EXPECT_TRUE(XcodeSDK("iPhoneSimulator12.0.sdk" ).SupportsSwift()); |
| 107 | EXPECT_TRUE(XcodeSDK("iPhoneSimulator12.0.Internal.sdk" ).SupportsSwift()); |
| 108 | EXPECT_FALSE(XcodeSDK("iPhoneSimulator7.2.sdk" ).SupportsSwift()); |
| 109 | EXPECT_TRUE(XcodeSDK("MacOSX10.10.sdk" ).SupportsSwift()); |
| 110 | EXPECT_FALSE(XcodeSDK("MacOSX10.9.sdk" ).SupportsSwift()); |
| 111 | EXPECT_TRUE(XcodeSDK("Linux.sdk" ).SupportsSwift()); |
| 112 | EXPECT_TRUE(XcodeSDK("MacOSX.sdk" ).SupportsSwift()); |
| 113 | EXPECT_FALSE(XcodeSDK("EverythingElse.sdk" ).SupportsSwift()); |
| 114 | } |
| 115 | |
| 116 | TEST(XcodeSDKTest, GetCanonicalNameAndConstruct) { |
| 117 | XcodeSDK::Info info; |
| 118 | info.type = XcodeSDK::Type::MacOSX; |
| 119 | EXPECT_EQ("macosx" , XcodeSDK::GetCanonicalName(info)); |
| 120 | EXPECT_EQ(XcodeSDK(info).Parse(), info); |
| 121 | |
| 122 | info.type = XcodeSDK::Type::iPhoneSimulator; |
| 123 | EXPECT_EQ("iphonesimulator" , XcodeSDK::GetCanonicalName(info)); |
| 124 | EXPECT_EQ(XcodeSDK(info).Parse(), info); |
| 125 | |
| 126 | info.type = XcodeSDK::Type::iPhoneOS; |
| 127 | EXPECT_EQ("iphoneos" , XcodeSDK::GetCanonicalName(info)); |
| 128 | EXPECT_EQ(XcodeSDK(info).Parse(), info); |
| 129 | |
| 130 | info.type = XcodeSDK::Type::AppleTVSimulator; |
| 131 | EXPECT_EQ("appletvsimulator" , XcodeSDK::GetCanonicalName(info)); |
| 132 | EXPECT_EQ(XcodeSDK(info).Parse(), info); |
| 133 | |
| 134 | info.type = XcodeSDK::Type::AppleTVOS; |
| 135 | EXPECT_EQ("appletvos" , XcodeSDK::GetCanonicalName(info)); |
| 136 | EXPECT_EQ(XcodeSDK(info).Parse(), info); |
| 137 | |
| 138 | info.type = XcodeSDK::Type::WatchSimulator; |
| 139 | EXPECT_EQ("watchsimulator" , XcodeSDK::GetCanonicalName(info)); |
| 140 | EXPECT_EQ(XcodeSDK(info).Parse(), info); |
| 141 | |
| 142 | info.type = XcodeSDK::Type::watchOS; |
| 143 | EXPECT_EQ("watchos" , XcodeSDK::GetCanonicalName(info)); |
| 144 | EXPECT_EQ(XcodeSDK(info).Parse(), info); |
| 145 | |
| 146 | info.type = XcodeSDK::Type::XRSimulator; |
| 147 | EXPECT_EQ("xrsimulator" , XcodeSDK::GetCanonicalName(info)); |
| 148 | EXPECT_EQ(XcodeSDK(info).Parse(), info); |
| 149 | |
| 150 | info.type = XcodeSDK::Type::XROS; |
| 151 | EXPECT_EQ("xros" , XcodeSDK::GetCanonicalName(info)); |
| 152 | EXPECT_EQ(XcodeSDK(info).Parse(), info); |
| 153 | |
| 154 | info.type = XcodeSDK::Type::Linux; |
| 155 | EXPECT_EQ("linux" , XcodeSDK::GetCanonicalName(info)); |
| 156 | EXPECT_EQ(XcodeSDK(info).Parse(), info); |
| 157 | |
| 158 | info.type = XcodeSDK::Type::unknown; |
| 159 | EXPECT_EQ("" , XcodeSDK::GetCanonicalName(info)); |
| 160 | EXPECT_EQ(XcodeSDK(info).Parse(), info); |
| 161 | |
| 162 | info.internal = true; |
| 163 | info.type = XcodeSDK::Type::MacOSX; |
| 164 | EXPECT_EQ("macosx.internal" , XcodeSDK::GetCanonicalName(info)); |
| 165 | EXPECT_EQ(XcodeSDK(info).Parse(), info); |
| 166 | |
| 167 | info.type = XcodeSDK::Type::iPhoneSimulator; |
| 168 | EXPECT_EQ("iphonesimulator.internal" , XcodeSDK::GetCanonicalName(info)); |
| 169 | EXPECT_EQ(XcodeSDK(info).Parse(), info); |
| 170 | |
| 171 | info.type = XcodeSDK::Type::iPhoneOS; |
| 172 | EXPECT_EQ("iphoneos.internal" , XcodeSDK::GetCanonicalName(info)); |
| 173 | EXPECT_EQ(XcodeSDK(info).Parse(), info); |
| 174 | |
| 175 | info.type = XcodeSDK::Type::AppleTVSimulator; |
| 176 | EXPECT_EQ("appletvsimulator.internal" , XcodeSDK::GetCanonicalName(info)); |
| 177 | EXPECT_EQ(XcodeSDK(info).Parse(), info); |
| 178 | |
| 179 | info.type = XcodeSDK::Type::AppleTVOS; |
| 180 | EXPECT_EQ("appletvos.internal" , XcodeSDK::GetCanonicalName(info)); |
| 181 | EXPECT_EQ(XcodeSDK(info).Parse(), info); |
| 182 | |
| 183 | info.type = XcodeSDK::Type::WatchSimulator; |
| 184 | EXPECT_EQ("watchsimulator.internal" , XcodeSDK::GetCanonicalName(info)); |
| 185 | EXPECT_EQ(XcodeSDK(info).Parse(), info); |
| 186 | |
| 187 | info.type = XcodeSDK::Type::watchOS; |
| 188 | EXPECT_EQ("watchos.internal" , XcodeSDK::GetCanonicalName(info)); |
| 189 | EXPECT_EQ(XcodeSDK(info).Parse(), info); |
| 190 | |
| 191 | info.type = XcodeSDK::Type::XRSimulator; |
| 192 | EXPECT_EQ("xrsimulator.internal" , XcodeSDK::GetCanonicalName(info)); |
| 193 | EXPECT_EQ(XcodeSDK(info).Parse(), info); |
| 194 | |
| 195 | info.type = XcodeSDK::Type::XROS; |
| 196 | EXPECT_EQ("xros.internal" , XcodeSDK::GetCanonicalName(info)); |
| 197 | EXPECT_EQ(XcodeSDK(info).Parse(), info); |
| 198 | info.type = XcodeSDK::Type::MacOSX; |
| 199 | info.version = llvm::VersionTuple(10, 9); |
| 200 | EXPECT_EQ("macosx10.9.internal" , XcodeSDK::GetCanonicalName(info)); |
| 201 | EXPECT_EQ(XcodeSDK(info).Parse(), info); |
| 202 | |
| 203 | info.type = XcodeSDK::Type::iPhoneOS; |
| 204 | info.version = llvm::VersionTuple(7, 0); |
| 205 | EXPECT_EQ("iphoneos7.0.internal" , XcodeSDK::GetCanonicalName(info)); |
| 206 | EXPECT_EQ(XcodeSDK(info).Parse(), info); |
| 207 | } |
| 208 | |
| 209 | TEST(XcodeSDKTest, GetSDKTypeForTriple) { |
| 210 | EXPECT_EQ( |
| 211 | XcodeSDK::GetSDKTypeForTriple(llvm::Triple("x86_64-apple-macosx10.14" )), |
| 212 | XcodeSDK::Type::MacOSX); |
| 213 | EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple(llvm::Triple("x86_64-apple-darwin" )), |
| 214 | XcodeSDK::Type::MacOSX); |
| 215 | EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple( |
| 216 | llvm::Triple("x86_64-apple-ios13.4-simulator" )), |
| 217 | XcodeSDK::Type::iPhoneSimulator); |
| 218 | EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple(llvm::Triple("arm64-apple-ios13.4" )), |
| 219 | XcodeSDK::Type::iPhoneOS); |
| 220 | EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple( |
| 221 | llvm::Triple("x86_64-apple-ios13.4-macabi" )), |
| 222 | XcodeSDK::Type::MacOSX); |
| 223 | EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple( |
| 224 | llvm::Triple("x86_64-apple-tvos-simulator" )), |
| 225 | XcodeSDK::Type::AppleTVSimulator); |
| 226 | EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple(llvm::Triple("arm64-apple-tvos" )), |
| 227 | XcodeSDK::Type::AppleTVOS); |
| 228 | EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple( |
| 229 | llvm::Triple("x86_64-apple-watchos-simulator" )), |
| 230 | XcodeSDK::Type::WatchSimulator); |
| 231 | EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple(llvm::Triple("arm64-apple-watchos" )), |
| 232 | XcodeSDK::Type::watchOS); |
| 233 | EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple( |
| 234 | llvm::Triple("arm64e-apple-xros-simulator" )), |
| 235 | XcodeSDK::Type::XRSimulator); |
| 236 | EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple(llvm::Triple("arm64e-apple-xros" )), |
| 237 | XcodeSDK::Type::XROS); |
| 238 | EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple(llvm::Triple("x86_64-unknown-linux" )), |
| 239 | XcodeSDK::Type::Linux); |
| 240 | EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple(llvm::Triple("i386-unknown-netbsd" )), |
| 241 | XcodeSDK::Type::unknown); |
| 242 | } |
| 243 | |
| 244 | TEST(XcodeSDKTest, FindXcodeContentsDirectoryInPath) { |
| 245 | std::string standard = |
| 246 | "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/" |
| 247 | "Developer/SDKs/MacOSX.sdk" ; |
| 248 | EXPECT_EQ("/Applications/Xcode.app/Contents" , |
| 249 | XcodeSDK::FindXcodeContentsDirectoryInPath(standard)); |
| 250 | |
| 251 | std::string standard_version = |
| 252 | "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/" |
| 253 | "Developer/SDKs/MacOSX10.15.sdk" ; |
| 254 | EXPECT_EQ("/Applications/Xcode.app/Contents" , |
| 255 | XcodeSDK::FindXcodeContentsDirectoryInPath(standard_version)); |
| 256 | |
| 257 | std::string beta = "/Applications/Xcode-beta.app/Contents/Developer/" |
| 258 | "Platforms/MacOSX.platform/" |
| 259 | "Developer/SDKs/MacOSX10.15.sdk" ; |
| 260 | EXPECT_EQ("/Applications/Xcode-beta.app/Contents" , |
| 261 | XcodeSDK::FindXcodeContentsDirectoryInPath(beta)); |
| 262 | |
| 263 | std::string no_app = |
| 264 | "/Applications/Xcode/Contents/Developer/Platforms/MacOSX.platform/" |
| 265 | "Developer/SDKs/MacOSX10.15.sdk" ; |
| 266 | EXPECT_EQ("" , XcodeSDK::FindXcodeContentsDirectoryInPath(no_app)); |
| 267 | |
| 268 | std::string no_contents = |
| 269 | "/Applications/Xcode.app/Developer/Platforms/MacOSX.platform/" |
| 270 | "Developer/SDKs/MacOSX10.15.sdk" ; |
| 271 | EXPECT_EQ("" , XcodeSDK::FindXcodeContentsDirectoryInPath(no_contents)); |
| 272 | |
| 273 | std::string no_capitalization = |
| 274 | "/Applications/Xcode.app/contents/Developer/Platforms/MacOSX.platform/" |
| 275 | "Developer/SDKs/MacOSX10.15.sdk" ; |
| 276 | EXPECT_EQ("" , XcodeSDK::FindXcodeContentsDirectoryInPath(no_capitalization)); |
| 277 | } |
| 278 | |