-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathgcc.cppm
More file actions
126 lines (104 loc) · 4.28 KB
/
gcc.cppm
File metadata and controls
126 lines (104 loc) · 4.28 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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// mcpp.toolchain.gcc - GCC-family compiler behavior.
export module mcpp.toolchain.gcc;
import std;
import mcpp.toolchain.model;
import mcpp.toolchain.probe;
import mcpp.xlings;
export namespace mcpp::toolchain::gcc {
bool matches_version_output(std::string_view firstLineLower);
std::string parse_version(std::string_view firstLine);
std::optional<std::filesystem::path> find_std_module_source(
const std::filesystem::path& cxx_binary,
std::string_view version);
void enrich_toolchain(Toolchain& tc);
std::optional<std::filesystem::path>
find_binutils_bin(const std::filesystem::path& compilerBin);
std::filesystem::path std_bmi_path(const std::filesystem::path& cacheDir);
std::filesystem::path staged_std_bmi_path(const std::filesystem::path& outputDir);
std::string std_module_build_command(const Toolchain& tc,
const std::filesystem::path& cacheDir,
std::string_view sysrootFlag,
std::string_view cppStandardFlag);
} // namespace mcpp::toolchain::gcc
namespace mcpp::toolchain::gcc {
bool matches_version_output(std::string_view firstLineLower) {
return firstLineLower.find("g++") != std::string::npos
|| firstLineLower.find("gcc") != std::string::npos;
}
std::string parse_version(std::string_view firstLine) {
std::string head(firstLine);
auto rpos = head.find_last_of("0123456789");
if (rpos != std::string::npos) {
std::size_t lpos = rpos;
while (lpos > 0
&& (std::isdigit(static_cast<unsigned char>(head[lpos - 1]))
|| head[lpos - 1] == '.')) {
--lpos;
}
auto version = head.substr(lpos, rpos - lpos + 1);
if (!version.empty()) return version;
}
return mcpp::toolchain::extract_version(firstLine);
}
std::optional<std::filesystem::path> find_std_module_source(
const std::filesystem::path& cxx_binary,
std::string_view version)
{
auto root = cxx_binary.parent_path().parent_path();
auto p = root / "include" / "c++" / std::string(version) / "bits" / "std.cc";
if (std::filesystem::exists(p)) return p;
auto cmd = std::format("'{}' -print-file-name=libstdc++.so 2>/dev/null",
cxx_binary.string());
auto r = mcpp::toolchain::run_capture(cmd);
if (r) {
auto trimmed = mcpp::toolchain::trim_line(*r);
if (!trimmed.empty()) {
std::filesystem::path libpath = trimmed;
auto root2 = libpath.parent_path().parent_path();
auto p2 = root2 / "include" / "c++" / std::string(version) / "bits" / "std.cc";
if (std::filesystem::exists(p2)) return p2;
}
}
return std::nullopt;
}
void enrich_toolchain(Toolchain& tc) {
tc.stdlibId = "libstdc++";
tc.stdlibVersion = tc.version;
if (auto p = find_std_module_source(tc.binaryPath, tc.version)) {
tc.stdModuleSource = *p;
tc.hasImportStd = true;
}
}
std::optional<std::filesystem::path>
find_binutils_bin(const std::filesystem::path& compilerBin) {
if (auto as = mcpp::xlings::paths::find_sibling_binary(
compilerBin, "binutils", "bin/as")) {
return as->parent_path();
}
return std::nullopt;
}
std::filesystem::path std_bmi_path(const std::filesystem::path& cacheDir) {
return cacheDir / "gcm.cache" / "std.gcm";
}
std::filesystem::path staged_std_bmi_path(const std::filesystem::path& outputDir) {
return outputDir / "gcm.cache" / "std.gcm";
}
std::string std_module_build_command(const Toolchain& tc,
const std::filesystem::path& cacheDir,
std::string_view sysrootFlag,
std::string_view cppStandardFlag) {
std::string bFlag;
if (auto binutilsBin = find_binutils_bin(tc.binaryPath)) {
bFlag = std::format(" -B'{}'", binutilsBin->string());
}
return std::format(
"cd {} && {}{} {} -fmodules -O2{}{} -c {} -o std.o 2>&1",
mcpp::xlings::shq(cacheDir.string()),
mcpp::toolchain::compiler_env_prefix(tc),
mcpp::xlings::shq(tc.binaryPath.string()),
cppStandardFlag,
sysrootFlag,
bFlag,
mcpp::xlings::shq(tc.stdModuleSource.string()));
}
} // namespace mcpp::toolchain::gcc