]> granicus.if.org Git - clang/commitdiff
[WebAssembly] Support multilibs for wasm32 and add a wasm OS that uses it
authorDan Gohman <dan433584@gmail.com>
Tue, 15 Jan 2019 06:58:16 +0000 (06:58 +0000)
committerDan Gohman <dan433584@gmail.com>
Tue, 15 Jan 2019 06:58:16 +0000 (06:58 +0000)
This adds support for multilib paths for wasm32 targets, following
[Debian's Multiarch conventions], and also adds an experimental OS name in
order to test it.

[Debian's Multiarch conventions]: https://wiki.debian.org/Multiarch/

Differential Revision: https://reviews.llvm.org/D56553

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@351164 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Basic/Targets.cpp
lib/Driver/ToolChains/WebAssembly.cpp
test/Driver/wasm-toolchain.c
test/Driver/wasm-toolchain.cpp

index f79da4e5761f7c4aa7193ae61b1ac89ed4df371a..fd201a9adda63d4c30e7a016cebca682320445bb 100644 (file)
@@ -572,17 +572,19 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple,
   case llvm::Triple::wasm32:
     if (Triple.getSubArch() != llvm::Triple::NoSubArch ||
         Triple.getVendor() != llvm::Triple::UnknownVendor ||
-        Triple.getOS() != llvm::Triple::UnknownOS ||
-        Triple.getEnvironment() != llvm::Triple::UnknownEnvironment ||
-        !(Triple.isOSBinFormatELF() || Triple.isOSBinFormatWasm()))
+        !Triple.isOSBinFormatWasm())
+      return nullptr;
+    if (Triple.getOS() != llvm::Triple::UnknownOS &&
+        Triple.getOS() != llvm::Triple::COWS)
       return nullptr;
     return new WebAssemblyOSTargetInfo<WebAssembly32TargetInfo>(Triple, Opts);
   case llvm::Triple::wasm64:
     if (Triple.getSubArch() != llvm::Triple::NoSubArch ||
         Triple.getVendor() != llvm::Triple::UnknownVendor ||
-        Triple.getOS() != llvm::Triple::UnknownOS ||
-        Triple.getEnvironment() != llvm::Triple::UnknownEnvironment ||
-        !(Triple.isOSBinFormatELF() || Triple.isOSBinFormatWasm()))
+        !Triple.isOSBinFormatWasm())
+      return nullptr;
+    if (Triple.getOS() != llvm::Triple::UnknownOS &&
+        Triple.getOS() != llvm::Triple::COWS)
       return nullptr;
     return new WebAssemblyOSTargetInfo<WebAssembly64TargetInfo>(Triple, Opts);
 
index 6776a41dad06747995b30beafd7ad2a7f46fde7e..6310d5fabaec89d4718160f31d4dafc4891e74fb 100644 (file)
@@ -24,6 +24,15 @@ using namespace llvm::opt;
 wasm::Linker::Linker(const ToolChain &TC)
     : GnuTool("wasm::Linker", "lld", TC) {}
 
+/// Following the conventions in https://wiki.debian.org/Multiarch/Tuples,
+/// we remove the vendor field to form the multiarch triple.
+static std::string getMultiarchTriple(const Driver &D,
+                                      const llvm::Triple &TargetTriple,
+                                      StringRef SysRoot) {
+    return (TargetTriple.getArchName() + "-" +
+            TargetTriple.getOSAndEnvironmentName()).str();
+}
+
 bool wasm::Linker::isLinkJob() const { return true; }
 
 bool wasm::Linker::hasIntegratedCPP() const { return false; }
@@ -75,7 +84,17 @@ WebAssembly::WebAssembly(const Driver &D, const llvm::Triple &Triple,
 
   getProgramPaths().push_back(getDriver().getInstalledDir());
 
-  getFilePaths().push_back(getDriver().SysRoot + "/lib");
+  if (getTriple().getOS() == llvm::Triple::UnknownOS) {
+    // Theoretically an "unknown" OS should mean no standard libraries, however
+    // it could also mean that a custom set of libraries is in use, so just add
+    // /lib to the search path. Disable multiarch in this case, to discourage
+    // paths containing "unknown" from acquiring meanings.
+    getFilePaths().push_back(getDriver().SysRoot + "/lib");
+  } else {
+    const std::string MultiarchTriple =
+        getMultiarchTriple(getDriver(), Triple, getDriver().SysRoot);
+    getFilePaths().push_back(getDriver().SysRoot + "/lib/" + MultiarchTriple);
+  }
 }
 
 bool WebAssembly::IsMathErrnoDefault() const { return false; }
@@ -124,16 +143,29 @@ WebAssembly::GetCXXStdlibType(const ArgList &Args) const {
 
 void WebAssembly::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
                                             ArgStringList &CC1Args) const {
-  if (!DriverArgs.hasArg(options::OPT_nostdinc))
+  if (!DriverArgs.hasArg(options::OPT_nostdinc)) {
+    if (getTriple().getOS() != llvm::Triple::UnknownOS) {
+      const std::string MultiarchTriple =
+          getMultiarchTriple(getDriver(), getTriple(), getDriver().SysRoot);
+      addSystemInclude(DriverArgs, CC1Args, getDriver().SysRoot + "/include/" + MultiarchTriple);
+    }
     addSystemInclude(DriverArgs, CC1Args, getDriver().SysRoot + "/include");
+  }
 }
 
 void WebAssembly::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
                                                ArgStringList &CC1Args) const {
   if (!DriverArgs.hasArg(options::OPT_nostdlibinc) &&
-      !DriverArgs.hasArg(options::OPT_nostdincxx))
+      !DriverArgs.hasArg(options::OPT_nostdincxx)) {
+    if (getTriple().getOS() != llvm::Triple::UnknownOS) {
+      const std::string MultiarchTriple =
+          getMultiarchTriple(getDriver(), getTriple(), getDriver().SysRoot);
+      addSystemInclude(DriverArgs, CC1Args,
+                       getDriver().SysRoot + "/include/" + MultiarchTriple + "/c++/v1");
+    }
     addSystemInclude(DriverArgs, CC1Args,
                      getDriver().SysRoot + "/include/c++/v1");
+  }
 }
 
 void WebAssembly::AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
index 3d4c23a2b8007483a346ac2a82749e3a404ce3ca..59ecd0ac077ce5e4a2d1aa4c45d81b6b014fa844 100644 (file)
 // RUN: %clang %s -### -target wasm32-unknown-unknown -fvisibility=default 2>&1 | FileCheck -check-prefix=FVISIBILITY_DEFAULT %s
 // FVISIBILITY_DEFAULT-NOT: hidden
 
-// A basic C link command-line.
+// A basic C link command-line with unknown OS.
 
 // RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo -fuse-ld=wasm-ld %s 2>&1 | FileCheck -check-prefix=LINK %s
 // LINK: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
 // LINK: wasm-ld{{.*}}" "-L/foo/lib" "crt1.o" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
 
-// A basic C link command-line with optimization.
+// A basic C link command-line with optimization with unknown OS.
 
 // RUN: %clang -### -O2 -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo -fuse-ld=wasm-ld %s 2>&1 | FileCheck -check-prefix=LINK_OPT %s
 // LINK_OPT: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
 // LINK_OPT: wasm-ld{{.*}}" "-L/foo/lib" "crt1.o" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
+
+// A basic C link command-line with known OS.
+
+// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-cows-musl --sysroot=/foo -fuse-ld=wasm-ld %s 2>&1 | FileCheck -check-prefix=LINK_KNOWN %s
+// LINK_KNOWN: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
+// LINK_KNOWN: wasm-ld{{.*}}" "-L/foo/lib/wasm32-cows-musl" "crt1.o" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
+
+// A basic C link command-line with optimization with known OS.
+
+// RUN: %clang -### -O2 -no-canonical-prefixes -target wasm32-unknown-cows-musl --sysroot=/foo -fuse-ld=wasm-ld %s 2>&1 | FileCheck -check-prefix=LINK_OPT_KNOWN %s
+// LINK_OPT_KNOWN: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
+// LINK_OPT_KNOWN: wasm-ld{{.*}}" "-L/foo/lib/wasm32-cows-musl" "crt1.o" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
+
+// A basic C compile command-line with known OS.
+
+// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-cows-musl --sysroot=/foo %s 2>&1 | FileCheck -check-prefix=COMPILE %s
+// COMPILE: clang{{.*}}" "-cc1" {{.*}} "-internal-isystem" "/foo/include/wasm32-cows-musl" "-internal-isystem" "/foo/include"
index b20eafe19ae2ac013875ffa87e89ada32265c230..db549e4714ba309f0c07f06d87f79b283df70e25 100644 (file)
 // RUN: %clangxx %s -### -target wasm32-unknown-unknown -fvisibility=default 2>&1 | FileCheck -check-prefix=FVISIBILITY_DEFAULT %s
 // FVISIBILITY_DEFAULT-NOT: hidden
 
-// A basic C++ link command-line.
+// A basic C++ link command-line with unknown OS.
 
-// RUN: %clangxx -### -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo --stdlib=c++ -fuse-ld=wasm-ld %s 2>&1 | FileCheck -check-prefix=LINK %s
+// RUN: %clangxx -### -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo -fuse-ld=wasm-ld --stdlib=c++ %s 2>&1 | FileCheck -check-prefix=LINK %s
 // LINK: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
 // LINK: wasm-ld{{.*}}" "-L/foo/lib" "crt1.o" "[[temp]]" "-lc++" "-lc++abi" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
 
-// A basic C++ link command-line with optimization.
+// A basic C++ link command-line with optimization with unknown OS.
 
 // RUN: %clangxx -### -O2 -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo %s --stdlib=c++ -fuse-ld=wasm-ld 2>&1 | FileCheck -check-prefix=LINK_OPT %s
 // LINK_OPT: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
 // LINK_OPT: wasm-ld{{.*}}" "-L/foo/lib" "crt1.o" "[[temp]]" "-lc++" "-lc++abi" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
+
+// A basic C++ link command-line with known OS.
+
+// RUN: %clangxx -### -no-canonical-prefixes -target wasm32-unknown-cows-musl --sysroot=/foo -fuse-ld=wasm-ld --stdlib=c++ %s 2>&1 | FileCheck -check-prefix=LINK_KNOWN %s
+// LINK_KNOWN: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
+// LINK_KNOWN: wasm-ld{{.*}}" "-L/foo/lib/wasm32-cows-musl" "crt1.o" "[[temp]]" "-lc++" "-lc++abi" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
+
+// A basic C++ link command-line with optimization with known OS.
+
+// RUN: %clangxx -### -O2 -no-canonical-prefixes -target wasm32-unknown-cows-musl --sysroot=/foo %s --stdlib=c++ -fuse-ld=wasm-ld 2>&1 | FileCheck -check-prefix=LINK_OPT_KNOWN %s
+// LINK_OPT_KNOWN: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
+// LINK_OPT_KNOWN: wasm-ld{{.*}}" "-L/foo/lib/wasm32-cows-musl" "crt1.o" "[[temp]]" "-lc++" "-lc++abi" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
+
+// A basic C++ compile command-line with known OS.
+
+// RUN: %clangxx -### -no-canonical-prefixes -target wasm32-unknown-cows-musl --sysroot=/foo --stdlib=c++ %s 2>&1 | FileCheck -check-prefix=COMPILE %s
+// COMPILE: clang{{.*}}" "-cc1" {{.*}} "-internal-isystem" "/foo/include/wasm32-cows-musl/c++/v1" "-internal-isystem" "/foo/include/c++/v1" "-internal-isystem" "/foo/include/wasm32-cows-musl" "-internal-isystem" "/foo/include"