fix(guile-gnutls): make gnutls integration fully static by initializing from main guile binary

This commit is contained in:
vxtls 2026-03-05 10:55:38 -05:00
parent 9205c2b1e4
commit ac79f9e19d
6 changed files with 103 additions and 51 deletions

View file

@ -17,7 +17,7 @@ src_configure() {
--host="${host_triplet}" \
--build="${host_triplet}" \
--enable-static \
--enable-shared \
--disable-shared \
--disable-doc \
--disable-tests \
--disable-tools \

View file

@ -6,7 +6,7 @@ src_prepare() {
}
src_configure() {
local host_triplet pkg_config_path guile_cflags guile_static_libs gnutls_static_libs gnutls_link_flags
local host_triplet pkg_config_path guile_cflags guile_static_libs gnutls_static_libs
host_triplet="$(gcc -dumpmachine)"
pkg_config_path="${LIBDIR}/pkgconfig:${PREFIX}/lib/pkgconfig:${PREFIX}/share/pkgconfig"
guile_cflags="$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" \
@ -15,55 +15,109 @@ src_configure() {
/usr/bin/pkg-config --static --libs guile-3.0)"
gnutls_static_libs="$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" \
/usr/bin/pkg-config --static --libs gnutls)"
gnutls_link_flags="-Wl,-Bstatic ${gnutls_static_libs} -Wl,-Bdynamic"
PATH="${PREFIX}/bin:/usr/bin:/bin" \
PKG_CONFIG="/usr/bin/pkg-config" \
PKG_CONFIG_LIBDIR="${pkg_config_path}" \
PKG_CONFIG_PATH="${pkg_config_path}" \
CFLAGS="-fPIC" \
CXXFLAGS="-fPIC" \
LD_LIBRARY_PATH="${LIBDIR}:${PREFIX}/lib:${LD_LIBRARY_PATH}" \
GUILE_CFLAGS="${guile_cflags}" \
GUILE_LIBS="${guile_static_libs}" \
GNUTLS_LIBS="${gnutls_link_flags}" \
GNUTLS_LIBS="${gnutls_static_libs}" \
./configure \
--prefix="${PREFIX}" \
--libdir="${LIBDIR}" \
--host="${host_triplet}" \
--build="${host_triplet}" \
--disable-static \
--enable-shared \
--enable-static \
--disable-shared \
'--with-guile-site-dir=$(datarootdir)/guile/site/$(GUILE_EFFECTIVE_VERSION)' \
'--with-guile-site-ccache-dir=$(libdir)/guile/$(GUILE_EFFECTIVE_VERSION)/site-ccache' \
'--with-guile-extension-dir=$(libdir)/guile/$(GUILE_EFFECTIVE_VERSION)/extensions'
}
src_compile() {
default_src_compile
local pkg_config_path guile_cflags guile_static_libs gnutls_static_libs
local main_c
pkg_config_path="${LIBDIR}/pkgconfig:${PREFIX}/lib/pkgconfig:${PREFIX}/share/pkgconfig"
guile_cflags="$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" \
/usr/bin/pkg-config --cflags guile-3.0)"
guile_static_libs="$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" \
/usr/bin/pkg-config --static --libs guile-3.0)"
gnutls_static_libs="$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" \
/usr/bin/pkg-config --static --libs gnutls)"
make "${MAKEJOBS}" -C guile/src built-sources
make "${MAKEJOBS}" -C guile/src core.lo errors.lo utils.lo
make "${MAKEJOBS}" -C guile modules/gnutls.scm GNUTLS_GUILE_CROSS_COMPILING=yes
mkdir -p static
ar rcs static/libguile-gnutls-static.a \
guile/src/.libs/core.o \
guile/src/.libs/errors.o \
guile/src/.libs/utils.o
main_c="static/guile-static-main.c"
cat > "${main_c}" <<'EOF_C'
#include <libguile.h>
void scm_init_gnutls(void);
static void
inner_main(void *closure, int argc, char **argv)
{
(void) closure;
scm_init_gnutls();
scm_shell(argc, argv);
}
int
main(int argc, char **argv)
{
scm_boot_guile(argc, argv, inner_main, NULL);
return 0;
}
EOF_C
gcc -O2 -static ${guile_cflags} \
-o static/guile \
"${main_c}" \
static/libguile-gnutls-static.a \
${guile_static_libs} \
${gnutls_static_libs}
}
src_install() {
default_src_install
install -Dm755 static/guile "${DESTDIR}${PREFIX}/bin/guile"
install -Dm644 guile/modules/gnutls.scm \
"${DESTDIR}${PREFIX}/share/guile/site/3.0/gnutls.scm"
install -Dm644 guile/modules/gnutls/extra.scm \
"${DESTDIR}${PREFIX}/share/guile/site/3.0/gnutls/extra.scm"
install -Dm644 static/libguile-gnutls-static.a \
"${DESTDIR}${LIBDIR}/libguile-gnutls-static.a"
}
src_postprocess() {
local module_path
local guile_site_path guile_site_ccache guile_core_ccache
default_src_postprocess
module_path="$(find "${DESTDIR}${LIBDIR}/guile" -type f -name 'guile-gnutls-v-2.so' | head -n1)"
if [ -z "${module_path}" ] || [ ! -f "${module_path}" ]; then
echo "guile-gnutls: extension module not found after install." >&2
if find "${DESTDIR}" -type f \( -name '*.so' -o -name '*.so.*' \) | grep -q .; then
echo "guile-gnutls: shared objects are forbidden in static profile." >&2
false
fi
if command -v readelf >/dev/null 2>&1; then
if readelf -d "${module_path}" | grep -q 'NEEDED.*libguile'; then
echo "guile-gnutls: extension must not link libguile directly." >&2
false
fi
if readelf -d "${module_path}" | grep -q 'NEEDED.*libgnutls'; then
echo "guile-gnutls: extension must link gnutls stack statically." >&2
false
fi
fi
guile_site_path="${DESTDIR}${PREFIX}/share/guile/site/3.0:${PREFIX}/share/guile/site/3.0:${PREFIX}/share/guile/3.0"
guile_site_ccache="${DESTDIR}${LIBDIR}/guile/3.0/site-ccache:${LIBDIR}/guile/3.0/site-ccache"
guile_core_ccache="${LIBDIR}/guile/3.0/ccache"
PATH="${PREFIX}/bin:/usr/bin:/bin" \
GUILE_LOAD_PATH="${guile_site_path}" \
GUILE_LOAD_COMPILED_PATH="${guile_site_ccache}:${guile_core_ccache}" \
GUILE_SYSTEM_PATH="${guile_site_path}" \
GUILE_SYSTEM_COMPILED_PATH="${guile_site_ccache}:${guile_core_ccache}" \
"${DESTDIR}${PREFIX}/bin/guile" -c '(use-modules (gnutls)) (display "gnutls-module-ok\n")'
}

View file

@ -1,28 +0,0 @@
SPDX-License-Identifier: GPL-3.0-or-later
Keep the Guile extension model while avoiding a second libguile copy inside
the extension module.
When Guile itself is built without shared libguile, linking the extension
against libguile can embed another runtime copy and lead to crashes. Rely on
symbols from the hosting Guile process instead.
--- guile-gnutls-v5.0.1/guile/src/Makefile.am
+++ guile-gnutls-v5.0.1/guile/src/Makefile.am
@@ -40,14 +40,13 @@
# Use '-module' to build a "dlopenable module", in Libtool terms.
# Use '-undefined' to placate Libtool on Windows; see
# <https://lists.gnutls.org/pipermail/gnutls-devel/2014-December/007294.html>.
-guile_gnutls_v_2_la_LDFLAGS = -module -no-undefined
+guile_gnutls_v_2_la_LDFLAGS = -module
guile_gnutls_v_2_la_SOURCES = core.c errors.c utils.c
guile_gnutls_v_2_la_CFLAGS = \
$(AM_CFLAGS) $(GNULIB_CFLAGS) $(GUILE_CFLAGS) $(GNUTLS_CFLAGS)
guile_gnutls_v_2_la_LIBADD = \
- $(GNUTLS_LIBS) \
- $(GUILE_LDFLAGS)
+ $(GNUTLS_LIBS)
AM_CPPFLAGS = \
-I$(top_srcdir)/lib/includes \

View file

@ -0,0 +1,22 @@
SPDX-License-Identifier: GPL-3.0-or-later
In static bootstrap profile, initialize bindings from symbols linked into the
main Guile executable rather than loading a shared extension object.
--- guile-gnutls-v5.0.1/guile/modules/gnutls.in
+++ guile-gnutls-v5.0.1/guile/modules/gnutls.in
@@ -817,11 +817,9 @@
;; save 'extensiondir' only if it's different from what Guile expects.
@maybe_guileextensiondir@))
- (unless (getenv "GNUTLS_GUILE_CROSS_COMPILING")
- (load-extension (if %libdir
- (string-append %libdir "/guile-gnutls-v-2")
- "guile-gnutls-v-2")
- "scm_init_gnutls")))
+ (unless (getenv "GNUTLS_GUILE_CROSS_COMPILING")
+ (dynamic-call "scm_init_gnutls"
+ (dynamic-link #f))))
(define-syntax define-deprecated
(lambda (s)

View file

@ -16,7 +16,9 @@ src_configure() {
--prefix="${PREFIX}" \
--libdir="${LIBDIR}" \
--host="${host_triplet}" \
--build="${host_triplet}"
--build="${host_triplet}" \
--enable-static \
--disable-shared
}
src_compile() {

View file

@ -14,6 +14,8 @@ src_configure() {
--libdir="${LIBDIR}" \
--host="${host_triplet}" \
--build="${host_triplet}" \
--enable-static \
--disable-shared \
--disable-documentation
}