Skip to content

Commit 0638570

Browse files
committed
HostInfoMacOS: Add a utility function for finding an SDK-specific tool
This is an API needed by swift-lldb. https://reviews.llvm.org/D151591 (cherry picked from commit 7ba3383702f4da4af739a9199dce4d08f8c496ce)
1 parent 4ef0fda commit 0638570

File tree

4 files changed

+76
-22
lines changed

4 files changed

+76
-22
lines changed

lldb/include/lldb/Host/HostInfoBase.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "lldb/Utility/XcodeSDK.h"
1717
#include "lldb/lldb-enumerations.h"
1818
#include "llvm/ADT/StringRef.h"
19+
#include "llvm/Support/Errc.h"
1920

2021
#include <cstdint>
2122

@@ -133,6 +134,12 @@ class HostInfoBase {
133134
return llvm::make_error<HostInfoError>("cannot determine SDK root");
134135
}
135136

137+
/// Return the path to a specific tool in the specified Xcode SDK.
138+
static llvm::Expected<llvm::StringRef> FindSDKTool(XcodeSDK sdk,
139+
llvm::StringRef tool) {
140+
return llvm::errorCodeToError(llvm::errc::no_such_file_or_directory);
141+
}
142+
136143
/// Return information about module \p image_name if it is loaded in
137144
/// the current process's address space.
138145
static SharedCacheImageInfo

lldb/include/lldb/Host/macosx/HostInfoMacOSX.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "lldb/Host/posix/HostInfoPosix.h"
1313
#include "lldb/Utility/FileSpec.h"
1414
#include "lldb/Utility/XcodeSDK.h"
15+
#include "llvm/ADT/StringRef.h"
1516
#include "llvm/Support/VersionTuple.h"
1617

1718
namespace lldb_private {
@@ -51,8 +52,9 @@ class HostInfoMacOSX : public HostInfoPosix {
5152
FileSpec &file_spec, bool verify);
5253
#endif
5354

54-
/// Query xcrun to find an Xcode SDK directory.
5555
static llvm::Expected<llvm::StringRef> GetSDKRoot(SDKOptions options);
56+
static llvm::Expected<llvm::StringRef> FindSDKTool(XcodeSDK sdk,
57+
llvm::StringRef tool);
5658

5759
/// Shared cache utilities
5860
static SharedCacheImageInfo

lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm

Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -522,41 +522,69 @@ static void ParseOSVersion(llvm::VersionTuple &version, NSString *Key) {
522522
return path;
523523
}
524524

525-
llvm::Expected<llvm::StringRef> HostInfoMacOSX::GetSDKRoot(SDKOptions options) {
526-
struct ErrorOrPath {
527-
std::string str;
528-
bool is_error;
529-
};
530-
static llvm::StringMap<ErrorOrPath> g_sdk_path;
531-
static std::mutex g_sdk_path_mutex;
525+
namespace {
526+
struct ErrorOrPath {
527+
std::string str;
528+
bool is_error;
529+
};
530+
} // namespace
532531

533-
std::lock_guard<std::mutex> guard(g_sdk_path_mutex);
532+
static llvm::Expected<llvm::StringRef>
533+
find_cached_path(llvm::StringMap<ErrorOrPath> &cache, std::mutex &mutex,
534+
llvm::StringRef key,
535+
std::function<llvm::Expected<std::string>(void)> compute) {
536+
std::lock_guard<std::mutex> guard(mutex);
534537
LLDB_SCOPED_TIMER();
535538

536-
if (!options.XcodeSDK)
537-
return llvm::createStringError(llvm::inconvertibleErrorCode(),
538-
"XCodeSDK not specified");
539-
XcodeSDK sdk = *options.XcodeSDK;
540-
541-
auto key = sdk.GetString();
542-
auto it = g_sdk_path.find(key);
543-
if (it != g_sdk_path.end()) {
539+
auto it = cache.find(key);
540+
if (it != cache.end()) {
544541
if (it->second.is_error)
545542
return llvm::createStringError(llvm::inconvertibleErrorCode(),
546543
it->second.str);
547-
else
548-
return it->second.str;
544+
return it->second.str;
549545
}
550-
auto path_or_err = GetXcodeSDK(sdk);
546+
auto path_or_err = compute();
551547
if (!path_or_err) {
552548
std::string error = toString(path_or_err.takeError());
553-
g_sdk_path.insert({key, {error, true}});
549+
cache.insert({key, {error, true}});
554550
return llvm::createStringError(llvm::inconvertibleErrorCode(), error);
555551
}
556-
auto it_new = g_sdk_path.insert({key, {*path_or_err, false}});
552+
auto it_new = cache.insert({key, {*path_or_err, false}});
557553
return it_new.first->second.str;
558554
}
559555

556+
llvm::Expected<llvm::StringRef> HostInfoMacOSX::GetSDKRoot(SDKOptions options) {
557+
static llvm::StringMap<ErrorOrPath> g_sdk_path;
558+
static std::mutex g_sdk_path_mutex;
559+
if (!options.XcodeSDK)
560+
return llvm::createStringError(llvm::inconvertibleErrorCode(),
561+
"XCodeSDK not specified");
562+
XcodeSDK sdk = *options.XcodeSDK;
563+
auto key = sdk.GetString();
564+
return find_cached_path(g_sdk_path, g_sdk_path_mutex, key, [&](){
565+
return GetXcodeSDK(sdk);
566+
});
567+
}
568+
569+
llvm::Expected<llvm::StringRef>
570+
HostInfoMacOSX::FindSDKTool(XcodeSDK sdk, llvm::StringRef tool) {
571+
static llvm::StringMap<ErrorOrPath> g_tool_path;
572+
static std::mutex g_tool_path_mutex;
573+
std::string key;
574+
llvm::raw_string_ostream(key) << sdk.GetString() << ":" << tool;
575+
return find_cached_path(
576+
g_tool_path, g_tool_path_mutex, key,
577+
[&]() -> llvm::Expected<std::string> {
578+
std::string sdk_name = XcodeSDK::GetCanonicalName(sdk.Parse());
579+
if (sdk_name.empty())
580+
return llvm::createStringError(llvm::inconvertibleErrorCode(),
581+
"Unrecognized SDK type: " +
582+
sdk.GetString());
583+
llvm::SmallVector<llvm::StringRef, 2> find = {"-find", tool};
584+
return xcrun(sdk_name, find);
585+
});
586+
}
587+
560588
namespace {
561589
struct dyld_shared_cache_dylib_text_info {
562590
uint64_t version; // current version 1

lldb/unittests/Host/HostInfoTest.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,23 @@ TEST_F(HostInfoTest, GetXcodeSDK) {
7373
// This is expected to fail.
7474
EXPECT_TRUE(get_sdk("CeciNestPasUnOS.sdk", true).empty());
7575
}
76+
77+
TEST_F(HostInfoTest, FindSDKTool) {
78+
auto find_tool = [](std::string sdk, llvm::StringRef tool,
79+
bool error = false) -> llvm::StringRef {
80+
auto sdk_path_or_err =
81+
HostInfo::FindSDKTool(XcodeSDK(std::move(sdk)), tool);
82+
if (!error) {
83+
EXPECT_TRUE((bool)sdk_path_or_err);
84+
return *sdk_path_or_err;
85+
}
86+
EXPECT_FALSE((bool)sdk_path_or_err);
87+
llvm::consumeError(sdk_path_or_err.takeError());
88+
return {};
89+
};
90+
EXPECT_FALSE(find_tool("MacOSX.sdk", "clang").empty());
91+
EXPECT_TRUE(find_tool("MacOSX.sdk", "CeciNestPasUnOutil").empty());
92+
}
7693
#endif
7794

7895
TEST(HostInfoTestInitialization, InitTwice) {

0 commit comments

Comments
 (0)