From beb5a8178571265dbfabec108c0c52196dfab46b Mon Sep 17 00:00:00 2001 From: Enrique Saurez Date: Tue, 9 Jun 2026 19:12:14 -0700 Subject: [PATCH] [build] E: Build libsqlite3.so alongside libsqlite3.a Adds a libsqlite3.so link step to the `build` recipe that links the .so from the (now PIC) static archive via -Wl,--whole-archive so every sqlite3 entry point becomes part of the .so's .dynsym. Sets DT_SONAME=libsqlite3.so so consumers that link against it emit a proper DT_NEEDED entry. libsqlite3 is self-contained -- no transitive .so deps -- so the .so records no DT_NEEDED of its own. libc / libm / libz symbols are left UND via -nostdlib and bind at dlopen time against the host executable's .dynsym, matching the model already used by libffi.so / libssl.so. Changes: - Makefile.nanvix: - CONFIGURE_ENV CFLAGS gains -fPIC so the .o files used by libsqlite3.a are also usable by the .so link. - `build` recipe extended with a gcc -shared invocation that links libsqlite3.so from libsqlite3.a after the upstream `make all` completes. - LIB_ARTIFACTS gains "libsqlite3.so", so the `install` recipe copies it to LIB_OUT alongside libsqlite3.a (and `package` / `verify-package` pick it up via the same list). - .nanvix/z.py: - _staged_output_files extended with libsqlite3.so so Windows tar-copy mode copies the install-staged .so back to the host workspace after the container exits. Runtime dependency: the shared-library build becomes useful once the loader changes in nanvix/nanvix#2473 ([syscall] E: Run dlopen ctors/dtors and DT_RUNPATH) ship. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .nanvix/z.py | 1 + Makefile.nanvix | 26 ++++++++++++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/.nanvix/z.py b/.nanvix/z.py index 2d6990747c..bb46c07170 100644 --- a/.nanvix/z.py +++ b/.nanvix/z.py @@ -189,6 +189,7 @@ def _staged_output_files(self) -> list[str]: root = repo_root() return [ str((lib_out() / "libsqlite3.a").relative_to(root)), + str((lib_out() / "libsqlite3.so").relative_to(root)), str((include_out() / "sqlite3.h").relative_to(root)), str((include_out() / "sqlite3ext.h").relative_to(root)), str((bin_out() / "sqlite3.elf").relative_to(root)), diff --git a/Makefile.nanvix b/Makefile.nanvix index 74387bece9..765be9cbd9 100644 --- a/Makefile.nanvix +++ b/Makefile.nanvix @@ -51,7 +51,7 @@ INSTALL_PREFIX ?= $(SYSROOT_PATH) # Artifacts staged by `install` into the release/test output tree so that # `./z release` (which packages release_dir()) can find them. -LIB_ARTIFACTS := libsqlite3.a +LIB_ARTIFACTS := libsqlite3.a libsqlite3.so INCLUDE_ARTIFACTS := sqlite3.h src/sqlite3ext.h BIN_ARTIFACTS := sqlite3$(EXE) @@ -93,7 +93,7 @@ CC="$(TOOLCHAIN_PREFIX)/bin/i686-nanvix-gcc" \ CXX="$(TOOLCHAIN_PREFIX)/bin/i686-nanvix-g++" \ CPP="$(TOOLCHAIN_PREFIX)/bin/i686-nanvix-cpp" \ LD="$(TOOLCHAIN_PREFIX)/bin/i686-nanvix-ld" \ -CFLAGS="-I$(SYSROOT_PREFIX)/include -DSQLITE_OMIT_WAL=1" \ +CFLAGS="-I$(SYSROOT_PREFIX)/include -fPIC -DSQLITE_OMIT_WAL=1" \ LDFLAGS="-static -T$(SYSROOT_PREFIX)/lib/user.ld -L$(SYSROOT_PREFIX)/lib -Wl,--allow-multiple-definition -Wl,--start-group $(LIBCRT0) $(LIBPOSIX) $(LIBC) $(LIBM) $(LIBZ) -Wl,--end-group" \ LIBS="-Wl,--start-group $(LIBCRT0) $(LIBPOSIX) $(LIBC) $(LIBM) $(LIBZ) -Wl,--end-group" @@ -129,6 +129,27 @@ $(CONFIGURED_MARKER): build: $(CONFIGURED_MARKER) make -j$$(nproc) $(BTCLSH_OVERRIDE) all @if [ -f sqlite3 ] && [ ! -f sqlite3$(EXE) ]; then mv sqlite3 sqlite3$(EXE); fi + @# Link libsqlite3.so from the (now PIC) static archive via + @# --whole-archive so every sqlite3 entry point becomes part of the + @# .so's .dynsym. Set DT_SONAME so consumers that link `-lsqlite3` + @# against this .so emit a proper DT_NEEDED entry. libc / libm / + @# libz symbols are left UND via -nostdlib and bind at dlopen time + @# against the host executable's .dynsym, matching the model used + @# by other Nanvix shared libraries such as libffi.so / libssl.so. + @# + @# `-static-libgcc -lgcc` embeds the small set of libgcc helpers + @# that sqlite3.c needs for 64-bit integer arithmetic on i686 + @# (__divdi3 / __moddi3 / __udivdi3 / __umoddi3, all STV_HIDDEN + @# inside libgcc). Without them, ld leaves the symbols UND in + @# libsqlite3.so and the cpython configure-time hello-world probe + @# (`-lsqlite3 -lpthread -ldl`, no libgcc) fails to link, which + @# silently drops `-lsqlite3` from `_sqlite3.cpython-312.so`'s + @# DT_NEEDED list and breaks dlopen at runtime. + $(TOOLCHAIN_PREFIX)/bin/i686-nanvix-gcc -shared -fPIC -nostdlib \ + -Wl,-soname,libsqlite3.so -Wl,-z,noexecstack \ + -Wl,--whole-archive libsqlite3.a -Wl,--no-whole-archive \ + -static-libgcc -lgcc \ + -o libsqlite3.so # Stage built artifacts into the release/test output tree so that # `./z release` (which packages release_dir()) can find them. @@ -169,6 +190,7 @@ test: test-functional clean: -make clean 2>/dev/null || true rm -f $(CONFIGURED_MARKER) sqlite3$(EXE) _sqlite_test.sql jimsh0 lemon mksourceid mkkeywordhash srcck1 src-verify lempar.c + rm -f libsqlite3.so rm -rf $(OUT_DIR) dist/ distclean: clean