Index: lldb/include/lldb/Host/HostInfoBase.h =================================================================== --- lldb/include/lldb/Host/HostInfoBase.h +++ lldb/include/lldb/Host/HostInfoBase.h @@ -92,6 +92,9 @@ static bool ComputePathRelativeToLibrary(FileSpec &file_spec, llvm::StringRef dir); + static FileSpec GetXcodeContentsDirectory() { return {}; } + static FileSpec GetXcodeDeveloperDirectory() { return {}; } + /// Return the directory containing a specific Xcode SDK. static llvm::StringRef GetXcodeSDKPath(XcodeSDK sdk) { return {}; } Index: lldb/include/lldb/Host/macosx/HostInfoMacOSX.h =================================================================== --- lldb/include/lldb/Host/macosx/HostInfoMacOSX.h +++ lldb/include/lldb/Host/macosx/HostInfoMacOSX.h @@ -32,7 +32,8 @@ static bool GetOSBuildString(std::string &s); static bool GetOSKernelDescription(std::string &s); static FileSpec GetProgramFileSpec(); - static std::string FindXcodeContentsDirectoryInPath(llvm::StringRef path); + static FileSpec GetXcodeContentsDirectory(); + static FileSpec GetXcodeDeveloperDirectory(); /// Query xcrun to find an Xcode SDK directory. static llvm::StringRef GetXcodeSDKPath(XcodeSDK sdk); Index: lldb/include/lldb/Utility/XcodeSDK.h =================================================================== --- lldb/include/lldb/Utility/XcodeSDK.h +++ lldb/include/lldb/Utility/XcodeSDK.h @@ -87,6 +87,8 @@ static std::string GetCanonicalName(Info info); /// Return the best-matching SDK type for a specific triple. static XcodeSDK::Type GetSDKTypeForTriple(const llvm::Triple &triple); + + static std::string FindXcodeContentsDirectoryInPath(llvm::StringRef path); }; } // namespace lldb_private Index: lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm =================================================================== --- lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm +++ lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm @@ -297,6 +297,63 @@ } } +FileSpec HostInfoMacOSX::GetXcodeContentsDirectory() { + static FileSpec g_xcode_contents_path; + static std::once_flag g_once_flag; + std::call_once(g_once_flag, [&]() { + // Try the shlib dir first. + if (FileSpec fspec = HostInfo::GetShlibDir()) { + if (FileSystem::Instance().Exists(fspec)) { + std::string xcode_contents_dir = + XcodeSDK::FindXcodeContentsDirectoryInPath(fspec.GetPath()); + if (!xcode_contents_dir.empty()) { + g_xcode_contents_path = FileSpec(xcode_contents_dir); + return; + } + } + } + + if (const char *developer_dir_env_var = getenv("DEVELOPER_DIR")) { + FileSpec fspec(developer_dir_env_var); + if (FileSystem::Instance().Exists(fspec)) { + // FIXME: This looks like it couldn't possibly work! + std::string xcode_contents_dir = + XcodeSDK::FindXcodeContentsDirectoryInPath(fspec.GetPath()); + if (!xcode_contents_dir.empty()) { + g_xcode_contents_path = FileSpec(xcode_contents_dir); + return; + } + } + } + + FileSpec fspec(HostInfo::GetXcodeSDKPath(XcodeSDK::GetAnyMacOS())); + if (fspec) { + if (FileSystem::Instance().Exists(fspec)) { + std::string xcode_contents_dir = + XcodeSDK::FindXcodeContentsDirectoryInPath(fspec.GetPath()); + if (!xcode_contents_dir.empty()) { + g_xcode_contents_path = FileSpec(xcode_contents_dir); + return; + } + } + } + }); + return g_xcode_contents_path; +} + +lldb_private::FileSpec HostInfoMacOSX::GetXcodeDeveloperDirectory() { + static lldb_private::FileSpec g_developer_directory; + static llvm::once_flag g_once_flag; + llvm::call_once(g_once_flag, []() { + if (FileSpec fspec = GetXcodeContentsDirectory()) { + fspec.AppendPathComponent("Developer"); + if (FileSystem::Instance().Exists(fspec)) + g_developer_directory = fspec; + } + }); + return g_developer_directory; +} + static std::string GetXcodeSDK(XcodeSDK sdk) { XcodeSDK::Info info = sdk.Parse(); std::string sdk_name = XcodeSDK::GetCanonicalName(info); Index: lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp =================================================================== --- lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp +++ lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp @@ -15,6 +15,7 @@ #include #include #include "lldb/Host/PseudoTerminal.h" +#include "lldb/Host/HostInfo.h" #include "lldb/Target/Process.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Status.h" @@ -77,7 +78,7 @@ // simulator PlatformAppleSimulator::LoadCoreSimulator(); - std::string developer_dir = GetXcodeDeveloperDirectory().GetPath(); + std::string developer_dir = HostInfo::GetXcodeDeveloperDirectory().GetPath(); CoreSimulatorSupport::DeviceSet devices = CoreSimulatorSupport::DeviceSet::GetAvailableDevices( developer_dir.c_str()); @@ -124,7 +125,7 @@ const char *arg_cstr = args.GetArgumentAtIndex(0); if (arg_cstr) { std::string arg_str(arg_cstr); - std::string developer_dir = GetXcodeDeveloperDirectory().GetPath(); + std::string developer_dir = HostInfo::GetXcodeDeveloperDirectory().GetPath(); CoreSimulatorSupport::DeviceSet devices = CoreSimulatorSupport::DeviceSet::GetAvailableDevices( developer_dir.c_str()); @@ -214,7 +215,7 @@ #if defined(__APPLE__) std::lock_guard guard(m_core_sim_path_mutex); if (!m_core_simulator_framework_path.hasValue()) { - if (FileSpec fspec = GetXcodeDeveloperDirectory()) { + if (FileSpec fspec = HostInfo::GetXcodeDeveloperDirectory()) { std::string developer_dir = fspec.GetPath(); StreamString cs_path; cs_path.Printf( @@ -247,7 +248,7 @@ if (!m_device.hasValue()) { const CoreSimulatorSupport::DeviceType::ProductFamilyID dev_id = CoreSimulatorSupport::DeviceType::ProductFamilyID::iPhone; - std::string developer_dir = GetXcodeDeveloperDirectory().GetPath(); + std::string developer_dir = HostInfo::GetXcodeDeveloperDirectory().GetPath(); m_device = CoreSimulatorSupport::DeviceSet::GetAvailableDevices( developer_dir.c_str()) .GetFanciest(dev_id); Index: lldb/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp =================================================================== --- lldb/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp +++ lldb/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp @@ -255,7 +255,7 @@ const char *PlatformAppleTVSimulator::GetSDKDirectoryAsCString() { std::lock_guard guard(m_sdk_dir_mutex); if (m_sdk_directory.empty()) { - if (FileSpec fspec = GetXcodeDeveloperDirectory()) { + if (FileSpec fspec = HostInfo::GetXcodeDeveloperDirectory()) { std::string developer_dir = fspec.GetPath(); char sdks_directory[PATH_MAX]; char sdk_dirname[PATH_MAX]; Index: lldb/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp =================================================================== --- lldb/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp +++ lldb/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp @@ -255,7 +255,7 @@ const char *PlatformAppleWatchSimulator::GetSDKDirectoryAsCString() { std::lock_guard guard(m_sdk_dir_mutex); if (m_sdk_directory.empty()) { - if (FileSpec fspec = GetXcodeDeveloperDirectory()) { + if (FileSpec fspec = HostInfo::GetXcodeDeveloperDirectory()) { std::string developer_dir = fspec.GetPath(); char sdks_directory[PATH_MAX]; char sdk_dirname[PATH_MAX]; Index: lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h =================================================================== --- lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h +++ lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h @@ -89,9 +89,6 @@ llvm::Expected FetchExtendedCrashInformation(lldb_private::Process &process) override; - static lldb_private::FileSpec GetXcodeContentsDirectory(); - static lldb_private::FileSpec GetXcodeDeveloperDirectory(); - /// Return the toolchain directory the current LLDB instance is located in. static lldb_private::FileSpec GetCurrentToolchainDirectory(); @@ -165,7 +162,6 @@ static std::string FindComponentInPath(llvm::StringRef path, llvm::StringRef component); - static std::string FindXcodeContentsDirectoryInPath(llvm::StringRef path); std::string m_developer_directory; llvm::StringMap m_sdk_path; Index: lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp =================================================================== --- lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp +++ lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp @@ -1133,19 +1133,6 @@ return g_xcode_select_filespec; } -lldb_private::FileSpec PlatformDarwin::GetXcodeDeveloperDirectory() { - static lldb_private::FileSpec g_developer_directory; - static llvm::once_flag g_once_flag; - llvm::call_once(g_once_flag, []() { - if (FileSpec fspec = GetXcodeContentsDirectory()) { - fspec.AppendPathComponent("Developer"); - if (FileSystem::Instance().Exists(fspec)) - g_developer_directory = fspec; - } - }); - return g_developer_directory; -} - BreakpointSP PlatformDarwin::SetThreadCreationBreakpoint(Target &target) { BreakpointSP bp_sp; static const char *g_bp_names[] = { @@ -1260,7 +1247,7 @@ } FileSpec PlatformDarwin::GetSDKDirectoryForModules(XcodeSDK::Type sdk_type) { - FileSpec sdks_spec = GetXcodeContentsDirectory(); + FileSpec sdks_spec = HostInfo::GetXcodeContentsDirectory(); sdks_spec.AppendPathComponent("Developer"); sdks_spec.AppendPathComponent("Platforms"); @@ -1586,7 +1573,7 @@ llvm::call_once(g_once_flag, []() { // When locating executables, trust the DEVELOPER_DIR first if it is set - FileSpec xcode_contents_dir = GetXcodeContentsDirectory(); + FileSpec xcode_contents_dir = HostInfo::GetXcodeContentsDirectory(); if (xcode_contents_dir) { FileSpec xcode_lldb_resources = xcode_contents_dir; xcode_lldb_resources.AppendPathComponent("SharedFrameworks"); @@ -1738,72 +1725,6 @@ return {}; } -std::string -PlatformDarwin::FindXcodeContentsDirectoryInPath(llvm::StringRef path) { - auto begin = llvm::sys::path::begin(path); - auto end = llvm::sys::path::end(path); - - // Iterate over the path components until we find something that ends with - // .app. If the next component is Contents then we've found the Contents - // directory. - for (auto it = begin; it != end; ++it) { - if (it->endswith(".app")) { - auto next = it; - if (++next != end && *next == "Contents") { - llvm::SmallString<128> buffer; - llvm::sys::path::append(buffer, begin, ++next, - llvm::sys::path::Style::posix); - return buffer.str().str(); - } - } - } - - return {}; -} - -FileSpec PlatformDarwin::GetXcodeContentsDirectory() { - static FileSpec g_xcode_contents_path; - static std::once_flag g_once_flag; - std::call_once(g_once_flag, [&]() { - // Try the shlib dir first. - if (FileSpec fspec = HostInfo::GetShlibDir()) { - if (FileSystem::Instance().Exists(fspec)) { - std::string xcode_contents_dir = - FindXcodeContentsDirectoryInPath(fspec.GetPath()); - if (!xcode_contents_dir.empty()) { - g_xcode_contents_path = FileSpec(xcode_contents_dir); - return; - } - } - } - - if (const char *developer_dir_env_var = getenv("DEVELOPER_DIR")) { - FileSpec fspec(developer_dir_env_var); - if (FileSystem::Instance().Exists(fspec)) { - std::string xcode_contents_dir = - FindXcodeContentsDirectoryInPath(fspec.GetPath()); - if (!xcode_contents_dir.empty()) { - g_xcode_contents_path = FileSpec(xcode_contents_dir); - return; - } - } - } - - FileSpec fspec(HostInfo::GetXcodeSDKPath(XcodeSDK::GetAnyMacOS())); - if (fspec) { - if (FileSystem::Instance().Exists(fspec)) { - std::string xcode_contents_dir = - FindXcodeContentsDirectoryInPath(fspec.GetPath()); - if (!xcode_contents_dir.empty()) { - g_xcode_contents_path = FileSpec(xcode_contents_dir); - return; - } - } - } - }); - return g_xcode_contents_path; -} - FileSpec PlatformDarwin::GetCurrentToolchainDirectory() { if (FileSpec fspec = HostInfo::GetShlibDir()) return FileSpec(FindComponentInPath(fspec.GetPath(), ".xctoolchain")); Index: lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp =================================================================== --- lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp +++ lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp @@ -17,6 +17,7 @@ #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" #include "lldb/Host/Host.h" +#include "lldb/Host/HostInfo.h" #include "lldb/Interpreter/OptionValueFileSpecList.h" #include "lldb/Interpreter/OptionValueProperties.h" #include "lldb/Interpreter/Property.h" @@ -327,7 +328,7 @@ // DeveloperDirectory is something like // "/Applications/Xcode.app/Contents/Developer" - std::string developer_dir = GetXcodeDeveloperDirectory().GetPath(); + std::string developer_dir = HostInfo::GetXcodeDeveloperDirectory().GetPath(); if (developer_dir.empty()) developer_dir = "/Applications/Xcode.app/Contents/Developer"; Index: lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp =================================================================== --- lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp +++ lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp @@ -197,7 +197,7 @@ return {}; // First try to find an SDK that matches the given SDK version. - if (FileSpec fspec = GetXcodeContentsDirectory()) { + if (FileSpec fspec = HostInfo::GetXcodeContentsDirectory()) { StreamString sdk_path; sdk_path.Printf("%s/Developer/Platforms/MacOSX.platform/Developer/" "SDKs/MacOSX%u.%u.sdk", Index: lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp =================================================================== --- lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp +++ lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp @@ -15,6 +15,7 @@ #include "lldb/Core/PluginManager.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" +#include "lldb/Host/HostInfo.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Utility/FileSpec.h" @@ -342,7 +343,7 @@ const char *PlatformRemoteDarwinDevice::GetDeviceSupportDirectory() { std::string platform_dir = "/Platforms/" + GetPlatformName() + "/DeviceSupport"; if (m_device_support_directory.empty()) { - if (FileSpec fspec = GetXcodeDeveloperDirectory()) { + if (FileSpec fspec = HostInfo::GetXcodeDeveloperDirectory()) { m_device_support_directory = fspec.GetPath(); m_device_support_directory.append(platform_dir.c_str()); } else { Index: lldb/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp =================================================================== --- lldb/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp +++ lldb/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp @@ -260,7 +260,7 @@ const char *PlatformiOSSimulator::GetSDKDirectoryAsCString() { std::lock_guard guard(m_sdk_dir_mutex); if (m_sdk_directory.empty()) { - if (FileSpec fspec = GetXcodeDeveloperDirectory()) { + if (FileSpec fspec = HostInfo::GetXcodeDeveloperDirectory()) { std::string developer_dir = fspec.GetPath(); char sdks_directory[PATH_MAX]; char sdk_dirname[PATH_MAX]; Index: lldb/source/Utility/XcodeSDK.cpp =================================================================== --- lldb/source/Utility/XcodeSDK.cpp +++ lldb/source/Utility/XcodeSDK.cpp @@ -285,3 +285,25 @@ return XcodeSDK::unknown; } } + +std::string XcodeSDK::FindXcodeContentsDirectoryInPath(llvm::StringRef path) { + auto begin = llvm::sys::path::begin(path); + auto end = llvm::sys::path::end(path); + + // Iterate over the path components until we find something that ends with + // .app. If the next component is Contents then we've found the Contents + // directory. + for (auto it = begin; it != end; ++it) { + if (it->endswith(".app")) { + auto next = it; + if (++next != end && *next == "Contents") { + llvm::SmallString<128> buffer; + llvm::sys::path::append(buffer, begin, ++next, + llvm::sys::path::Style::posix); + return buffer.str().str(); + } + } + } + + return {}; +} Index: lldb/unittests/Platform/PlatformDarwinTest.cpp =================================================================== --- lldb/unittests/Platform/PlatformDarwinTest.cpp +++ lldb/unittests/Platform/PlatformDarwinTest.cpp @@ -20,7 +20,6 @@ struct PlatformDarwinTester : public PlatformDarwin { public: using PlatformDarwin::FindComponentInPath; - using PlatformDarwin::FindXcodeContentsDirectoryInPath; }; TEST(PlatformDarwinTest, TestParseVersionBuildDir) { @@ -51,44 +50,6 @@ EXPECT_EQ(llvm::VersionTuple(3, 4, 5), V); } -TEST(PlatformDarwinTest, FindXcodeContentsDirectoryInPath) { - std::string standard = - "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/" - "Developer/SDKs/MacOSX.sdk"; - EXPECT_EQ("/Applications/Xcode.app/Contents", - PlatformDarwinTester::FindXcodeContentsDirectoryInPath(standard)); - - std::string standard_version = - "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/" - "Developer/SDKs/MacOSX10.15.sdk"; - EXPECT_EQ( - "/Applications/Xcode.app/Contents", - PlatformDarwinTester::FindXcodeContentsDirectoryInPath(standard_version)); - - std::string beta = "/Applications/Xcode-beta.app/Contents/Developer/" - "Platforms/MacOSX.platform/" - "Developer/SDKs/MacOSX10.15.sdk"; - EXPECT_EQ("/Applications/Xcode-beta.app/Contents", - PlatformDarwinTester::FindXcodeContentsDirectoryInPath(beta)); - - std::string no_app = - "/Applications/Xcode/Contents/Developer/Platforms/MacOSX.platform/" - "Developer/SDKs/MacOSX10.15.sdk"; - EXPECT_EQ("", PlatformDarwinTester::FindXcodeContentsDirectoryInPath(no_app)); - - std::string no_contents = - "/Applications/Xcode.app/Developer/Platforms/MacOSX.platform/" - "Developer/SDKs/MacOSX10.15.sdk"; - EXPECT_EQ( - "", PlatformDarwinTester::FindXcodeContentsDirectoryInPath(no_contents)); - - std::string no_capitalization = - "/Applications/Xcode.app/contents/Developer/Platforms/MacOSX.platform/" - "Developer/SDKs/MacOSX10.15.sdk"; - EXPECT_EQ("", PlatformDarwinTester::FindXcodeContentsDirectoryInPath( - no_capitalization)); -} - TEST(PlatformDarwinTest, FindComponentInPath) { EXPECT_EQ("/path/to/foo", PlatformDarwinTester::FindComponentInPath("/path/to/foo/", "foo")); Index: lldb/unittests/Utility/XcodeSDKTest.cpp =================================================================== --- lldb/unittests/Utility/XcodeSDKTest.cpp +++ lldb/unittests/Utility/XcodeSDKTest.cpp @@ -204,3 +204,38 @@ EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple(llvm::Triple("i386-unknown-netbsd")), XcodeSDK::Type::unknown); } + +TEST(XcodeSDKTest, FindXcodeContentsDirectoryInPath) { + std::string standard = + "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/" + "Developer/SDKs/MacOSX.sdk"; + EXPECT_EQ("/Applications/Xcode.app/Contents", + XcodeSDK::FindXcodeContentsDirectoryInPath(standard)); + + std::string standard_version = + "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/" + "Developer/SDKs/MacOSX10.15.sdk"; + EXPECT_EQ("/Applications/Xcode.app/Contents", + XcodeSDK::FindXcodeContentsDirectoryInPath(standard_version)); + + std::string beta = "/Applications/Xcode-beta.app/Contents/Developer/" + "Platforms/MacOSX.platform/" + "Developer/SDKs/MacOSX10.15.sdk"; + EXPECT_EQ("/Applications/Xcode-beta.app/Contents", + XcodeSDK::FindXcodeContentsDirectoryInPath(beta)); + + std::string no_app = + "/Applications/Xcode/Contents/Developer/Platforms/MacOSX.platform/" + "Developer/SDKs/MacOSX10.15.sdk"; + EXPECT_EQ("", XcodeSDK::FindXcodeContentsDirectoryInPath(no_app)); + + std::string no_contents = + "/Applications/Xcode.app/Developer/Platforms/MacOSX.platform/" + "Developer/SDKs/MacOSX10.15.sdk"; + EXPECT_EQ("", XcodeSDK::FindXcodeContentsDirectoryInPath(no_contents)); + + std::string no_capitalization = + "/Applications/Xcode.app/contents/Developer/Platforms/MacOSX.platform/" + "Developer/SDKs/MacOSX10.15.sdk"; + EXPECT_EQ("", XcodeSDK::FindXcodeContentsDirectoryInPath(no_capitalization)); +}