@@ -31,40 +31,6 @@ using namespace clang::driver;
31
31
using namespace clang ::driver::tools;
32
32
using namespace clang ::driver::toolchains;
33
33
34
- // / Is the triple {aarch64.aarch64_be}-none-elf?
35
- static bool isAArch64BareMetal (const llvm::Triple &Triple) {
36
- if (Triple.getArch () != llvm::Triple::aarch64 &&
37
- Triple.getArch () != llvm::Triple::aarch64_be)
38
- return false ;
39
-
40
- if (Triple.getVendor () != llvm::Triple::UnknownVendor)
41
- return false ;
42
-
43
- if (Triple.getOS () != llvm::Triple::UnknownOS)
44
- return false ;
45
-
46
- return Triple.getEnvironmentName () == " elf" ;
47
- }
48
-
49
- static bool isRISCVBareMetal (const llvm::Triple &Triple) {
50
- if (!Triple.isRISCV ())
51
- return false ;
52
-
53
- if (Triple.getVendor () != llvm::Triple::UnknownVendor)
54
- return false ;
55
-
56
- if (Triple.getOS () != llvm::Triple::UnknownOS)
57
- return false ;
58
-
59
- return Triple.getEnvironmentName () == " elf" ;
60
- }
61
-
62
- // / Is the triple powerpc[64][le]-*-none-eabi?
63
- static bool isPPCBareMetal (const llvm::Triple &Triple) {
64
- return Triple.isPPC () && Triple.getOS () == llvm::Triple::UnknownOS &&
65
- Triple.getEnvironment () == llvm::Triple::EABI;
66
- }
67
-
68
34
static bool findRISCVMultilibs (const Driver &D,
69
35
const llvm::Triple &TargetTriple,
70
36
const ArgList &Args, DetectedMultilibs &Result) {
@@ -129,8 +95,7 @@ static bool findRISCVMultilibs(const Driver &D,
129
95
return false ;
130
96
}
131
97
132
- static std::string computeClangRuntimesSysRoot (const Driver &D,
133
- bool IncludeTriple) {
98
+ static std::string computeBaseSysRoot (const Driver &D, bool IncludeTriple) {
134
99
if (!D.SysRoot .empty ())
135
100
return D.SysRoot ;
136
101
@@ -143,123 +108,56 @@ static std::string computeClangRuntimesSysRoot(const Driver &D,
143
108
return std::string (SysRootDir);
144
109
}
145
110
146
- // Only consider the GCC toolchain based on the values provided through the
147
- // `--gcc-toolchain` and `--gcc-install-dir` flags. The function below returns
148
- // whether the GCC toolchain was initialized successfully.
149
- bool BareMetal::initGCCInstallation (const llvm::Triple &Triple,
150
- const llvm::opt::ArgList &Args) {
151
- if (Args.getLastArg (options::OPT_gcc_toolchain) ||
152
- Args.getLastArg (clang::driver::options::OPT_gcc_install_dir_EQ)) {
153
- GCCInstallation.init (Triple, Args);
154
- return GCCInstallation.isValid ();
111
+ BareMetal::BareMetal (const Driver &D, const llvm::Triple &Triple,
112
+ const ArgList &Args)
113
+ : ToolChain(D, Triple, Args),
114
+ SysRoot(computeBaseSysRoot(D, /* IncludeTriple=*/ true )) {
115
+ getProgramPaths ().push_back (getDriver ().Dir );
116
+
117
+ findMultilibs (D, Triple, Args);
118
+ SmallString<128 > SysRoot (computeSysRoot ());
119
+ if (!SysRoot.empty ()) {
120
+ for (const Multilib &M : getOrderedMultilibs ()) {
121
+ SmallString<128 > Dir (SysRoot);
122
+ llvm::sys::path::append (Dir, M.osSuffix (), " lib" );
123
+ getFilePaths ().push_back (std::string (Dir));
124
+ getLibraryPaths ().push_back (std::string (Dir));
125
+ }
155
126
}
156
- return false ;
157
127
}
158
128
159
- // This logic is adapted from RISCVToolChain.cpp as part of the ongoing effort
160
- // to merge RISCVToolChain into the Baremetal toolchain. It infers the presence
161
- // of a valid GCC toolchain by checking whether the `crt0.o` file exists in the
162
- // `bin/../<target-triple>/lib` directory.
163
- static bool detectGCCToolchainAdjacent (const Driver &D) {
164
- SmallString<128 > GCCDir;
165
- llvm::sys::path::append (GCCDir, D.Dir , " .." , D.getTargetTriple (),
166
- " lib/crt0.o" );
167
- return llvm::sys::fs::exists (GCCDir);
168
- }
129
+ // / Is the triple {aarch64.aarch64_be}-none-elf?
130
+ static bool isAArch64BareMetal (const llvm::Triple &Triple) {
131
+ if (Triple.getArch () != llvm::Triple::aarch64 &&
132
+ Triple.getArch () != llvm::Triple::aarch64_be)
133
+ return false ;
169
134
170
- // If no sysroot is provided the driver will first attempt to infer it from the
171
- // values of `--gcc-install-dir` or `--gcc-toolchain`, which specify the
172
- // location of a GCC toolchain.
173
- // If neither flag is used, the sysroot defaults to either:
174
- // - `bin/../<target-triple>`
175
- // - `bin/../lib/clang-runtimes/<target-triple>`
176
- //
177
- // To use the `clang-runtimes` path, ensure that `../<target-triple>/lib/crt0.o`
178
- // does not exist relative to the driver.
179
- std::string BareMetal::computeSysRoot () const {
180
- // Use Baremetal::sysroot if it has already been set.
181
- if (!SysRoot.empty ())
182
- return SysRoot;
183
-
184
- // Use the sysroot specified via the `--sysroot` command-line flag, if
185
- // provided.
186
- const Driver &D = getDriver ();
187
- if (!D.SysRoot .empty ())
188
- return D.SysRoot ;
135
+ if (Triple.getVendor () != llvm::Triple::UnknownVendor)
136
+ return false ;
189
137
190
- // Attempt to infer sysroot from a valid GCC installation.
191
- // If no valid GCC installation, check for a GCC toolchain alongside Clang.
192
- SmallString<128 > inferredSysRoot;
193
- if (IsGCCInstallationValid) {
194
- llvm::sys::path::append (inferredSysRoot, GCCInstallation.getParentLibPath (),
195
- " .." , GCCInstallation.getTriple ().str ());
196
- } else if (detectGCCToolchainAdjacent (D)) {
197
- // Use the triple as provided to the driver. Unlike the parsed triple
198
- // this has not been normalized to always contain every field.
199
- llvm::sys::path::append (inferredSysRoot, D.Dir , " .." , D.getTargetTriple ());
200
- }
201
- // If a valid sysroot was inferred and exists, use it
202
- if (!inferredSysRoot.empty () && llvm::sys::fs::exists (inferredSysRoot))
203
- return std::string (inferredSysRoot);
138
+ if (Triple.getOS () != llvm::Triple::UnknownOS)
139
+ return false ;
204
140
205
- // Use the clang-runtimes path.
206
- return computeClangRuntimesSysRoot (D, /* IncludeTriple*/ true );
141
+ return Triple.getEnvironmentName () == " elf" ;
207
142
}
208
143
209
- static void addMultilibsFilePaths (const Driver &D, const MultilibSet &Multilibs,
210
- const Multilib &Multilib,
211
- StringRef InstallPath,
212
- ToolChain::path_list &Paths) {
213
- if (const auto &PathsCallback = Multilibs.filePathsCallback ())
214
- for (const auto &Path : PathsCallback (Multilib))
215
- addPathIfExists (D, InstallPath + Path, Paths);
144
+ static bool isRISCVBareMetal (const llvm::Triple &Triple) {
145
+ if (!Triple.isRISCV ())
146
+ return false ;
147
+
148
+ if (Triple.getVendor () != llvm::Triple::UnknownVendor)
149
+ return false ;
150
+
151
+ if (Triple.getOS () != llvm::Triple::UnknownOS)
152
+ return false ;
153
+
154
+ return Triple.getEnvironmentName () == " elf" ;
216
155
}
217
156
218
- // GCC mutltilibs will only work for those targets that have their multlib
219
- // structure encoded into GCCInstallation. Baremetal toolchain supports ARM,
220
- // AArch64, RISCV and PPC and of these only RISCV have GCC multilibs hardcoded
221
- // in GCCInstallation.
222
- BareMetal::BareMetal (const Driver &D, const llvm::Triple &Triple,
223
- const ArgList &Args)
224
- : Generic_ELF(D, Triple, Args) {
225
- IsGCCInstallationValid = initGCCInstallation (Triple, Args);
226
- std::string ComputedSysRoot = computeSysRoot ();
227
- if (IsGCCInstallationValid) {
228
- if (!isRISCVBareMetal (Triple))
229
- D.Diag (clang::diag::warn_drv_multilib_not_available_for_target);
230
-
231
- Multilibs = GCCInstallation.getMultilibs ();
232
- SelectedMultilibs.assign ({GCCInstallation.getMultilib ()});
233
-
234
- path_list &Paths = getFilePaths ();
235
- // Add toolchain/multilib specific file paths.
236
- addMultilibsFilePaths (D, Multilibs, SelectedMultilibs.back (),
237
- GCCInstallation.getInstallPath (), Paths);
238
- // Adding filepath for locating crt{begin,end}.o files.
239
- Paths.push_back (GCCInstallation.getInstallPath ().str ());
240
- // Adding filepath for locating crt0.o file.
241
- Paths.push_back (ComputedSysRoot + " /lib" );
242
-
243
- ToolChain::path_list &PPaths = getProgramPaths ();
244
- // Multilib cross-compiler GCC installations put ld in a triple-prefixed
245
- // directory off of the parent of the GCC installation.
246
- PPaths.push_back (Twine (GCCInstallation.getParentLibPath () + " /../" +
247
- GCCInstallation.getTriple ().str () + " /bin" )
248
- .str ());
249
- PPaths.push_back ((GCCInstallation.getParentLibPath () + " /../bin" ).str ());
250
- } else {
251
- getProgramPaths ().push_back (getDriver ().Dir );
252
- findMultilibs (D, Triple, Args);
253
- const SmallString<128 > SysRootDir (computeSysRoot ());
254
- if (!SysRootDir.empty ()) {
255
- for (const Multilib &M : getOrderedMultilibs ()) {
256
- SmallString<128 > Dir (SysRootDir);
257
- llvm::sys::path::append (Dir, M.osSuffix (), " lib" );
258
- getFilePaths ().push_back (std::string (Dir));
259
- getLibraryPaths ().push_back (std::string (Dir));
260
- }
261
- }
262
- }
157
+ // / Is the triple powerpc[64][le]-*-none-eabi?
158
+ static bool isPPCBareMetal (const llvm::Triple &Triple) {
159
+ return Triple.isPPC () && Triple.getOS () == llvm::Triple::UnknownOS &&
160
+ Triple.getEnvironment () == llvm::Triple::EABI;
263
161
}
264
162
265
163
static void
@@ -318,7 +216,7 @@ getMultilibConfigPath(const Driver &D, const llvm::Triple &Triple,
318
216
return {};
319
217
}
320
218
} else {
321
- MultilibPath = computeClangRuntimesSysRoot (D, /* IncludeTriple=*/ false );
219
+ MultilibPath = computeBaseSysRoot (D, /* IncludeTriple=*/ false );
322
220
llvm::sys::path::append (MultilibPath, MultilibFilename);
323
221
}
324
222
return MultilibPath;
@@ -336,15 +234,15 @@ void BareMetal::findMultilibs(const Driver &D, const llvm::Triple &Triple,
336
234
if (D.getVFS ().exists (*MultilibPath)) {
337
235
// If multilib.yaml is found, update sysroot so it doesn't use a target
338
236
// specific suffix
339
- SysRoot = computeClangRuntimesSysRoot (D, /* IncludeTriple=*/ false );
237
+ SysRoot = computeBaseSysRoot (D, /* IncludeTriple=*/ false );
340
238
SmallVector<StringRef> CustomFlagMacroDefines;
341
239
findMultilibsFromYAML (*this , D, *MultilibPath, Args, Result,
342
240
CustomFlagMacroDefines);
343
241
SelectedMultilibs = Result.SelectedMultilibs ;
344
242
Multilibs = Result.Multilibs ;
345
243
MultilibMacroDefines.append (CustomFlagMacroDefines.begin (),
346
244
CustomFlagMacroDefines.end ());
347
- } else if (isRISCVBareMetal (Triple) && ! detectGCCToolchainAdjacent (D) ) {
245
+ } else if (isRISCVBareMetal (Triple)) {
348
246
if (findRISCVMultilibs (D, Triple, Args, Result)) {
349
247
SelectedMultilibs = Result.SelectedMultilibs ;
350
248
Multilibs = Result.Multilibs ;
@@ -365,6 +263,8 @@ Tool *BareMetal::buildStaticLibTool() const {
365
263
return new tools::baremetal::StaticLibTool (*this );
366
264
}
367
265
266
+ std::string BareMetal::computeSysRoot () const { return SysRoot; }
267
+
368
268
BareMetal::OrderedMultilibs BareMetal::getOrderedMultilibs () const {
369
269
// Get multilibs in reverse order because they're ordered most-specific last.
370
270
if (!SelectedMultilibs.empty ())
@@ -392,10 +292,10 @@ void BareMetal::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
392
292
if (std::optional<std::string> Path = getStdlibIncludePath ())
393
293
addSystemInclude (DriverArgs, CC1Args, *Path);
394
294
395
- const SmallString<128 > SysRootDir (computeSysRoot ());
396
- if (!SysRootDir .empty ()) {
295
+ const SmallString<128 > SysRoot (computeSysRoot ());
296
+ if (!SysRoot .empty ()) {
397
297
for (const Multilib &M : getOrderedMultilibs ()) {
398
- SmallString<128 > Dir (SysRootDir );
298
+ SmallString<128 > Dir (SysRoot );
399
299
llvm::sys::path::append (Dir, M.includeSuffix ());
400
300
llvm::sys::path::append (Dir, " include" );
401
301
addSystemInclude (DriverArgs, CC1Args, Dir.str ());
@@ -409,19 +309,6 @@ void BareMetal::addClangTargetOptions(const ArgList &DriverArgs,
409
309
CC1Args.push_back (" -nostdsysteminc" );
410
310
}
411
311
412
- void BareMetal::addLibStdCxxIncludePaths (
413
- const llvm::opt::ArgList &DriverArgs,
414
- llvm::opt::ArgStringList &CC1Args) const {
415
- if (!IsGCCInstallationValid)
416
- return ;
417
- const GCCVersion &Version = GCCInstallation.getVersion ();
418
- StringRef TripleStr = GCCInstallation.getTriple ().str ();
419
- const Multilib &Multilib = GCCInstallation.getMultilib ();
420
- addLibStdCXXIncludePaths (computeSysRoot () + " /include/c++/" + Version.Text ,
421
- TripleStr, Multilib.includeSuffix (), DriverArgs,
422
- CC1Args);
423
- }
424
-
425
312
void BareMetal::AddClangCXXStdlibIncludeArgs (const ArgList &DriverArgs,
426
313
ArgStringList &CC1Args) const {
427
314
if (DriverArgs.hasArg (options::OPT_nostdinc, options::OPT_nostdlibinc,
@@ -452,23 +339,23 @@ void BareMetal::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
452
339
};
453
340
454
341
switch (GetCXXStdlibType (DriverArgs)) {
455
- case ToolChain::CST_Libcxx: {
456
- SmallString<128 > P (D.Dir );
457
- llvm::sys::path::append (P, " .." , " include" );
458
- AddCXXIncludePath (P);
459
- break ;
460
- }
461
- case ToolChain::CST_Libstdcxx:
462
- addLibStdCxxIncludePaths (DriverArgs, CC1Args);
463
- break ;
342
+ case ToolChain::CST_Libcxx: {
343
+ SmallString<128 > P (D.Dir );
344
+ llvm::sys::path::append (P, " .." , " include" );
345
+ AddCXXIncludePath (P);
346
+ break ;
347
+ }
348
+ case ToolChain::CST_Libstdcxx:
349
+ // We only support libc++ toolchain installation.
350
+ break ;
464
351
}
465
352
466
- std::string SysRootDir (computeSysRoot ());
467
- if (SysRootDir .empty ())
353
+ std::string SysRoot (computeSysRoot ());
354
+ if (SysRoot .empty ())
468
355
return ;
469
356
470
357
for (const Multilib &M : getOrderedMultilibs ()) {
471
- SmallString<128 > Dir (SysRootDir );
358
+ SmallString<128 > Dir (SysRoot );
472
359
llvm::sys::path::append (Dir, M.gccSuffix ());
473
360
switch (GetCXXStdlibType (DriverArgs)) {
474
361
case ToolChain::CST_Libcxx: {
0 commit comments