From 6d85b82fd996d5b49cf0b882227ef11e12acd2cc Mon Sep 17 00:00:00 2001 From: Faidon Liambotis Date: Fri, 7 Oct 2022 15:30:35 +0300 Subject: [PATCH 1/5] Fix NJOBS when DEB_BUILD_OPTIONS is not present NJOBS is supposed to have the -j argument (as in the DEB_BUILD_OPTIONS case) --- debian/rules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/rules b/debian/rules index 0ccca717..08a4bcaf 100755 --- a/debian/rules +++ b/debian/rules @@ -27,7 +27,7 @@ DEBIAN_REVISION := $(shell dpkg-parsechangelog | sed -rne "s,^Version: 1:([0-9. ifneq (,$(filter parallel=%,$(subst $(COMMA), ,$(DEB_BUILD_OPTIONS)))) NJOBS := -j $(subst parallel=,,$(filter parallel=%,$(subst $(COMMA), ,$(DEB_BUILD_OPTIONS)))) else - NJOBS := $(shell nproc) + NJOBS := -j $(shell nproc) endif VENDOR=$(shell lsb_release -is) From bcf5c6f89b64554353d57d4a55d6e0b53fe2d000 Mon Sep 17 00:00:00 2001 From: Faidon Liambotis Date: Fri, 7 Oct 2022 15:33:03 +0300 Subject: [PATCH 2/5] Build compiler-rt for wasm32 and wasm64 Current shortcomings/future work: * Unfortunately this currently takes the form of a separate, standalone build (with the just-built stage2 toolchain), which makes this a little more convoluted. The upstream compiler-rt build system does not have a way (that I could find) to manually add additional targets to the build. * GNU strip (binutils) does not understand the WebAssembly binary, so dh_strip fails. llvm-strip does, but a) does not understand all the arguments that dh_strip passes (e.g. -N), b) fails with "invalid relocation offset" on --strip-debug (but works with --strip-all). This currently passes -X to dh_strip to exclude them from being stripped entirely. Invoking llvm-strip manually with --strip-all can be considered in the future. * The wasm32/wasm64 binaries are, by design, architecture-independent. With this commit, they are being built in every architecture, and shipped in the libclang-common-X.Y-dev package, which is arch: any, but ships both architecture-dependent (native/host compiler-rt) and architecture-independent files (include headers etc.). In a future iteration, the wasm32/wasm64 compiler-rt library could be factored out to a separate (arch: all) package. This is left outstanding because it should probably happen alongside a different split for libclang-common-X.Y-dev that will include splitting the native libclang-rt as well. Closes: #1010932 --- debian/rules | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/debian/rules b/debian/rules index 08a4bcaf..78e0581e 100755 --- a/debian/rules +++ b/debian/rules @@ -713,7 +713,38 @@ else endif touch $@ -override_dh_auto_build: debian-full-build debian-libfuzzer-build debian-libclc-build +debian-rtlib-wasm-build: + echo "Using cmake: $(CMAKE_BIN)" + for build in wasm32 wasm64; do \ + mkdir -p build-compiler-rt-$$build; \ + $(CMAKE_BIN) -B build-compiler-rt-$$build -S compiler-rt/lib/builtins/ \ + -G Ninja \ + -DCMAKE_C_COMPILER_TARGET=$$build-unknown-unknown \ + -DCMAKE_CXX_COMPILER_TARGET=$$build-unknown-unknown \ + -DCMAKE_ASM_COMPILER_TARGET=$$build-unknown-unknown \ + -DCMAKE_C_COMPILER=$(STAGE_2_BIN_DIR)/clang \ + -DCMAKE_CXX_COMPILER=$(STAGE_2_BIN_DIR)/clang++ \ + -DCMAKE_C_FLAGS="$(opt_flags) $(STAGE_2_CFLAGS)" \ + -DCMAKE_CXX_FLAGS="$(opt_flags) $(STAGE_2_CXXFLAGS)" \ + -DCMAKE_SHARED_LINKER_FLAGS="$(STAGE_2_LDFLAGS) -L$(STAGE_2_LIB_DIR)" \ + -DCMAKE_MODULE_LINKER_FLAGS="$(STAGE_2_LDFLAGS) -L$(STAGE_2_LIB_DIR)" \ + -DCMAKE_EXE_LINKER_FLAGS="$(STAGE_2_LDFLAGS) -L$(STAGE_2_LIB_DIR)" \ + -DCMAKE_INSTALL_PREFIX=/usr/lib/llvm-$(LLVM_VERSION)/lib/clang/$(LLVM_VERSION_FULL) \ + -DCMAKE_INSTALL_DATADIR=lib \ + -DCMAKE_INSTALL_INCLUDEDIR=include \ + -DLLVM_CONFIG_PATH=$(STAGE_2_BIN_DIR)/llvm-config \ + -DCOMPILER_RT_STANDALONE_BUILD=ON \ + -DCOMPILER_RT_BAREMETAL_BUILD=ON \ + -DCOMPILER_RT_INCLUDE_TESTS=OFF \ + -DCOMPILER_RT_USE_LIBCXX=OFF \ + -DCOMPILER_RT_USE_BUILTINS_LIBRARY=ON \ + -DCOMPILER_RT_DEFAULT_TARGET_TRIPLE=$$build-unknown-unknown \ + -DCOMPILER_RT_OS_DIR=wasi; \ + ninja -C build-compiler-rt-$$build $(NJOBS) $(VERBOSE); \ + done + touch $@ + +override_dh_auto_build: debian-full-build debian-libfuzzer-build debian-libclc-build debian-rtlib-wasm-build override_dh_prep: build_doc dh_prep @@ -860,6 +891,9 @@ ifeq ($(LLVM_SPIRV_INSTALLED),yes) DESTDIR=$(DEB_INST) ninja $(VERBOSE) -C libclc/build install endif + DESTDIR=$(DEB_INST) ninja $(VERBOSE) -C build-compiler-rt-wasm32 install + DESTDIR=$(DEB_INST) ninja $(VERBOSE) -C build-compiler-rt-wasm64 install + # Rename binaries mkdir -p $(DEB_INST)/usr/bin/ cd $(DEB_INST)/usr/bin/; \ @@ -1007,7 +1041,9 @@ ifeq ($(shell dpkg --compare-versions $(shell dpkg-query -W -f '$${Version}' bin : # for some reasons, the +x might be removed chmod -f +x $(CURDIR)/debian/*/usr/lib/llvm-$(LLVM_VERSION)/bin/* || true else - dh_strip -a -v + # GNU strip doesn't recognize WebAssembly binaries, and actually corrupts them. + # llvm-strip (as of 15.0.2) fails with --strip-debug (but works with --strip-all) + dh_strip -a -v -Xlibclang_rt.builtins-wasm32.a -Xlibclang_rt.builtins-wasm64.a endif override_dh_install: @@ -1143,6 +1179,7 @@ override_dh_auto_clean: rm -f $(CURDIR)/clang/tools/clang-format/clang-format-diff-$(LLVM_VERSION) rm -f $(CURDIR)/clang/tools/clang-format/clang-format-$(LLVM_VERSION).py rm -rf libclc/build + rm -rf build-compiler-rt-wasm32 build-compiler-rt-wasm64 if test -f lld/docs/ld.lld-$(LLVM_VERSION).1; then \ mv lld/docs/ld.lld-$(LLVM_VERSION).1 lld/docs/ld.lld.1; \ fi @@ -1158,4 +1195,4 @@ override_dh_auto_clean: : # remove extra stamps rm -f debian-*-build -.PHONY: override_dh_strip preconfigure debian-full-build debian-libfuzzer-build debian-libclc-build +.PHONY: override_dh_strip preconfigure debian-full-build debian-libfuzzer-build debian-libclc-build debian-rtlib-wasm-build From a94a2fe7c39d209c11b41833c11aade179c8ec11 Mon Sep 17 00:00:00 2001 From: Faidon Liambotis Date: Fri, 7 Oct 2022 15:45:21 +0300 Subject: [PATCH 3/5] Default to compiler-rt for WebAssembly (wasm32/64) Our packaging overrides the upstream choice for rtlib to default always to libgcc. Unfortunately, libgcc is not available for WebAssembly (wasm32/wasm64 targets). This makes every build to -target wasm32-unknown-wasi fail, unless one passes --rtlib=compiler-rt. Patch the upstream source to default, and only accept, compiler-rt for the WebAssembly target to make everything work out of the box. This mirrors similar code that the upstream Darwin and Fuchsia targets have. GCC seems fairly far from supporting WebAssembly. If/when that day comes, this patch can be dropped. --- debian/patches/series | 1 + debian/patches/wasm-compiler-rt-default.diff | 31 ++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 debian/patches/wasm-compiler-rt-default.diff diff --git a/debian/patches/series b/debian/patches/series index be3883aa..c1e8198c 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -138,6 +138,7 @@ llvm-runtimes-builtins-build-check.diff compilerrt-builtins-arch-fix-armhf.diff compilerrt-build-scudo-standalone-option.diff wasm-ld-path.diff +wasm-compiler-rt-default.diff issue-54242.diff revert-update-doc.diff unwind-force-pthread-dl.diff diff --git a/debian/patches/wasm-compiler-rt-default.diff b/debian/patches/wasm-compiler-rt-default.diff new file mode 100644 index 00000000..351fcc79 --- /dev/null +++ b/debian/patches/wasm-compiler-rt-default.diff @@ -0,0 +1,31 @@ +--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp ++++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp +@@ -369,6 +369,18 @@ ToolChain::RuntimeLibType WebAssembly::G + return ToolChain::RLT_CompilerRT; + } + ++ToolChain::RuntimeLibType WebAssembly::GetRuntimeLibType( ++ const ArgList &Args) const { ++ if (Arg *A = Args.getLastArg(options::OPT_rtlib_EQ)) { ++ StringRef Value = A->getValue(); ++ if (Value != "compiler-rt") ++ getDriver().Diag(clang::diag::err_drv_unsupported_rtlib_for_platform) ++ << Value << "WebAssembly"; ++ } ++ ++ return ToolChain::RLT_CompilerRT; ++} ++ + ToolChain::CXXStdlibType + WebAssembly::GetCXXStdlibType(const ArgList &Args) const { + if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) { +--- a/clang/lib/Driver/ToolChains/WebAssembly.h ++++ b/clang/lib/Driver/ToolChains/WebAssembly.h +@@ -61,6 +61,7 @@ private: + llvm::opt::ArgStringList &CC1Args, + Action::OffloadKind DeviceOffloadKind) const override; + RuntimeLibType GetDefaultRuntimeLibType() const override; ++ RuntimeLibType GetRuntimeLibType(const llvm::opt::ArgList &Args) const override; + CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override; + void + AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, From 335200bf6980e34f9984deb0a2375130ed550269 Mon Sep 17 00:00:00 2001 From: Faidon Liambotis Date: Fri, 7 Oct 2022 15:48:50 +0300 Subject: [PATCH 4/5] Add support for loading wasi-libc from /usr The WebAssembly target seems to have been designed to be always passed a --sysroot, likely because of being tested to work only with the WASI-SDK. This results into passing bare, non-existing paths in include paths, such as: -internal-isystem /include/wasm32-wasi -internal-isystem /include (and similar for /lib/). In Debian, the wasi-libc package ships its files in /usr/include/wasm32-wasi, /usr/lib/wasm32-wasi etc. Add support in the target for including paths from /usr as well. To avoid changing the code in more intrusive ways (to do e.g. what the Linux target does) add a bit of an indirection where the "sysroot" defaults to "/usr" instead of the empty string. This should probably be adjusted a bit if it were to be upstreamed. Closes: #1020746 --- debian/patches/series | 1 + debian/patches/wasm-sysroot-usr.diff | 62 ++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 debian/patches/wasm-sysroot-usr.diff diff --git a/debian/patches/series b/debian/patches/series index c1e8198c..fd314c94 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -139,6 +139,7 @@ compilerrt-builtins-arch-fix-armhf.diff compilerrt-build-scudo-standalone-option.diff wasm-ld-path.diff wasm-compiler-rt-default.diff +wasm-sysroot-usr.diff issue-54242.diff revert-update-doc.diff unwind-force-pthread-dl.diff diff --git a/debian/patches/wasm-sysroot-usr.diff b/debian/patches/wasm-sysroot-usr.diff new file mode 100644 index 00000000..ae73057b --- /dev/null +++ b/debian/patches/wasm-sysroot-usr.diff @@ -0,0 +1,62 @@ +--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp ++++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp +@@ -174,7 +174,7 @@ WebAssembly::WebAssembly(const Driver &D + + getProgramPaths().push_back(getDriver().getInstalledDir()); + +- auto SysRoot = getDriver().SysRoot; ++ std::string SysRoot = computeSysRoot(); + 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 +@@ -402,6 +402,7 @@ void WebAssembly::AddClangSystemIncludeA + return; + + const Driver &D = getDriver(); ++ std::string SysRoot = computeSysRoot(); + + if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { + SmallString<128> P(D.ResourceDir); +@@ -427,10 +428,10 @@ void WebAssembly::AddClangSystemIncludeA + + if (getTriple().getOS() != llvm::Triple::UnknownOS) { + const std::string MultiarchTriple = +- getMultiarchTriple(D, getTriple(), D.SysRoot); +- addSystemInclude(DriverArgs, CC1Args, D.SysRoot + "/include/" + MultiarchTriple); ++ getMultiarchTriple(D, getTriple(), SysRoot); ++ addSystemInclude(DriverArgs, CC1Args, SysRoot + "/include/" + MultiarchTriple); + } +- addSystemInclude(DriverArgs, CC1Args, D.SysRoot + "/include"); ++ addSystemInclude(DriverArgs, CC1Args, SysRoot + "/include"); + } + + void WebAssembly::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, +@@ -478,6 +479,17 @@ Tool *WebAssembly::buildLinker() const { + return new tools::wasm::Linker(*this); + } + ++std::string WebAssembly::computeSysRoot() const { ++ if (!getDriver().SysRoot.empty()) ++ return getDriver().SysRoot; ++ ++ std::string Path = "/usr"; ++ if (getVFS().exists(Path)) ++ return Path; ++ ++ return std::string(); ++} ++ + void WebAssembly::addLibCxxIncludePaths( + const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const { +--- a/clang/lib/Driver/ToolChains/WebAssembly.h ++++ b/clang/lib/Driver/ToolChains/WebAssembly.h +@@ -89,6 +89,8 @@ private: + llvm::opt::ArgStringList &CC1Args) const; + void addLibStdCXXIncludePaths(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const; ++ ++ std::string computeSysRoot() const override; + }; + + } // end namespace toolchains From 8c6d646478b00bc32a4f7ae22a9523c60388facd Mon Sep 17 00:00:00 2001 From: Faidon Liambotis Date: Fri, 7 Oct 2022 16:48:42 +0300 Subject: [PATCH 5/5] Add changelog for the recent WebAssembly changes --- debian/changelog | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/debian/changelog b/debian/changelog index d642fe46..8b47e430 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,15 @@ +llvm-toolchain-15 (1:15.0.2-2~exp2) UNRELEASED; urgency=medium + + * Add better support for the WebAssembly (wasm32/wasm64) targets: + - Ship compiler-rt for the wasm32 and wasm64 targets. (Closes: #1010932) + - Add patch wasm-compiler-rt-default.diff to default to compiler-rt for + these targets. libgcc does not currently exist for WebAssembly in neither + Debian nor upstream, and therefore compiler-rt is the only option. + - Add patch wasm-sysroot-usr.diff to support a system-installed (i.e. shipped + in /usr) wasi-libc. (Closes: #1020746) + + -- Faidon Liambotis Fri, 07 Oct 2022 16:44:57 +0300 + llvm-toolchain-15 (1:15.0.2-2~exp1) experimental; urgency=medium * Ship bolt