@@ -97,7 +97,8 @@ static bool findRISCVMultilibs(const Driver &D,
9797 return false ;
9898}
9999
100- static std::string computeBaseSysRoot (const Driver &D, bool IncludeTriple) {
100+ static std::string computeInstalledToolchainSysRoot (const Driver &D,
101+ bool IncludeTriple) {
101102 if (!D.SysRoot .empty ())
102103 return D.SysRoot ;
103104
@@ -110,20 +111,93 @@ static std::string computeBaseSysRoot(const Driver &D, bool IncludeTriple) {
110111 return std::string (SysRootDir);
111112}
112113
114+ // GCC sysroot here means form sysroot from either --gcc-install-dir, or from
115+ // --gcc-toolchain or if the toolchain is installed alongside clang in
116+ // bin/../<TargetTriple> directory if it is not explicitly specified on the
117+ // command line through `--sysroot` option. libc here will be newlib.
118+ std::string BareMetal::computeGCCSysRoot () const {
119+ if (!getDriver ().SysRoot .empty ())
120+ return getDriver ().SysRoot ;
121+
122+ SmallString<128 > SysRootDir;
123+ if (GCCInstallation.isValid ()) {
124+ StringRef LibDir = GCCInstallation.getParentLibPath ();
125+ StringRef TripleStr = GCCInstallation.getTriple ().str ();
126+ llvm::sys::path::append (SysRootDir, LibDir, " .." , TripleStr);
127+ } else {
128+ // Use the triple as provided to the driver. Unlike the parsed triple
129+ // this has not been normalized to always contain every field.
130+ llvm::sys::path::append (SysRootDir, getDriver ().Dir , " .." ,
131+ getDriver ().getTargetTriple ());
132+ }
133+
134+ if (!llvm::sys::fs::exists (SysRootDir))
135+ return std::string ();
136+
137+ return std::string (SysRootDir);
138+ }
139+
140+ std::string BareMetal::computeSysRoot () const {
141+ if (!SysRoot.empty ())
142+ return SysRoot;
143+
144+ std::string SysRoot = getDriver ().SysRoot ;
145+ if (!SysRoot.empty () && llvm::sys::fs::exists (SysRoot))
146+ return SysRoot;
147+
148+ // Verify the GCC installation from -gcc-install-dir, --gcc-toolchain, or
149+ // alongside clang. If valid, form the sysroot. Otherwise, check
150+ // lib/clang-runtimes above the driver.
151+ SysRoot = computeGCCSysRoot ();
152+ if (!SysRoot.empty ())
153+ return SysRoot;
154+
155+ SysRoot =
156+ computeInstalledToolchainSysRoot (getDriver (), /* IncludeTriple*/ true );
157+
158+ return SysRoot;
159+ }
160+
161+ static void addMultilibsFilePaths (const Driver &D, const MultilibSet &Multilibs,
162+ const Multilib &Multilib,
163+ StringRef InstallPath,
164+ ToolChain::path_list &Paths) {
165+ if (const auto &PathsCallback = Multilibs.filePathsCallback ())
166+ for (const auto &Path : PathsCallback (Multilib))
167+ addPathIfExists (D, InstallPath + Path, Paths);
168+ }
169+
113170BareMetal::BareMetal (const Driver &D, const llvm::Triple &Triple,
114171 const ArgList &Args)
115- : ToolChain(D, Triple, Args),
116- SysRoot(computeBaseSysRoot(D, /* IncludeTriple=*/ true )) {
117- getProgramPaths ().push_back (getDriver ().Dir );
118-
119- findMultilibs (D, Triple, Args);
120- SmallString<128 > SysRoot (computeSysRoot ());
121- if (!SysRoot.empty ()) {
122- for (const Multilib &M : getOrderedMultilibs ()) {
123- SmallString<128 > Dir (SysRoot);
124- llvm::sys::path::append (Dir, M.osSuffix (), " lib" );
125- getFilePaths ().push_back (std::string (Dir));
126- getLibraryPaths ().push_back (std::string (Dir));
172+ : Generic_ELF(D, Triple, Args) {
173+ GCCInstallation.init (Triple, Args);
174+ SysRoot = computeSysRoot ();
175+ if (GCCInstallation.isValid ()) {
176+ Multilibs = GCCInstallation.getMultilibs ();
177+ SelectedMultilibs.assign ({GCCInstallation.getMultilib ()});
178+ path_list &Paths = getFilePaths ();
179+ // Add toolchain/multilib specific file paths.
180+ addMultilibsFilePaths (D, Multilibs, SelectedMultilibs.back (),
181+ GCCInstallation.getInstallPath (), Paths);
182+ getFilePaths ().push_back (GCCInstallation.getInstallPath ().str ());
183+ ToolChain::path_list &PPaths = getProgramPaths ();
184+ // Multilib cross-compiler GCC installations put ld in a triple-prefixed
185+ // directory off of the parent of the GCC installation.
186+ PPaths.push_back (Twine (GCCInstallation.getParentLibPath () + " /../" +
187+ GCCInstallation.getTriple ().str () + " /bin" )
188+ .str ());
189+ PPaths.push_back ((GCCInstallation.getParentLibPath () + " /../bin" ).str ());
190+ getFilePaths ().push_back (computeSysRoot () + " /lib" );
191+ } else {
192+ getProgramPaths ().push_back (getDriver ().Dir );
193+ findMultilibs (D, Triple, Args);
194+ if (!SysRoot.empty ()) {
195+ for (const Multilib &M : getOrderedMultilibs ()) {
196+ SmallString<128 > Dir (SysRoot);
197+ llvm::sys::path::append (Dir, M.osSuffix (), " lib" );
198+ getFilePaths ().push_back (std::string (Dir));
199+ getLibraryPaths ().push_back (std::string (Dir));
200+ }
127201 }
128202 }
129203}
@@ -215,7 +289,7 @@ getMultilibConfigPath(const Driver &D, const llvm::Triple &Triple,
215289 return {};
216290 }
217291 } else {
218- MultilibPath = computeBaseSysRoot (D, /* IncludeTriple=*/ false );
292+ MultilibPath = computeInstalledToolchainSysRoot (D, /* IncludeTriple=*/ false );
219293 llvm::sys::path::append (MultilibPath, MultilibFilename);
220294 }
221295 return MultilibPath;
@@ -233,7 +307,7 @@ void BareMetal::findMultilibs(const Driver &D, const llvm::Triple &Triple,
233307 if (D.getVFS ().exists (*MultilibPath)) {
234308 // If multilib.yaml is found, update sysroot so it doesn't use a target
235309 // specific suffix
236- SysRoot = computeBaseSysRoot (D, /* IncludeTriple=*/ false );
310+ SysRoot = computeInstalledToolchainSysRoot (D, /* IncludeTriple=*/ false );
237311 findMultilibsFromYAML (*this , D, *MultilibPath, Args, Result);
238312 SelectedMultilibs = Result.SelectedMultilibs ;
239313 Multilibs = Result.Multilibs ;
@@ -258,8 +332,6 @@ Tool *BareMetal::buildStaticLibTool() const {
258332 return new tools::baremetal::StaticLibTool (*this );
259333}
260334
261- std::string BareMetal::computeSysRoot () const { return SysRoot; }
262-
263335BareMetal::OrderedMultilibs BareMetal::getOrderedMultilibs () const {
264336 // Get multilibs in reverse order because they're ordered most-specific last.
265337 if (!SelectedMultilibs.empty ())
@@ -304,6 +376,19 @@ void BareMetal::addClangTargetOptions(const ArgList &DriverArgs,
304376 CC1Args.push_back (" -nostdsysteminc" );
305377}
306378
379+ void BareMetal::addLibStdCxxIncludePaths (
380+ const llvm::opt::ArgList &DriverArgs,
381+ llvm::opt::ArgStringList &CC1Args) const {
382+ if (!GCCInstallation.isValid ())
383+ return ;
384+ const GCCVersion &Version = GCCInstallation.getVersion ();
385+ StringRef TripleStr = GCCInstallation.getTriple ().str ();
386+ const Multilib &Multilib = GCCInstallation.getMultilib ();
387+ addLibStdCXXIncludePaths (computeSysRoot () + " /include/c++/" + Version.Text ,
388+ TripleStr, Multilib.includeSuffix (), DriverArgs,
389+ CC1Args);
390+ }
391+
307392void BareMetal::AddClangCXXStdlibIncludeArgs (const ArgList &DriverArgs,
308393 ArgStringList &CC1Args) const {
309394 if (DriverArgs.hasArg (options::OPT_nostdinc, options::OPT_nostdlibinc,
@@ -341,7 +426,7 @@ void BareMetal::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
341426 break ;
342427 }
343428 case ToolChain::CST_Libstdcxx:
344- // We only support libc++ toolchain installation.
429+ addLibStdCxxIncludePaths (DriverArgs, CC1Args);
345430 break ;
346431 }
347432
0 commit comments