-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathprobe_sysroot.cppm
More file actions
75 lines (65 loc) · 2.79 KB
/
probe_sysroot.cppm
File metadata and controls
75 lines (65 loc) · 2.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// mcpp.fallback.probe_sysroot — sysroot detection strategies.
//
// Three strategies for discovering the sysroot:
// 1. Remap GCC's baked-in build-time sysroot to the local xpkgs layout
// 2. Parse Clang's .cfg file for --sysroot=
// 3. macOS: use xcrun to discover the SDK path
module;
#include <cstdlib>
export module mcpp.fallback.probe_sysroot;
import std;
import mcpp.xlings;
import mcpp.platform;
import mcpp.log;
export namespace mcpp::fallback {
// When GCC reports a sysroot ending in "subos/default" that doesn't exist
// on the current machine (baked build-time path), remap it to the
// equivalent sysroot relative to the compiler's own xpkgs directory.
std::optional<std::filesystem::path>
remap_xlings_baked_sysroot(std::string_view reportedPath,
const std::filesystem::path& compilerBin) {
if (reportedPath.empty()) return std::nullopt;
if (!reportedPath.ends_with("subos/default")) return std::nullopt;
if (std::filesystem::exists(std::string(reportedPath))) return std::nullopt;
if (auto xpkgs = mcpp::xlings::paths::xpkgs_from_compiler(compilerBin)) {
// xpkgs is <registry>/data/xpkgs -> registry = xpkgs/../..
auto registrySysroot = xpkgs->parent_path().parent_path()
/ "subos" / "default";
if (std::filesystem::exists(registrySysroot / "usr" / "include"))
return registrySysroot;
}
return std::nullopt;
}
// Parse a Clang .cfg file alongside the compiler binary for --sysroot=.
std::optional<std::filesystem::path>
parse_clang_cfg_sysroot(const std::filesystem::path& compilerBin) {
auto stem = compilerBin.stem().string();
auto cfgPath = compilerBin.parent_path() / (stem + ".cfg");
if (!std::filesystem::exists(cfgPath)) return std::nullopt;
std::ifstream ifs(cfgPath);
std::string line;
while (std::getline(ifs, line)) {
constexpr std::string_view prefix = "--sysroot=";
if (line.starts_with(prefix)) {
// Trim whitespace
auto val = std::string(line.substr(prefix.size()));
while (!val.empty() && (val.back() == '\n' || val.back() == '\r' || val.back() == ' '))
val.pop_back();
while (!val.empty() && (val.front() == '\n' || val.front() == '\r' || val.front() == ' '))
val.erase(val.begin());
if (!val.empty() && std::filesystem::exists(val))
return std::filesystem::path(val);
}
}
return std::nullopt;
}
// macOS fallback: use xcrun to discover the SDK path.
std::optional<std::filesystem::path>
probe_macos_sdk_sysroot() {
auto sdk = mcpp::platform::macos::sdk_path();
if (sdk) {
mcpp::log::verbose("probe", std::format("sysroot (macOS SDK): {}", sdk->string()));
}
return sdk;
}
} // namespace mcpp::fallback