@@ -31,40 +31,6 @@ using namespace clang::driver;
3131using namespace clang ::driver::tools;
3232using namespace clang ::driver::toolchains;
3333
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-
6834static bool findRISCVMultilibs (const Driver &D,
6935 const llvm::Triple &TargetTriple,
7036 const ArgList &Args, DetectedMultilibs &Result) {
@@ -129,8 +95,7 @@ static bool findRISCVMultilibs(const Driver &D,
12995 return false ;
13096}
13197
132- static std::string computeClangRuntimesSysRoot (const Driver &D,
133- bool IncludeTriple) {
98+ static std::string computeBaseSysRoot (const Driver &D, bool IncludeTriple) {
13499 if (!D.SysRoot .empty ())
135100 return D.SysRoot ;
136101
@@ -143,123 +108,56 @@ static std::string computeClangRuntimesSysRoot(const Driver &D,
143108 return std::string (SysRootDir);
144109}
145110
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+ }
155126 }
156- return false ;
157127}
158128
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 ;
169134
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 ;
189137
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 ;
204140
205- // Use the clang-runtimes path.
206- return computeClangRuntimesSysRoot (D, /* IncludeTriple*/ true );
141+ return Triple.getEnvironmentName () == " elf" ;
207142}
208143
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" ;
216155}
217156
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;
263161}
264162
265163static void
@@ -318,7 +216,7 @@ getMultilibConfigPath(const Driver &D, const llvm::Triple &Triple,
318216 return {};
319217 }
320218 } else {
321- MultilibPath = computeClangRuntimesSysRoot (D, /* IncludeTriple=*/ false );
219+ MultilibPath = computeBaseSysRoot (D, /* IncludeTriple=*/ false );
322220 llvm::sys::path::append (MultilibPath, MultilibFilename);
323221 }
324222 return MultilibPath;
@@ -336,15 +234,15 @@ void BareMetal::findMultilibs(const Driver &D, const llvm::Triple &Triple,
336234 if (D.getVFS ().exists (*MultilibPath)) {
337235 // If multilib.yaml is found, update sysroot so it doesn't use a target
338236 // specific suffix
339- SysRoot = computeClangRuntimesSysRoot (D, /* IncludeTriple=*/ false );
237+ SysRoot = computeBaseSysRoot (D, /* IncludeTriple=*/ false );
340238 SmallVector<StringRef> CustomFlagMacroDefines;
341239 findMultilibsFromYAML (*this , D, *MultilibPath, Args, Result,
342240 CustomFlagMacroDefines);
343241 SelectedMultilibs = Result.SelectedMultilibs ;
344242 Multilibs = Result.Multilibs ;
345243 MultilibMacroDefines.append (CustomFlagMacroDefines.begin (),
346244 CustomFlagMacroDefines.end ());
347- } else if (isRISCVBareMetal (Triple) && ! detectGCCToolchainAdjacent (D) ) {
245+ } else if (isRISCVBareMetal (Triple)) {
348246 if (findRISCVMultilibs (D, Triple, Args, Result)) {
349247 SelectedMultilibs = Result.SelectedMultilibs ;
350248 Multilibs = Result.Multilibs ;
@@ -365,6 +263,8 @@ Tool *BareMetal::buildStaticLibTool() const {
365263 return new tools::baremetal::StaticLibTool (*this );
366264}
367265
266+ std::string BareMetal::computeSysRoot () const { return SysRoot; }
267+
368268BareMetal::OrderedMultilibs BareMetal::getOrderedMultilibs () const {
369269 // Get multilibs in reverse order because they're ordered most-specific last.
370270 if (!SelectedMultilibs.empty ())
@@ -392,10 +292,10 @@ void BareMetal::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
392292 if (std::optional<std::string> Path = getStdlibIncludePath ())
393293 addSystemInclude (DriverArgs, CC1Args, *Path);
394294
395- const SmallString<128 > SysRootDir (computeSysRoot ());
396- if (!SysRootDir .empty ()) {
295+ const SmallString<128 > SysRoot (computeSysRoot ());
296+ if (!SysRoot .empty ()) {
397297 for (const Multilib &M : getOrderedMultilibs ()) {
398- SmallString<128 > Dir (SysRootDir );
298+ SmallString<128 > Dir (SysRoot );
399299 llvm::sys::path::append (Dir, M.includeSuffix ());
400300 llvm::sys::path::append (Dir, " include" );
401301 addSystemInclude (DriverArgs, CC1Args, Dir.str ());
@@ -409,19 +309,6 @@ void BareMetal::addClangTargetOptions(const ArgList &DriverArgs,
409309 CC1Args.push_back (" -nostdsysteminc" );
410310}
411311
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-
425312void BareMetal::AddClangCXXStdlibIncludeArgs (const ArgList &DriverArgs,
426313 ArgStringList &CC1Args) const {
427314 if (DriverArgs.hasArg (options::OPT_nostdinc, options::OPT_nostdlibinc,
@@ -452,23 +339,23 @@ void BareMetal::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
452339 };
453340
454341 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 ;
464351 }
465352
466- std::string SysRootDir (computeSysRoot ());
467- if (SysRootDir .empty ())
353+ std::string SysRoot (computeSysRoot ());
354+ if (SysRoot .empty ())
468355 return ;
469356
470357 for (const Multilib &M : getOrderedMultilibs ()) {
471- SmallString<128 > Dir (SysRootDir );
358+ SmallString<128 > Dir (SysRoot );
472359 llvm::sys::path::append (Dir, M.gccSuffix ());
473360 switch (GetCXXStdlibType (DriverArgs)) {
474361 case ToolChain::CST_Libcxx: {
0 commit comments