@@ -97,7 +97,8 @@ static bool findRISCVMultilibs(const Driver &D,
97
97
return false ;
98
98
}
99
99
100
- static std::string computeBaseSysRoot (const Driver &D, bool IncludeTriple) {
100
+ static std::string computeInstalledToolchainSysRoot (const Driver &D,
101
+ bool IncludeTriple) {
101
102
if (!D.SysRoot .empty ())
102
103
return D.SysRoot ;
103
104
@@ -110,20 +111,93 @@ static std::string computeBaseSysRoot(const Driver &D, bool IncludeTriple) {
110
111
return std::string (SysRootDir);
111
112
}
112
113
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
+
113
170
BareMetal::BareMetal (const Driver &D, const llvm::Triple &Triple,
114
171
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
+ }
127
201
}
128
202
}
129
203
}
@@ -215,7 +289,7 @@ getMultilibConfigPath(const Driver &D, const llvm::Triple &Triple,
215
289
return {};
216
290
}
217
291
} else {
218
- MultilibPath = computeBaseSysRoot (D, /* IncludeTriple=*/ false );
292
+ MultilibPath = computeInstalledToolchainSysRoot (D, /* IncludeTriple=*/ false );
219
293
llvm::sys::path::append (MultilibPath, MultilibFilename);
220
294
}
221
295
return MultilibPath;
@@ -233,7 +307,7 @@ void BareMetal::findMultilibs(const Driver &D, const llvm::Triple &Triple,
233
307
if (D.getVFS ().exists (*MultilibPath)) {
234
308
// If multilib.yaml is found, update sysroot so it doesn't use a target
235
309
// specific suffix
236
- SysRoot = computeBaseSysRoot (D, /* IncludeTriple=*/ false );
310
+ SysRoot = computeInstalledToolchainSysRoot (D, /* IncludeTriple=*/ false );
237
311
findMultilibsFromYAML (*this , D, *MultilibPath, Args, Result);
238
312
SelectedMultilibs = Result.SelectedMultilibs ;
239
313
Multilibs = Result.Multilibs ;
@@ -258,8 +332,6 @@ Tool *BareMetal::buildStaticLibTool() const {
258
332
return new tools::baremetal::StaticLibTool (*this );
259
333
}
260
334
261
- std::string BareMetal::computeSysRoot () const { return SysRoot; }
262
-
263
335
BareMetal::OrderedMultilibs BareMetal::getOrderedMultilibs () const {
264
336
// Get multilibs in reverse order because they're ordered most-specific last.
265
337
if (!SelectedMultilibs.empty ())
@@ -304,6 +376,19 @@ void BareMetal::addClangTargetOptions(const ArgList &DriverArgs,
304
376
CC1Args.push_back (" -nostdsysteminc" );
305
377
}
306
378
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
+
307
392
void BareMetal::AddClangCXXStdlibIncludeArgs (const ArgList &DriverArgs,
308
393
ArgStringList &CC1Args) const {
309
394
if (DriverArgs.hasArg (options::OPT_nostdinc, options::OPT_nostdlibinc,
@@ -341,7 +426,7 @@ void BareMetal::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
341
426
break ;
342
427
}
343
428
case ToolChain::CST_Libstdcxx:
344
- // We only support libc++ toolchain installation.
429
+ addLibStdCxxIncludePaths (DriverArgs, CC1Args);
345
430
break ;
346
431
}
347
432
0 commit comments