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