mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-04 05:20:30 +00:00
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++`.
This commit is contained in:
parent
ce3b219021
commit
b1f6bfca7f
Notes:
sideshowbarker
2024-07-18 00:35:10 +09:00
Author: https://github.com/BertalanD Commit: https://github.com/SerenityOS/serenity/commit/b1f6bfca7fb Pull-request: https://github.com/SerenityOS/serenity/pull/10996 Reviewed-by: https://github.com/timschumi ✅
1 changed files with 53 additions and 7 deletions
|
@ -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);
|
||||
+
|
||||
|
|
Loading…
Reference in a new issue