Skip to content

Commit 5e137d0

Browse files
committed
don't embed Python code into libwallycore.so
Embedding SWIG Python code into libwallycore.so ties the library to a specific version of Python, thereby precluding concurrent installation of the wallycore Python module for multiple implementations of Python on the same system if the Python modules are linked with a system-wide libwallycore.so. On Gentoo at least, linking libwallycore.so with libpython3.14.so and then attempting to use the wallycore Python module from Python 3.11, 3.12, or 3.13 causes an immediate segfault. Rather than injecting Python-specific glue into libwallycore.so, we can and should keep it contained within the Python native extension library that we build for each Python implementation. The Python wheel actually already compiles swig_python_wrap.c and links it into the native extension library, so linking it into libwallycore.so as well is redundant and harmful. * Remove libswig_python.la from libwallycore_la_LIBADD, and expunge its existence from Makefile.am entirely since it's now unused. * The Python wheel build for each Python implementation compiles swig_python_wrap.c against the headers for that particular Python implementation, ensuring that the resulting native extension library matches the ABI of the Python implementation for which it is installed. This may be a different Python implementation than the one found by Autoconf, the only relevance of which now is in finding the interpreter with which to run the tests. * Since we no longer link libwallycore.so with libpython*.so, there should no longer be any manylinux compatibility issues, so drop the --enable-python-manylinux Autoconf option and the PYTHON_MANYLINUX Automake conditional. This also means that the test programs no longer need to link with $(PYTHON_LIBS) since libwallycore.la now never has any dependence on Python (implicit or explicit). * Note that the Python native extension libraries do not explicitly link with libpython*.so either. This is correct, as the dynamic linker resolves their undefined Py* symbols when it loads them into the Python interpreter. * manylinux intentionally omits libpython*.so libraries from its build containers to discourage/prevent wheels' native extension libraries from linking against the Python DSO. We don't do that (anymore), but the AX_PYTHON_DEVEL Autoconf macro expects to be able to find it and fails its final sanity check if it can't. Thankfully, more recent versions of the macro support an 'optional' flag that allows configure to proceed even if the check fails. So now we set that flag and just check that we have a value in $PYTHON_CPPFLAGS, which is all the SWIG_PYTHON macro cares about in the first place. After applying these changes, the Gentoo ebuild for libwally-core 1.5.0 now successfully runs the SWIG Python tests on all currently supported versions of Python (3.11 through 3.14), all using the same libwallycore.so.6.
1 parent c0e4e9d commit 5e137d0

File tree

4 files changed

+18
-60
lines changed

4 files changed

+18
-60
lines changed

README.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,6 @@ $ brew install swig
7373
- `--enable-swig-python`. Enable the [SWIG](http://www.swig.org/) Python
7474
interface. The resulting shared library can be imported from Python using
7575
the generated interface file `src/swig_python/wallycore/__init__.py`. (default: no).
76-
- `--enable-python-manylinux`. Enable [manylinux](https://github.com/pypa/manylinux)
77-
support for building [PyPI](https://pypi.org/) compatible python wheels. Using
78-
the resulting library in non-python programs requires linking with `libpython.so`.
7976
- `--enable-swig-java`. Enable the [SWIG](http://www.swig.org/) Java (JNI)
8077
interface. After building, see `src/swig_java/src/com/blockstream/libwally/Wally.java`
8178
for the Java interface definition (default: no).

configure.ac

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -311,12 +311,11 @@ AC_SUBST([libsecp256k1_LIBS])
311311
#
312312
# Python facilities
313313
#
314-
AC_ARG_ENABLE(python-manylinux,
315-
AS_HELP_STRING([--enable-python-manylinux],[enable manylinux Python compatibility (default: no)]),
316-
[python_manylinux=$enableval], [python_manylinux=no])
317-
AM_CONDITIONAL([PYTHON_MANYLINUX], [test "x$python_manylinux" = "xyes"])
318-
319-
AX_PYTHON_DEVEL([>= '2.7.0'])
314+
dnl We set the 'optional' flag here because manylinux cibuildwheel containers
315+
dnl don't include libpython*.so, and thus AX_PYTHON_DEVEL fails its final sanity
316+
dnl check. We actually don't link against libpython*.so anyway, so all we care
317+
dnl about is that we get a good value of $PYTHON_CPPFLAGS to pass to SWIG.
318+
AX_PYTHON_DEVEL([>= '2.7.0'], [true])
320319
AM_CONDITIONAL([HAVE_PYTHON], [test "$PYTHON" != ""])
321320

322321

@@ -338,10 +337,10 @@ AC_ARG_ENABLE(swig-python,
338337
[swig_python=$enableval], [swig_python=no])
339338
AM_CONDITIONAL([USE_SWIG_PYTHON], [test "x$swig_python" = "xyes"])
340339

341-
AM_CONDITIONAL([RUN_PYTHON_TESTS], [test "$PYTHON" != "" -a "x$pythonexists" = "xyes"])
340+
AM_CONDITIONAL([RUN_PYTHON_TESTS], [test -n "$PYTHON"])
342341

343342
if test "x$swig_python" = "xyes"; then
344-
if test "x$pythonexists" != "xyes"; then
343+
if test -z "$PYTHON_CPPFLAGS"; then
345344
AC_MSG_FAILURE([ERROR: No usable Python was found for swig-python])
346345
fi
347346
if test "x$elements_abi" = "xno"; then

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def _call(args, cwd=ABS_PATH):
6262
_call(['git', 'submodule', 'update', '--init', '--recursive'])
6363

6464
CONFIGURE_ARGS = [
65-
'--with-pic', '--enable-swig-python', '--enable-python-manylinux',
65+
'--with-pic', '--enable-swig-python',
6666
'--disable-swig-java', '--disable-tests', '--disable-dependency-tracking'
6767
]
6868

src/Makefile.am

Lines changed: 10 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,7 @@ TOOLS_EXTRA_ARGS :=
3838
endif
3939

4040
if USE_SWIG_PYTHON
41-
noinst_LTLIBRARIES += libswig_python.la
42-
libswig_python_la_SOURCES = swig_python/swig_python_wrap.c
43-
44-
libswig_python_la_CFLAGS = -I$(top_srcdir) $(libsecp256k1_CFLAGS) $(AM_CFLAGS) $(SWIG_PYTHON_CPPFLAGS) $(SWIG_WARN_CFLAGS) $(NOALIAS_CFLAGS)
45-
if PYTHON_MANYLINUX
46-
else
47-
libswig_python_la_LIBADD = $(PYTHON_LIBS)
48-
endif # PYTHON_MANYLINUX
49-
41+
BUILT_SOURCES = swig_python/swig_python_wrap.c
5042
# Append our extra wrapper code to the package
5143
swig_python/swig_python_wrap.c : swig_python/swig.i swig_python/python_extra.py_in
5244
$(AM_V_at)$(SWIG) $(SWIG_PYTHON_OPT) $(SWIG_GEN_FLAGS) -outdir swig_python -o $@ $< && \
@@ -60,20 +52,6 @@ clean-local: clean-swig-python
6052
endif # USE_SWIG_PYTHON
6153

6254
if RUN_PYTHON_TESTS
63-
# Python requires the shared library to be named _wallycore.so
64-
# for 'import' to work.
65-
if IS_OSX
66-
platform_dso_ext = dylib
67-
else
68-
if IS_MINGW
69-
platform_dso_ext = dll
70-
else
71-
platform_dso_ext = so
72-
endif # IS_MINGW
73-
endif # IS_OSX
74-
.libs/_wallycore.so: .libs/libwallycore.$(platform_dso_ext)
75-
$(AM_V_at)ln -sfn libwallycore.$(platform_dso_ext) $@
76-
PYTHON_TEST_DEPS = .libs/_wallycore.so
7755
PYTHON_TEST = PYTHONDONTWRITEBYTECODE=1 $(PYTHON)
7856
endif
7957

@@ -224,83 +202,67 @@ endif
224202

225203
TESTS =
226204
noinst_PROGRAMS =
205+
227206
if RUN_TESTS
228207
TESTS += test_bech32
229208
noinst_PROGRAMS += test_bech32
230209
test_bech32_SOURCES = ctest/test_bech32.c
231210
test_bech32_CFLAGS = -I$(top_srcdir)/include $(AM_CFLAGS)
232211
test_bech32_LDADD = $(lib_LTLIBRARIES) @CTEST_EXTRA_STATIC@
233-
if PYTHON_MANYLINUX
234-
test_bech32_LDADD += $(PYTHON_LIBS)
235-
endif
212+
236213
TESTS += test_psbt
237214
noinst_PROGRAMS += test_psbt
238215
test_psbt_SOURCES = ctest/test_psbt.c ccan/ccan/str/hex/hex.c
239216
test_psbt_CFLAGS = -I$(top_srcdir)/include $(AM_CFLAGS) -I$(srcdir)/ccan
240217
test_psbt_LDADD = $(lib_LTLIBRARIES) @CTEST_EXTRA_STATIC@
241-
if PYTHON_MANYLINUX
242-
test_psbt_LDADD += $(PYTHON_LIBS)
243-
endif
218+
244219
TESTS += test_psbt_limits
245220
noinst_PROGRAMS += test_psbt_limits
246221
test_psbt_limits_SOURCES = ctest/test_psbt_limits.c ccan/ccan/str/hex/hex.c
247222
test_psbt_limits_CFLAGS = -I$(top_srcdir)/include $(AM_CFLAGS) -I$(srcdir)/ccan
248223
test_psbt_limits_LDADD = $(lib_LTLIBRARIES) @CTEST_EXTRA_STATIC@
249-
if PYTHON_MANYLINUX
250-
test_psbt_limits_LDADD += $(PYTHON_LIBS)
251-
endif
224+
252225
if USE_PTHREAD
253226
TESTS += test_clear
254227
noinst_PROGRAMS += test_clear
255228
test_clear_SOURCES = ctest/test_clear.c
256229
test_clear_CFLAGS = -I$(top_srcdir)/include $(PTHREAD_CFLAGS) $(AM_CFLAGS) $(NOOPT_CFLAGS) $(NOBUILTIN_CFLAGS)
257230
test_clear_LIBS = $(PTHREAD_LIBS)
258231
test_clear_LDADD = $(lib_LTLIBRARIES) @CTEST_EXTRA_STATIC@
259-
if PYTHON_MANYLINUX
260-
test_clear_LDADD += $(PYTHON_LIBS)
261-
endif
262232
endif
233+
263234
TESTS += test_coinselection
264235
noinst_PROGRAMS += test_coinselection
265236
test_coinselection_SOURCES = ctest/test_coinselection.c
266237
test_coinselection_CFLAGS = -I$(top_srcdir)/include $(AM_CFLAGS)
267238
test_coinselection_LDADD = $(lib_LTLIBRARIES) @CTEST_EXTRA_STATIC@
268-
if PYTHON_MANYLINUX
269-
test_coinselection_LDADD += $(PYTHON_LIBS)
270-
endif
239+
271240
TESTS += test_tx
272241
noinst_PROGRAMS += test_tx
273242
test_tx_SOURCES = ctest/test_tx.c
274243
test_tx_CFLAGS = -I$(top_srcdir)/include $(AM_CFLAGS)
275244
test_tx_LDADD = $(lib_LTLIBRARIES) @CTEST_EXTRA_STATIC@
276-
if PYTHON_MANYLINUX
277-
test_tx_LDADD += $(PYTHON_LIBS)
278-
endif
245+
279246
TESTS += test_descriptor
280247
noinst_PROGRAMS += test_descriptor
281248
test_descriptor_SOURCES = ctest/test_descriptor.c
282249
test_descriptor_CFLAGS = -I$(top_srcdir)/include $(AM_CFLAGS)
283250
test_descriptor_LDADD = $(lib_LTLIBRARIES) @CTEST_EXTRA_STATIC@
284-
if PYTHON_MANYLINUX
285-
test_descriptor_LDADD += $(PYTHON_LIBS)
286-
endif
251+
287252
if BUILD_ELEMENTS
288253
TESTS += test_elements_tx
289254
noinst_PROGRAMS += test_elements_tx
290255
test_elements_tx_SOURCES = ctest/test_elements_tx.c
291256
test_elements_tx_CFLAGS = -I$(top_srcdir)/include $(AM_CFLAGS)
292257
test_elements_tx_LDADD = $(lib_LTLIBRARIES) @CTEST_EXTRA_STATIC@
293-
if PYTHON_MANYLINUX
294-
test_elements_tx_LDADD += $(PYTHON_LIBS)
295-
endif
296258
endif
297259

298260
check-local: check-libwallycore check-swig-python check-swig-java
299261
$(AM_V_at)! grep '^int ' $(top_srcdir)/include/*.h # Missing WALLY_CORE_API
300262

301263
if SHARED_BUILD_ENABLED
302264
if RUN_PYTHON_TESTS
303-
check-libwallycore: $(PYTHON_TEST_DEPS)
265+
check-libwallycore:
304266
$(AM_V_at)$(PYTHON_TEST) test/test_address.py
305267
$(AM_V_at)$(PYTHON_TEST) test/test_aes.py
306268
$(AM_V_at)$(PYTHON_TEST) test/test_anti_exfil.py

0 commit comments

Comments
 (0)