123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687 |
- //===--- MinGW.cpp - MinGWToolChain Implementation ------------------------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- #include "MinGW.h"
- #include "CommonArgs.h"
- #include "clang/Config/config.h"
- #include "clang/Driver/Compilation.h"
- #include "clang/Driver/Driver.h"
- #include "clang/Driver/DriverDiagnostic.h"
- #include "clang/Driver/InputInfo.h"
- #include "clang/Driver/Options.h"
- #include "clang/Driver/SanitizerArgs.h"
- #include "llvm/Option/ArgList.h"
- #include "llvm/Support/FileSystem.h"
- #include "llvm/Support/Path.h"
- #include "llvm/Support/VirtualFileSystem.h"
- #include <system_error>
- using namespace clang::diag;
- using namespace clang::driver;
- using namespace clang;
- using namespace llvm::opt;
- /// MinGW Tools
- void tools::MinGW::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- claimNoWarnArgs(Args);
- ArgStringList CmdArgs;
- if (getToolChain().getArch() == llvm::Triple::x86) {
- CmdArgs.push_back("--32");
- } else if (getToolChain().getArch() == llvm::Triple::x86_64) {
- CmdArgs.push_back("--64");
- }
- Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
- CmdArgs.push_back("-o");
- CmdArgs.push_back(Output.getFilename());
- for (const auto &II : Inputs)
- CmdArgs.push_back(II.getFilename());
- const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
- C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
- Exec, CmdArgs, Inputs, Output));
- if (Args.hasArg(options::OPT_gsplit_dwarf))
- SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output,
- SplitDebugName(JA, Args, Inputs[0], Output));
- }
- void tools::MinGW::Linker::AddLibGCC(const ArgList &Args,
- ArgStringList &CmdArgs) const {
- if (Args.hasArg(options::OPT_mthreads))
- CmdArgs.push_back("-lmingwthrd");
- CmdArgs.push_back("-lmingw32");
- // Make use of compiler-rt if --rtlib option is used
- ToolChain::RuntimeLibType RLT = getToolChain().GetRuntimeLibType(Args);
- if (RLT == ToolChain::RLT_Libgcc) {
- bool Static = Args.hasArg(options::OPT_static_libgcc) ||
- Args.hasArg(options::OPT_static);
- bool Shared = Args.hasArg(options::OPT_shared);
- bool CXX = getToolChain().getDriver().CCCIsCXX();
- if (Static || (!CXX && !Shared)) {
- CmdArgs.push_back("-lgcc");
- CmdArgs.push_back("-lgcc_eh");
- } else {
- CmdArgs.push_back("-lgcc_s");
- CmdArgs.push_back("-lgcc");
- }
- } else {
- AddRunTimeLibs(getToolChain(), getToolChain().getDriver(), CmdArgs, Args);
- }
- CmdArgs.push_back("-lmoldname");
- CmdArgs.push_back("-lmingwex");
- for (auto Lib : Args.getAllArgValues(options::OPT_l))
- if (StringRef(Lib).startswith("msvcr") ||
- StringRef(Lib).startswith("ucrt") ||
- StringRef(Lib).startswith("crtdll"))
- return;
- CmdArgs.push_back("-lmsvcrt");
- }
- void tools::MinGW::Linker::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- const ToolChain &TC = getToolChain();
- const Driver &D = TC.getDriver();
- const SanitizerArgs &Sanitize = TC.getSanitizerArgs(Args);
- ArgStringList CmdArgs;
- // Silence warning for "clang -g foo.o -o foo"
- Args.ClaimAllArgs(options::OPT_g_Group);
- // and "clang -emit-llvm foo.o -o foo"
- Args.ClaimAllArgs(options::OPT_emit_llvm);
- // and for "clang -w foo.o -o foo". Other warning options are already
- // handled somewhere else.
- Args.ClaimAllArgs(options::OPT_w);
- if (!D.SysRoot.empty())
- CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
- if (Args.hasArg(options::OPT_s))
- CmdArgs.push_back("-s");
- CmdArgs.push_back("-m");
- switch (TC.getArch()) {
- case llvm::Triple::x86:
- CmdArgs.push_back("i386pe");
- break;
- case llvm::Triple::x86_64:
- CmdArgs.push_back("i386pep");
- break;
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- // FIXME: this is incorrect for WinCE
- CmdArgs.push_back("thumb2pe");
- break;
- case llvm::Triple::aarch64:
- CmdArgs.push_back("arm64pe");
- break;
- default:
- llvm_unreachable("Unsupported target architecture.");
- }
- Arg *SubsysArg =
- Args.getLastArg(options::OPT_mwindows, options::OPT_mconsole);
- if (SubsysArg && SubsysArg->getOption().matches(options::OPT_mwindows)) {
- CmdArgs.push_back("--subsystem");
- CmdArgs.push_back("windows");
- } else if (SubsysArg &&
- SubsysArg->getOption().matches(options::OPT_mconsole)) {
- CmdArgs.push_back("--subsystem");
- CmdArgs.push_back("console");
- }
- if (Args.hasArg(options::OPT_mdll))
- CmdArgs.push_back("--dll");
- else if (Args.hasArg(options::OPT_shared))
- CmdArgs.push_back("--shared");
- if (Args.hasArg(options::OPT_static))
- CmdArgs.push_back("-Bstatic");
- else
- CmdArgs.push_back("-Bdynamic");
- if (Args.hasArg(options::OPT_mdll) || Args.hasArg(options::OPT_shared)) {
- CmdArgs.push_back("-e");
- if (TC.getArch() == llvm::Triple::x86)
- CmdArgs.push_back("_DllMainCRTStartup@12");
- else
- CmdArgs.push_back("DllMainCRTStartup");
- CmdArgs.push_back("--enable-auto-image-base");
- }
- if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
- CmdArgs.push_back("--no-demangle");
- CmdArgs.push_back("-o");
- const char *OutputFile = Output.getFilename();
- // GCC implicitly adds an .exe extension if it is given an output file name
- // that lacks an extension.
- // GCC used to do this only when the compiler itself runs on windows, but
- // since GCC 8 it does the same when cross compiling as well.
- if (!llvm::sys::path::has_extension(OutputFile)) {
- CmdArgs.push_back(Args.MakeArgString(Twine(OutputFile) + ".exe"));
- OutputFile = CmdArgs.back();
- } else
- CmdArgs.push_back(OutputFile);
- Args.AddAllArgs(CmdArgs, options::OPT_e);
- // FIXME: add -N, -n flags
- Args.AddLastArg(CmdArgs, options::OPT_r);
- Args.AddLastArg(CmdArgs, options::OPT_s);
- Args.AddLastArg(CmdArgs, options::OPT_t);
- Args.AddAllArgs(CmdArgs, options::OPT_u_Group);
- Args.AddLastArg(CmdArgs, options::OPT_Z_Flag);
- if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
- if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_mdll)) {
- CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("dllcrt2.o")));
- } else {
- if (Args.hasArg(options::OPT_municode))
- CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crt2u.o")));
- else
- CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crt2.o")));
- }
- if (Args.hasArg(options::OPT_pg))
- CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("gcrt2.o")));
- CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtbegin.o")));
- }
- Args.AddAllArgs(CmdArgs, options::OPT_L);
- TC.AddFilePathLibArgs(Args, CmdArgs);
- // Add the compiler-rt library directories if they exist to help
- // the linker find the various sanitizer, builtin, and profiling runtimes.
- for (const auto &LibPath : TC.getLibraryPaths()) {
- if (TC.getVFS().exists(LibPath))
- CmdArgs.push_back(Args.MakeArgString("-L" + LibPath));
- }
- auto CRTPath = TC.getCompilerRTPath();
- if (TC.getVFS().exists(CRTPath))
- CmdArgs.push_back(Args.MakeArgString("-L" + CRTPath));
- AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA);
- // TODO: Add profile stuff here
- if (TC.ShouldLinkCXXStdlib(Args)) {
- bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
- !Args.hasArg(options::OPT_static);
- if (OnlyLibstdcxxStatic)
- CmdArgs.push_back("-Bstatic");
- TC.AddCXXStdlibLibArgs(Args, CmdArgs);
- if (OnlyLibstdcxxStatic)
- CmdArgs.push_back("-Bdynamic");
- }
- bool HasWindowsApp = false;
- for (auto Lib : Args.getAllArgValues(options::OPT_l)) {
- if (Lib == "windowsapp") {
- HasWindowsApp = true;
- break;
- }
- }
- if (!Args.hasArg(options::OPT_nostdlib)) {
- if (!Args.hasArg(options::OPT_nodefaultlibs)) {
- if (Args.hasArg(options::OPT_static))
- CmdArgs.push_back("--start-group");
- if (Args.hasArg(options::OPT_fstack_protector) ||
- Args.hasArg(options::OPT_fstack_protector_strong) ||
- Args.hasArg(options::OPT_fstack_protector_all)) {
- CmdArgs.push_back("-lssp_nonshared");
- CmdArgs.push_back("-lssp");
- }
- if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
- options::OPT_fno_openmp, false)) {
- switch (TC.getDriver().getOpenMPRuntime(Args)) {
- case Driver::OMPRT_OMP:
- CmdArgs.push_back("-lomp");
- break;
- case Driver::OMPRT_IOMP5:
- CmdArgs.push_back("-liomp5md");
- break;
- case Driver::OMPRT_GOMP:
- CmdArgs.push_back("-lgomp");
- break;
- case Driver::OMPRT_Unknown:
- // Already diagnosed.
- break;
- }
- }
- AddLibGCC(Args, CmdArgs);
- if (Args.hasArg(options::OPT_pg))
- CmdArgs.push_back("-lgmon");
- if (Args.hasArg(options::OPT_pthread))
- CmdArgs.push_back("-lpthread");
- if (Sanitize.needsAsanRt()) {
- // MinGW always links against a shared MSVCRT.
- CmdArgs.push_back(TC.getCompilerRTArgString(Args, "asan_dynamic",
- ToolChain::FT_Shared));
- CmdArgs.push_back(
- TC.getCompilerRTArgString(Args, "asan_dynamic_runtime_thunk"));
- CmdArgs.push_back("--require-defined");
- CmdArgs.push_back(TC.getArch() == llvm::Triple::x86
- ? "___asan_seh_interceptor"
- : "__asan_seh_interceptor");
- // Make sure the linker consider all object files from the dynamic
- // runtime thunk.
- CmdArgs.push_back("--whole-archive");
- CmdArgs.push_back(
- TC.getCompilerRTArgString(Args, "asan_dynamic_runtime_thunk"));
- CmdArgs.push_back("--no-whole-archive");
- }
- TC.addProfileRTLibs(Args, CmdArgs);
- if (!HasWindowsApp) {
- // Add system libraries. If linking to libwindowsapp.a, that import
- // library replaces all these and we shouldn't accidentally try to
- // link to the normal desktop mode dlls.
- if (Args.hasArg(options::OPT_mwindows)) {
- CmdArgs.push_back("-lgdi32");
- CmdArgs.push_back("-lcomdlg32");
- }
- CmdArgs.push_back("-ladvapi32");
- CmdArgs.push_back("-lshell32");
- CmdArgs.push_back("-luser32");
- CmdArgs.push_back("-lkernel32");
- }
- if (Args.hasArg(options::OPT_static)) {
- CmdArgs.push_back("--end-group");
- } else {
- AddLibGCC(Args, CmdArgs);
- if (!HasWindowsApp)
- CmdArgs.push_back("-lkernel32");
- }
- }
- if (!Args.hasArg(options::OPT_nostartfiles)) {
- // Add crtfastmath.o if available and fast math is enabled.
- TC.addFastMathRuntimeIfAvailable(Args, CmdArgs);
- CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtend.o")));
- }
- }
- const char *Exec = Args.MakeArgString(TC.GetLinkerPath());
- C.addCommand(std::make_unique<Command>(JA, *this,
- ResponseFileSupport::AtFileUTF8(),
- Exec, CmdArgs, Inputs, Output));
- }
- // Simplified from Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple.
- static bool findGccVersion(StringRef LibDir, std::string &GccLibDir,
- std::string &Ver) {
- auto Version = toolchains::Generic_GCC::GCCVersion::Parse("0.0.0");
- std::error_code EC;
- for (llvm::sys::fs::directory_iterator LI(LibDir, EC), LE; !EC && LI != LE;
- LI = LI.increment(EC)) {
- StringRef VersionText = llvm::sys::path::filename(LI->path());
- auto CandidateVersion =
- toolchains::Generic_GCC::GCCVersion::Parse(VersionText);
- if (CandidateVersion.Major == -1)
- continue;
- if (CandidateVersion <= Version)
- continue;
- Version = CandidateVersion;
- Ver = std::string(VersionText);
- GccLibDir = LI->path();
- }
- return Ver.size();
- }
- void toolchains::MinGW::findGccLibDir() {
- llvm::SmallVector<llvm::SmallString<32>, 2> SubdirNames;
- SubdirNames.emplace_back(getTriple().getArchName());
- SubdirNames[0] += "-w64-mingw32";
- SubdirNames.emplace_back("mingw32");
- if (SubdirName.empty())
- SubdirName = std::string(SubdirNames[0].str());
- // lib: Arch Linux, Ubuntu, Windows
- // lib64: openSUSE Linux
- for (StringRef CandidateLib : {"lib", "lib64"}) {
- for (StringRef CandidateSysroot : SubdirNames) {
- llvm::SmallString<1024> LibDir(Base);
- llvm::sys::path::append(LibDir, CandidateLib, "gcc", CandidateSysroot);
- if (findGccVersion(LibDir, GccLibDir, Ver)) {
- SubdirName = std::string(CandidateSysroot);
- return;
- }
- }
- }
- }
- static llvm::ErrorOr<std::string> findGcc(const llvm::Triple &T) {
- llvm::SmallVector<llvm::SmallString<32>, 2> Gccs;
- Gccs.emplace_back(T.getArchName());
- Gccs[0] += "-w64-mingw32-gcc";
- Gccs.emplace_back("mingw32-gcc");
- // Please do not add "gcc" here
- for (StringRef CandidateGcc : Gccs)
- if (llvm::ErrorOr<std::string> GPPName = llvm::sys::findProgramByName(CandidateGcc))
- return GPPName;
- return make_error_code(std::errc::no_such_file_or_directory);
- }
- static llvm::ErrorOr<std::string>
- findClangRelativeSysroot(const Driver &D, const llvm::Triple &T,
- std::string &SubdirName) {
- llvm::SmallVector<llvm::SmallString<32>, 2> Subdirs;
- Subdirs.emplace_back(T.str());
- Subdirs.emplace_back(T.getArchName());
- Subdirs[1] += "-w64-mingw32";
- StringRef ClangRoot = llvm::sys::path::parent_path(D.getInstalledDir());
- StringRef Sep = llvm::sys::path::get_separator();
- for (StringRef CandidateSubdir : Subdirs) {
- if (llvm::sys::fs::is_directory(ClangRoot + Sep + CandidateSubdir)) {
- SubdirName = std::string(CandidateSubdir);
- return (ClangRoot + Sep + CandidateSubdir).str();
- }
- }
- return make_error_code(std::errc::no_such_file_or_directory);
- }
- toolchains::MinGW::MinGW(const Driver &D, const llvm::Triple &Triple,
- const ArgList &Args)
- : ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args),
- RocmInstallation(D, Triple, Args) {
- getProgramPaths().push_back(getDriver().getInstalledDir());
- // The sequence for detecting a sysroot here should be kept in sync with
- // the testTriple function below.
- if (getDriver().SysRoot.size())
- Base = getDriver().SysRoot;
- // Look for <clang-bin>/../<triplet>; if found, use <clang-bin>/.. as the
- // base as it could still be a base for a gcc setup with libgcc.
- else if (llvm::ErrorOr<std::string> TargetSubdir =
- findClangRelativeSysroot(getDriver(), getTriple(), SubdirName))
- Base = std::string(llvm::sys::path::parent_path(TargetSubdir.get()));
- else if (llvm::ErrorOr<std::string> GPPName = findGcc(getTriple()))
- Base = std::string(llvm::sys::path::parent_path(
- llvm::sys::path::parent_path(GPPName.get())));
- else
- Base = std::string(
- llvm::sys::path::parent_path(getDriver().getInstalledDir()));
- Base += llvm::sys::path::get_separator();
- findGccLibDir();
- // GccLibDir must precede Base/lib so that the
- // correct crtbegin.o ,cetend.o would be found.
- getFilePaths().push_back(GccLibDir);
- getFilePaths().push_back(
- (Base + SubdirName + llvm::sys::path::get_separator() + "lib").str());
- getFilePaths().push_back(Base + "lib");
- // openSUSE
- getFilePaths().push_back(Base + SubdirName + "/sys-root/mingw/lib");
- NativeLLVMSupport =
- Args.getLastArgValue(options::OPT_fuse_ld_EQ, CLANG_DEFAULT_LINKER)
- .equals_insensitive("lld");
- }
- bool toolchains::MinGW::IsIntegratedAssemblerDefault() const { return true; }
- Tool *toolchains::MinGW::getTool(Action::ActionClass AC) const {
- switch (AC) {
- case Action::PreprocessJobClass:
- if (!Preprocessor)
- Preprocessor.reset(new tools::gcc::Preprocessor(*this));
- return Preprocessor.get();
- case Action::CompileJobClass:
- if (!Compiler)
- Compiler.reset(new tools::gcc::Compiler(*this));
- return Compiler.get();
- default:
- return ToolChain::getTool(AC);
- }
- }
- Tool *toolchains::MinGW::buildAssembler() const {
- return new tools::MinGW::Assembler(*this);
- }
- Tool *toolchains::MinGW::buildLinker() const {
- return new tools::MinGW::Linker(*this);
- }
- bool toolchains::MinGW::HasNativeLLVMSupport() const {
- return NativeLLVMSupport;
- }
- bool toolchains::MinGW::IsUnwindTablesDefault(const ArgList &Args) const {
- Arg *ExceptionArg = Args.getLastArg(options::OPT_fsjlj_exceptions,
- options::OPT_fseh_exceptions,
- options::OPT_fdwarf_exceptions);
- if (ExceptionArg &&
- ExceptionArg->getOption().matches(options::OPT_fseh_exceptions))
- return true;
- return getArch() == llvm::Triple::x86_64 ||
- getArch() == llvm::Triple::aarch64;
- }
- bool toolchains::MinGW::isPICDefault() const {
- return getArch() == llvm::Triple::x86_64 ||
- getArch() == llvm::Triple::aarch64;
- }
- bool toolchains::MinGW::isPIEDefault(const llvm::opt::ArgList &Args) const {
- return false;
- }
- bool toolchains::MinGW::isPICDefaultForced() const { return true; }
- llvm::ExceptionHandling
- toolchains::MinGW::GetExceptionModel(const ArgList &Args) const {
- if (getArch() == llvm::Triple::x86_64 || getArch() == llvm::Triple::aarch64)
- return llvm::ExceptionHandling::WinEH;
- return llvm::ExceptionHandling::DwarfCFI;
- }
- SanitizerMask toolchains::MinGW::getSupportedSanitizers() const {
- SanitizerMask Res = ToolChain::getSupportedSanitizers();
- Res |= SanitizerKind::Address;
- Res |= SanitizerKind::PointerCompare;
- Res |= SanitizerKind::PointerSubtract;
- Res |= SanitizerKind::Vptr;
- return Res;
- }
- void toolchains::MinGW::AddCudaIncludeArgs(const ArgList &DriverArgs,
- ArgStringList &CC1Args) const {
- CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args);
- }
- void toolchains::MinGW::AddHIPIncludeArgs(const ArgList &DriverArgs,
- ArgStringList &CC1Args) const {
- RocmInstallation.AddHIPIncludeArgs(DriverArgs, CC1Args);
- }
- void toolchains::MinGW::printVerboseInfo(raw_ostream &OS) const {
- CudaInstallation.print(OS);
- RocmInstallation.print(OS);
- }
- // Include directories for various hosts:
- // Windows, mingw.org
- // c:\mingw\lib\gcc\mingw32\4.8.1\include\c++
- // c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\mingw32
- // c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\backward
- // c:\mingw\include
- // c:\mingw\mingw32\include
- // Windows, mingw-w64 mingw-builds
- // c:\mingw32\i686-w64-mingw32\include
- // c:\mingw32\i686-w64-mingw32\include\c++
- // c:\mingw32\i686-w64-mingw32\include\c++\i686-w64-mingw32
- // c:\mingw32\i686-w64-mingw32\include\c++\backward
- // Windows, mingw-w64 msys2
- // c:\msys64\mingw32\include
- // c:\msys64\mingw32\i686-w64-mingw32\include
- // c:\msys64\mingw32\include\c++\4.9.2
- // c:\msys64\mingw32\include\c++\4.9.2\i686-w64-mingw32
- // c:\msys64\mingw32\include\c++\4.9.2\backward
- // openSUSE
- // /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++
- // /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++/x86_64-w64-mingw32
- // /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++/backward
- // /usr/x86_64-w64-mingw32/sys-root/mingw/include
- // Arch Linux
- // /usr/i686-w64-mingw32/include/c++/5.1.0
- // /usr/i686-w64-mingw32/include/c++/5.1.0/i686-w64-mingw32
- // /usr/i686-w64-mingw32/include/c++/5.1.0/backward
- // /usr/i686-w64-mingw32/include
- // Ubuntu
- // /usr/include/c++/4.8
- // /usr/include/c++/4.8/x86_64-w64-mingw32
- // /usr/include/c++/4.8/backward
- // /usr/x86_64-w64-mingw32/include
- void toolchains::MinGW::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
- ArgStringList &CC1Args) const {
- if (DriverArgs.hasArg(options::OPT_nostdinc))
- return;
- if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
- SmallString<1024> P(getDriver().ResourceDir);
- llvm::sys::path::append(P, "include");
- addSystemInclude(DriverArgs, CC1Args, P.str());
- }
- if (DriverArgs.hasArg(options::OPT_nostdlibinc))
- return;
- if (GetRuntimeLibType(DriverArgs) == ToolChain::RLT_Libgcc) {
- // openSUSE
- addSystemInclude(DriverArgs, CC1Args,
- Base + SubdirName + "/sys-root/mingw/include");
- }
- addSystemInclude(DriverArgs, CC1Args,
- Base + SubdirName + llvm::sys::path::get_separator() +
- "include");
- addSystemInclude(DriverArgs, CC1Args, Base + "include");
- }
- void toolchains::MinGW::AddClangCXXStdlibIncludeArgs(
- const ArgList &DriverArgs, ArgStringList &CC1Args) const {
- if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
- DriverArgs.hasArg(options::OPT_nostdincxx))
- return;
- StringRef Slash = llvm::sys::path::get_separator();
- switch (GetCXXStdlibType(DriverArgs)) {
- case ToolChain::CST_Libcxx: {
- std::string TargetDir = (Base + "include" + Slash + getTripleString() +
- Slash + "c++" + Slash + "v1")
- .str();
- if (getDriver().getVFS().exists(TargetDir))
- addSystemInclude(DriverArgs, CC1Args, TargetDir);
- addSystemInclude(DriverArgs, CC1Args,
- Base + SubdirName + Slash + "include" + Slash + "c++" +
- Slash + "v1");
- addSystemInclude(DriverArgs, CC1Args,
- Base + "include" + Slash + "c++" + Slash + "v1");
- break;
- }
- case ToolChain::CST_Libstdcxx:
- llvm::SmallVector<llvm::SmallString<1024>, 4> CppIncludeBases;
- CppIncludeBases.emplace_back(Base);
- llvm::sys::path::append(CppIncludeBases[0], SubdirName, "include", "c++");
- CppIncludeBases.emplace_back(Base);
- llvm::sys::path::append(CppIncludeBases[1], SubdirName, "include", "c++",
- Ver);
- CppIncludeBases.emplace_back(Base);
- llvm::sys::path::append(CppIncludeBases[2], "include", "c++", Ver);
- CppIncludeBases.emplace_back(GccLibDir);
- llvm::sys::path::append(CppIncludeBases[3], "include", "c++");
- for (auto &CppIncludeBase : CppIncludeBases) {
- addSystemInclude(DriverArgs, CC1Args, CppIncludeBase);
- CppIncludeBase += Slash;
- addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + SubdirName);
- addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + "backward");
- }
- break;
- }
- }
- static bool testTriple(const Driver &D, const llvm::Triple &Triple,
- const ArgList &Args) {
- // If an explicit sysroot is set, that will be used and we shouldn't try to
- // detect anything else.
- std::string SubdirName;
- if (D.SysRoot.size())
- return true;
- if (llvm::ErrorOr<std::string> TargetSubdir =
- findClangRelativeSysroot(D, Triple, SubdirName))
- return true;
- if (llvm::ErrorOr<std::string> GPPName = findGcc(Triple))
- return true;
- // If we neither found a colocated sysroot or a matching gcc executable,
- // conclude that we can't know if this is the correct spelling of the triple.
- return false;
- }
- static llvm::Triple adjustTriple(const Driver &D, const llvm::Triple &Triple,
- const ArgList &Args) {
- // First test if the original triple can find a sysroot with the triple
- // name.
- if (testTriple(D, Triple, Args))
- return Triple;
- llvm::SmallVector<llvm::StringRef, 3> Archs;
- // If not, test a couple other possible arch names that might be what was
- // intended.
- if (Triple.getArch() == llvm::Triple::x86) {
- Archs.emplace_back("i386");
- Archs.emplace_back("i586");
- Archs.emplace_back("i686");
- } else if (Triple.getArch() == llvm::Triple::arm ||
- Triple.getArch() == llvm::Triple::thumb) {
- Archs.emplace_back("armv7");
- }
- for (auto A : Archs) {
- llvm::Triple TestTriple(Triple);
- TestTriple.setArchName(A);
- if (testTriple(D, TestTriple, Args))
- return TestTriple;
- }
- // If none was found, just proceed with the original value.
- return Triple;
- }
- void toolchains::MinGW::fixTripleArch(const Driver &D, llvm::Triple &Triple,
- const ArgList &Args) {
- if (Triple.getArch() == llvm::Triple::x86 ||
- Triple.getArch() == llvm::Triple::arm ||
- Triple.getArch() == llvm::Triple::thumb)
- Triple = adjustTriple(D, Triple, Args);
- }
|