diff options
author | Daniel Bertalan <dani@danielbertalan.dev> | 2021-11-20 16:48:14 +0100 |
---|---|---|
committer | Brian Gianforcaro <b.gianfo@gmail.com> | 2021-11-28 09:38:57 -0800 |
commit | b1f6bfca7fbba32f020f85619826e83901a812c1 (patch) | |
tree | c2ed1fe3bc05e71425a64d18f065908ddbab5fd7 /Toolchain/Patches | |
parent | ce3b2190211292a704da413501afc9e502c0f148 (diff) | |
download | serenity-b1f6bfca7fbba32f020f85619826e83901a812c1.zip |
Toolchain/Clang: Support using `libstdc++` as the C++ standard library
This will come in handy if we want to use the LLVM port with a GNU host
compiler.
As of version 13, libc++ uses `__attribute__((using_if_exists))` to
import global LibC functions into the `std` namespace, which allows some
symbols to be absent. GCC does not support this attribute, so it fails
to build libc++ due to some obscure `wchar.h` functions. This means that
cross-compiling libc++ is not possible; and on-target builds would be
tedious, so we'll be better off using the toolchain's `libstdc++`.
Diffstat (limited to 'Toolchain/Patches')
-rw-r--r-- | Toolchain/Patches/llvm.patch | 60 |
1 files changed, 53 insertions, 7 deletions
diff --git a/Toolchain/Patches/llvm.patch b/Toolchain/Patches/llvm.patch index 88f73d824d..2f781da8cc 100644 --- a/Toolchain/Patches/llvm.patch +++ b/Toolchain/Patches/llvm.patch @@ -136,10 +136,10 @@ index 58ae08a38..8e9a3fee6 100644 options::OPT_foperator_names, false)) diff --git a/clang/lib/Driver/ToolChains/Serenity.cpp b/clang/lib/Driver/ToolChains/Serenity.cpp new file mode 100644 -index 000000000..461f55ad3 +index 000000000..4d653d86f --- /dev/null +++ b/clang/lib/Driver/ToolChains/Serenity.cpp -@@ -0,0 +1,281 @@ +@@ -0,0 +1,327 @@ +//===---- Serenity.cpp - SerenityOS ToolChain Implementation ----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. @@ -158,6 +158,7 @@ index 000000000..461f55ad3 +#include "clang/Driver/SanitizerArgs.h" +#include "llvm/Option/ArgList.h" +#include "llvm/Support/VirtualFileSystem.h" ++#include <string> + +using namespace clang::driver; +using namespace clang::driver::toolchains; @@ -348,28 +349,73 @@ index 000000000..461f55ad3 + + addSystemInclude(DriverArgs, CC1Args, D.SysRoot + "/usr/local/include"); + addSystemInclude(DriverArgs, CC1Args, D.SysRoot + "/usr/include"); ++} ++ ++static std::string getLibStdCXXVersion(const Driver &D, StringRef IncludePath) { ++ SmallString<128> Path(IncludePath); ++ llvm::sys::path::append(Path, "c++"); ++ ++ std::error_code EC; ++ std::tuple<int, int, int> Newest{0, 0, 0}; ++ std::string Result; ++ ++ for (llvm::vfs::directory_iterator LI = D.getVFS().dir_begin(Path, EC), LE; ++ !EC && LI != LE; LI = LI.increment(EC)) { ++ StringRef VersionText = llvm::sys::path::filename(LI->path()); ++ ++ // This is libc++ ++ if (VersionText[0] == 'v') ++ continue; ++ ++ llvm::SmallVector<StringRef, 3> Parts; ++ VersionText.split(Parts, '.'); ++ ++ // SerenityOS always builds GCC with <major>.<minor>.<patch> versions ++ if (Parts.size() < 3) ++ continue; ++ ++ std::tuple<int, int, int> Current; ++ if (!llvm::to_integer(Parts[0], std::get<0>(Current))) ++ continue; ++ if (!llvm::to_integer(Parts[1], std::get<1>(Current))) ++ continue; ++ if (!llvm::to_integer(Parts[2], std::get<2>(Current))) ++ continue; ++ ++ if (Current > Newest) { ++ Newest = Current; ++ Result = VersionText.str(); ++ } + } ++ return Result; +} + +void Serenity::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const { + if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdincxx, -+ +options::OPT_nostdlibinc)) ++ options::OPT_nostdlibinc)) + return; + -+ if (GetCXXStdlibType(DriverArgs) != ToolChain::CST_Libcxx) -+ llvm_unreachable("Only libc++ is supported on the Serenity target"); ++ const auto StdLib = GetCXXStdlibType(DriverArgs); + + const Driver &D = getDriver(); + std::string SysRoot = computeSysRoot(); + std::string Target = getTripleString(); + + auto AddIncludePath = [&](std::string Path) { -+ std::string Version = detectLibcxxVersion(Path); ++ std::string Version = StdLib == CXXStdlibType::CST_Libstdcxx ++ ? getLibStdCXXVersion(D, Path) ++ : detectLibcxxVersion(Path); + if (Version.empty()) + return false; + -+ std::string TargetDir = Path + "/" + Target + "/c++/" + Version; ++ std::string TargetDir; ++ if (StdLib == CXXStdlibType::CST_Libstdcxx) { ++ TargetDir = Path + "/c++/" + Version + "/" + Target; ++ } else { ++ TargetDir = Path + "/" + Target + "/c++/" + Version; ++ } ++ + if (D.getVFS().exists(TargetDir)) + addSystemInclude(DriverArgs, CC1Args, TargetDir); + |