michaelplatings updated this revision to Diff 529318. michaelplatings added a comment.
Rebase Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D143075/new/ https://reviews.llvm.org/D143075 Files: clang/lib/Driver/ToolChains/BareMetal.cpp clang/lib/Driver/ToolChains/BareMetal.h clang/test/Driver/baremetal-multilib-layered.yaml
Index: clang/test/Driver/baremetal-multilib-layered.yaml =================================================================== --- /dev/null +++ clang/test/Driver/baremetal-multilib-layered.yaml @@ -0,0 +1,45 @@ +# REQUIRES: shell +# UNSUPPORTED: system-windows + +# This test demonstrates "layered" multilib in which more than one +# multilib is matched. +# For example a multilib containing only a no-exceptions libc++ could +# be layered on top of a multilib containing C libs. This avoids the +# need to duplicate the C library for every libc++ variant. +# However -fno-exceptions is not yet supported for multilib selection +# so we use a more contrived -mfloat-abi example instead. + +# RUN: rm -rf %T/baremetal_multilib_layered +# RUN: mkdir -p %T/baremetal_multilib_layered/bin +# RUN: mkdir -p %T/baremetal_multilib_layered/lib/clang-runtimes +# RUN: ln -s %clang %T/baremetal_multilib_layered/bin/clang +# RUN: ln -s %s %T/baremetal_multilib_layered/lib/clang-runtimes/multilib.yaml + +# RUN: %T/baremetal_multilib_layered/bin/clang -no-canonical-prefixes -x c++ %s -### -o %t.out 2>&1 \ +# RUN: --target=thumbv7m-none-eabi -mfloat-abi=softfp --sysroot= \ +# RUN: | FileCheck -DSYSROOT=%T/baremetal_multilib_layered %s +# CHECK: "-cc1" "-triple" "thumbv7m-none-unknown-eabi" +# CHECK-SAME: "-internal-isystem" "[[SYSROOT]]/bin/../lib/clang-runtimes/softfp/include/c++/v1" +# CHECK-SAME: "-internal-isystem" "[[SYSROOT]]/bin/../lib/clang-runtimes/soft/include/c++/v1" +# CHECK-SAME: "-internal-isystem" "[[SYSROOT]]/bin/../lib/clang-runtimes/softfp/include" +# CHECK-SAME: "-internal-isystem" "[[SYSROOT]]/bin/../lib/clang-runtimes/soft/include" +# CHECK-NEXT: "-L[[SYSROOT]]/bin/../lib/clang-runtimes/softfp/lib" +# CHECK-SAME: "-L[[SYSROOT]]/bin/../lib/clang-runtimes/soft/lib" + +# RUN: %T/baremetal_multilib_layered/bin/clang -no-canonical-prefixes -print-multi-directory 2>&1 \ +# RUN: --target=arm-none-eabi -mfloat-abi=softfp --sysroot= \ +# RUN: | FileCheck --check-prefix=CHECK-PRINT-MULTI-DIRECTORY %s +# CHECK-PRINT-MULTI-DIRECTORY: soft +# CHECK-PRINT-MULTI-DIRECTORY-NEXT: softfp + +--- +MultilibVersion: 1.0 +Variants: +- Dir: soft + Flags: [-mfloat-abi=soft] +- Dir: softfp + Flags: [-mfloat-abi=softfp] +FlagMap: +- Match: -mfloat-abi=softfp + Flags: [-mfloat-abi=soft] +... Index: clang/lib/Driver/ToolChains/BareMetal.h =================================================================== --- clang/lib/Driver/ToolChains/BareMetal.h +++ clang/lib/Driver/ToolChains/BareMetal.h @@ -71,6 +71,10 @@ void AddLinkRuntimeLib(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const; std::string computeSysRoot() const override; + +private: + llvm::iterator_range<llvm::SmallVector<Multilib>::const_reverse_iterator> + getOrderedMultilibs() const; }; } // namespace toolchains Index: clang/lib/Driver/ToolChains/BareMetal.cpp =================================================================== --- clang/lib/Driver/ToolChains/BareMetal.cpp +++ clang/lib/Driver/ToolChains/BareMetal.cpp @@ -105,9 +105,12 @@ findMultilibs(D, Triple, Args); SmallString<128> SysRoot(computeSysRoot()); if (!SysRoot.empty()) { - llvm::sys::path::append(SysRoot, "lib"); - getFilePaths().push_back(std::string(SysRoot)); - getLibraryPaths().push_back(std::string(SysRoot)); + for (const Multilib &M : getOrderedMultilibs()) { + SmallString<128> Dir(SysRoot); + llvm::sys::path::append(Dir, M.osSuffix(), "lib"); + getFilePaths().push_back(std::string(Dir)); + getLibraryPaths().push_back(std::string(Dir)); + } } } @@ -224,10 +227,23 @@ } std::string BareMetal::computeSysRoot() const { - std::string Result = computeBaseSysRoot(getDriver(), getTriple()); - if (!SelectedMultilibs.empty()) - Result += SelectedMultilibs.back().osSuffix(); - return Result; + return computeBaseSysRoot(getDriver(), getTriple()); +} + +llvm::iterator_range<llvm::SmallVector<Multilib>::const_reverse_iterator> +BareMetal::getOrderedMultilibs() const { + // Get multilibs in reverse order because they're ordered most-specific last. + if (!SelectedMultilibs.empty()) { + return llvm::iterator_range< + llvm::SmallVector<Multilib>::const_reverse_iterator>( + SelectedMultilibs.rbegin(), SelectedMultilibs.rend()); + } + + // No multilibs selected so return a single default multilib. + static llvm::SmallVector<Multilib> Default = {Multilib()}; + return llvm::iterator_range< + llvm::SmallVector<Multilib>::const_reverse_iterator>(Default.rbegin(), + Default.rend()); } void BareMetal::AddClangSystemIncludeArgs(const ArgList &DriverArgs, @@ -242,10 +258,14 @@ } if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) { - SmallString<128> Dir(computeSysRoot()); - if (!Dir.empty()) { - llvm::sys::path::append(Dir, "include"); - addSystemInclude(DriverArgs, CC1Args, Dir.str()); + const SmallString<128> SysRoot(computeSysRoot()); + if (!SysRoot.empty()) { + for (const Multilib &M : getOrderedMultilibs()) { + SmallString<128> Dir(SysRoot); + llvm::sys::path::append(Dir, M.includeSuffix()); + llvm::sys::path::append(Dir, "include"); + addSystemInclude(DriverArgs, CC1Args, Dir.str()); + } } } } @@ -268,44 +288,47 @@ if (SysRoot.empty()) return; - switch (GetCXXStdlibType(DriverArgs)) { - case ToolChain::CST_Libcxx: { - // First check sysroot/usr/include/c++/v1 if it exists. - SmallString<128> TargetDir(SysRoot); - llvm::sys::path::append(TargetDir, "usr", "include", "c++", "v1"); - if (D.getVFS().exists(TargetDir)) { - addSystemInclude(DriverArgs, CC1Args, TargetDir.str()); + for (const Multilib &M : getOrderedMultilibs()) { + SmallString<128> Dir(SysRoot); + llvm::sys::path::append(Dir, M.gccSuffix()); + switch (GetCXXStdlibType(DriverArgs)) { + case ToolChain::CST_Libcxx: { + // First check sysroot/usr/include/c++/v1 if it exists. + SmallString<128> TargetDir(Dir); + llvm::sys::path::append(TargetDir, "usr", "include", "c++", "v1"); + if (D.getVFS().exists(TargetDir)) { + addSystemInclude(DriverArgs, CC1Args, TargetDir.str()); + break; + } + // Add generic path if nothing else succeeded so far. + llvm::sys::path::append(Dir, "include", "c++", "v1"); + addSystemInclude(DriverArgs, CC1Args, Dir.str()); + break; + } + case ToolChain::CST_Libstdcxx: { + llvm::sys::path::append(Dir, "include", "c++"); + std::error_code EC; + Generic_GCC::GCCVersion Version = {"", -1, -1, -1, "", "", ""}; + // Walk the subdirs, and find the one with the newest gcc version: + for (llvm::vfs::directory_iterator + LI = D.getVFS().dir_begin(Dir.str(), EC), + LE; + !EC && LI != LE; LI = LI.increment(EC)) { + StringRef VersionText = llvm::sys::path::filename(LI->path()); + auto CandidateVersion = Generic_GCC::GCCVersion::Parse(VersionText); + if (CandidateVersion.Major == -1) + continue; + if (CandidateVersion <= Version) + continue; + Version = CandidateVersion; + } + if (Version.Major != -1) { + llvm::sys::path::append(Dir, Version.Text); + addSystemInclude(DriverArgs, CC1Args, Dir.str()); + } break; } - // Add generic path if nothing else succeeded so far. - SmallString<128> Dir(SysRoot); - llvm::sys::path::append(Dir, "include", "c++", "v1"); - addSystemInclude(DriverArgs, CC1Args, Dir.str()); - break; - } - case ToolChain::CST_Libstdcxx: { - SmallString<128> Dir(SysRoot); - llvm::sys::path::append(Dir, "include", "c++"); - std::error_code EC; - Generic_GCC::GCCVersion Version = {"", -1, -1, -1, "", "", ""}; - // Walk the subdirs, and find the one with the newest gcc version: - for (llvm::vfs::directory_iterator LI = D.getVFS().dir_begin(Dir.str(), EC), - LE; - !EC && LI != LE; LI = LI.increment(EC)) { - StringRef VersionText = llvm::sys::path::filename(LI->path()); - auto CandidateVersion = Generic_GCC::GCCVersion::Parse(VersionText); - if (CandidateVersion.Major == -1) - continue; - if (CandidateVersion <= Version) - continue; - Version = CandidateVersion; } - if (Version.Major == -1) - return; - llvm::sys::path::append(Dir, Version.Text); - addSystemInclude(DriverArgs, CC1Args, Dir.str()); - break; - } } }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits