Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Bug#1010932: wasm-ld-13: unable to find library -lgcc

873 views
Skip to first unread message

Jérémy Lal

unread,
May 13, 2022, 9:00:04 AM5/13/22
to
Package: lld-13
Version: 1:13.0.1-4
Severity: normal


Hi,

I am trying to build llhttp, an indirect dependency of nodejs 16.5.0.

Using the recommended method is:

/usr/bin/clang -v --sysroot=/usr -target wasm32-unknown-wasi -Ofast -fno-exceptions -fvisibility=hidden -mexec-model=reactor -Wl,-error-limit=0 -Wl,-O3 -Wl,--lto-O3 -Wl,--strip-all -Wl,--allow-undefined -Wl,--export-dynamic -Wl,--export-table -Wl,--export=malloc -Wl,--export=free /home/dev/Software/debian/node-undici/js-team/deps/llhttp/src/*.c -I/home/dev/Software/debian/node-undici/js-team/deps/llhttp/include -o /home/dev/Software/debian/node-undici/js-team/lib/llhttp/llhttp.wasm

(I installed wasi-libc, lld, llvm, clang)
however, the result is:

"/usr/bin/wasm-ld-13" -m wasm32 -L/usr/lib/wasm32-wasi /usr/lib/wasm32-wasi/crt1-reactor.o --entry _initialize -error-limit=0 -O3 --lto-O3 --strip-all --allow-undefined --export-dynamic --export-table --export=malloc --export=free /tmp/api-1a4e87.o /tmp/http-f5ff3b.o /tmp/llhttp-f86505.o -lc -lgcc -o /home/dev/Software/debian/node-undici/js-team/lib/llhttp/llhttp.wasm
wasm-ld-13: error: unable to find library -lgcc

I apt-installed more packages, like libunwind-dev and libc++, libclang-cpp, etc...
but it still fails.

So maybe it's a problem with llvm, after all ?

Jérémy

-- System Information:
Debian Release: bookworm/sid
APT prefers unstable
APT policy: (500, 'unstable'), (101, 'testing')
Architecture: amd64 (x86_64)

Kernel: Linux 5.17.0-1-amd64 (SMP w/4 CPU threads; PREEMPT)
Kernel taint flags: TAINT_WARN
Locale: LANG=fr_FR.utf8, LC_CTYPE=fr_FR.utf8 (charmap=UTF-8), LANGUAGE not set
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

Versions of packages lld-13 depends on:
ii libc6 2.33-7
ii libgcc-s1 12.1.0-1
ii libllvm13 1:13.0.1-4
ii libstdc++6 12.1.0-1

lld-13 recommends no packages.

lld-13 suggests no packages.

-- no debconf information

Jérémy Lal

unread,
May 13, 2022, 9:20:04 AM5/13/22
to
Package: lld-13
Version: 1:13.0.1-4
Followup-For: Bug #1010932

Addendum:
"/usr/bin/wasm-ld-13" -m wasm32 -L/usr/lib/wasm32-wasi /usr/lib/wasm32-wasi/crt1-reactor.o --entry _initialize -error-limit=0 -O3 --lto-O3 --strip-all --allow-undefined --export-dynamic --export-table --export=malloc --export=free /tmp/api-1a4e87.o /tmp/http-f5ff3b.o /tmp/llhttp-f86505.o -lc -lgcc -o /home/dev/Software/debian/node-undici/js-team/lib/llhttp/llhttp.wasm
wasm-ld-13: error: unable to find library -lgcc

does not fail if I just remove the "-lgcc" flag.
However, that line is generated by clang.

Jérémy Lal

unread,
May 14, 2022, 8:50:03 AM5/14/22
to
Le ven. 13 mai 2022 à 15:08, Jérémy Lal <kap...@melix.org> a écrit :
Package: lld-13
Version: 1:13.0.1-4
Followup-For: Bug #1010932

Addendum:
 "/usr/bin/wasm-ld-13" -m wasm32 -L/usr/lib/wasm32-wasi /usr/lib/wasm32-wasi/crt1-reactor.o --entry _initialize -error-limit=0 -O3 --lto-O3 --strip-all --allow-undefined --export-dynamic --export-table --export=malloc --export=free /tmp/api-1a4e87.o /tmp/http-f5ff3b.o /tmp/llhttp-f86505.o -lc -lgcc -o /home/dev/Software/debian/node-undici/js-team/lib/llhttp/llhttp.wasm
wasm-ld-13: error: unable to find library -lgcc

does not fail if I just remove the "-lgcc" flag.
However, that line is generated by clang.

To workaround that issue, I found out that a combination of
-nodefaultlibs -Wl,-lc
flags work.

Still, something's wrong.

Jérémy 

Faidon Liambotis

unread,
Jul 7, 2022, 8:30:03 PM7/7/22
to
Hi Jérémy,

On Sat, May 14, 2022 at 02:44:25PM +0200, Jérémy Lal wrote:
> > Addendum:
> > "/usr/bin/wasm-ld-13" -m wasm32 -L/usr/lib/wasm32-wasi
> > /usr/lib/wasm32-wasi/crt1-reactor.o --entry _initialize -error-limit=0 -O3
> > --lto-O3 --strip-all --allow-undefined --export-dynamic --export-table
> > --export=malloc --export=free /tmp/api-1a4e87.o /tmp/http-f5ff3b.o
> > /tmp/llhttp-f86505.o -lc -lgcc -o
> > /home/dev/Software/debian/node-undici/js-team/lib/llhttp/llhttp.wasm
> > wasm-ld-13: error: unable to find library -lgcc
> >
> > does not fail if I just remove the "-lgcc" flag.
> > However, that line is generated by clang.
>
> To workaround that issue, I found out that a combination of
> -nodefaultlibs -Wl,-lc
> flags work.
>
> Still, something's wrong.

I'm not one of the LLVM maintainers, but I was debugging something
related today and came across your bug, so thought I'd do a drive-by
comment that would perhaps be helpful.

A few different things are going on here:

* The compiler requires a low-level compiler runtime, as it often emits
code that would need to use it. This can either be libgcc, or LLVM's
compiler-rt. Clang's default is conditional on the platform, but
Debian sets this unconditionally to libgcc (see
-DCLANG_DEFAULT_RTLIB=libgcc in llvm's debian/rules).

One can set this at runtime, regardless of default, by passing the
--rtlib option, such as --rtlib=compiler-rt or --rtlib=libgcc (the
latter will always be a no-op on a Debian system, as that is always
the default)

See https://gcc.gnu.org/onlinedocs/gccint/Libgcc.html for more
information about libgcc, and more importantly, clang's reference:
https://clang.llvm.org/docs/Toolchain.html#compiler-runtime

* I don't believe anyone has ever built gcc/libgcc for a wasm32-wasi
target. So the only option to my knowledge here is to use compiler-rt,
by passing --rtlib=compiler-rt.

* Unfortunately, I don't believe that a wasm32 build of compiler-rt
(filename: libclang_rt.builtins-wasm32.a) is shipped by any package in
any architecture in Debian.

In general, it looks like libclang-common-${version}-dev just ships
the architecture-native build, and that no "cross" package exists.

For libgcc, cross packages exist, e.g. one can install
libgcc-s1-arm64-cross on an amd64 system and get an arm64
binary. (But again, no wasm32 port for libgcc...)

* The wasi-sdk project ships libclang_rt.builtins-wasm32.a as part of
the SDK tarball, but also separately, in a libclang_rt tarball. For
example, with wasi-sdk-16, this can be downloaded here:
https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-16/libclang_rt.builtins-wasm32-wasi-16.0.tar.gz

This should be extracted under /usr/lib/llvm-14/lib/clang/14.0.6,
which would make this file available:
/usr/lib/llvm-14/lib/clang/14.0.6/lib/wasi/libclang_rt.builtins-wasm32.a

After downloading this file as above, and passing --rtlib=compiler-rt to
CFLAGS, the problem you are seeing should be fixed.

This bug can probably be retitled/repurposed to request for a way for
ship libclang_rt.builtins-wasm32-wasi to be shipped in Debian. (I suspect
this may be quite a large endeavor and especially if one were to include
the generic case of cross-compiling into this.)

Hope this helps!

Best,
Faidon

Faidon Liambotis

unread,
Sep 25, 2022, 6:00:04 PM9/25/22
to
Control: reassign -1 libclang-common-14-dev 1:14.0.6-2
Control: retitle -1 Please build and ship compiler-rt for wasm32/wasm64
Tags: patch

Dear maintainer,

clang in Debian right now can build to the wasm32-unknown-wasi target,
as well as the less commonly used wasm64-unknown-wasi target. However,
their use is very limited, as there is no available builtins library in
Debian.

libgcc is not available for WebAssembly. compiler-rt, however, is, and
is what the WASI SDK ships with. Unfortunately it is not being shipped
in Debian right now.

In other words, this is a request to build and ship:
/usr/lib/llvm-14/lib/clang/14.0.6/lib/wasi/libclang_rt.builtins-wasm32.a
/usr/lib/llvm-14/lib/clang/14.0.6/lib/wasi/libclang_rt.builtins-wasm64.a

I had success in building these in a clean llvm-toolchain tree with:
mkdir build; cd build
cmake \
-DCMAKE_C_COMPILER=clang \
-DCOMPILER_RT_STANDALONE_BUILD=ON \
-DCOMPILER_RT_BAREMETAL_BUILD=ON \
-DCOMPILER_RT_DEFAULT_TARGET_TRIPLE=wasm32-unknown-wasi \
-DCOMPILER_RT_OS_DIR=wasi \
../compiler-rt/lib/builtins/

The WASI SDK sets a few other options (BUILD_XRAY=OFF etc.) that I don't
know the use of:
https://github.com/WebAssembly/wasi-sdk/blob/a0a342ac182caf871223797c48d00138cf67e9fb/Makefile#L102

In the package's debian/rules, this could take the form of the libclc
SPIR-V build. Specifically, something like this (untested):

debian-rtlib-wasm32-build:
mkdir -p compiler-rt/lib/builtins/build-wasm32
echo "Using cmake: $(CMAKE_BIN)"
cd compiler-rt/lib/builtins/build-wasm32 && \
$(CMAKE_BIN) ../ \
-G $(GENERATOR) \
-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 \
-DCMAKE_INSTALL_DATADIR=lib \
-DCMAKE_INSTALL_INCLUDEDIR=include \
-DLLVM_CONFIG=$(STAGE_2_BIN_DIR)/llvm-config \
-DCOMPILER_RT_STANDALONE_BUILD=ON \
-DCOMPILER_RT_BAREMETAL_BUILD=ON \
-DCOMPILER_RT_DEFAULT_TARGET_TRIPLE=wasm32-unknown-wasi \
-DCOMPILER_RT_OS_DIR=wasi; \
ninja $(NJOBS) $(VERBOSE)
touch $@

(to be adjusted e.g. with a for loop for wasm64, plus hooked up on
dh_auto_build, clean etc.)

The resulting binaries could be shipped under libclang-common-14-dev,
or, given their architecture-independent nature, under a new Arch: all
package. I trust you know what's best here :)

Furthermore, given that a) there is no WASM port for libgcc b) Debian
defaults its rtlib to libgcc, this makes all out-of-the-box (i.e.
without --rtlib=compiler-rt) runs to fail. To address this, something
like this could be added to clang/lib/Driver/ToolChains/WebAssembly.cpp
to change the default to compiler-rt specifically for the WebAssembly
targets:

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;
}

(This is lifted from Darwin.cpp, and is otherwise also untested.)

Hope this all helps! Apologies for not providing better patches, but
building LLVM takes many hours on machines currently available to me,
which makes iterating on this quite painful. Thank you for maintaining
LLVM in Debian -- my time spent with the package revealed its immense
complexity, and I deeply appreciate all the work it has gone into it.

Regards,
Faidon
0 new messages