8000 bpo-44133: Link Python executable with object files (GH-30556) · python/cpython@6be8489 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6be8489

Browse files
authored
bpo-44133: Link Python executable with object files (GH-30556)
When Python is built without --enable-shared, the "python" program is now linked to object files, rather than being linked to the Python library (libpython.a), to make sure that all symbols are exported. Previously, the linker omitted some symbols like the Py_FrozenMain() function. When Python is configured with --without-static-libpython, the Python static library (libpython.a) is no longer built. * Check --without-static-libpython earlier in configure.ac * Add LINK_PYTHON_OBJS and LINK_PYTHON_DEPS variables to Makefile. * test_capi now ensures that the "Py_FrozenMain" symbol is exported.
1 parent 0885999 commit 6be8489

File tree

6 files changed

+131
-85
lines changed

6 files changed

+131
-85
lines changed

Lib/test/test_capi.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,24 @@ def test_Py_CompileString(self):
643643
expected = compile(code, "<string>", "exec")
644644
self.assertEqual(result.co_consts, expected.co_consts)
645645

646+
def test_export_symbols(self):
647+
# bpo-44133: Ensure that the "Py_FrozenMain" and
648+
# "PyThread_get_thread_native_id" symbols are exported by the Python
649+
# (directly by the binary, or via by the Python dynamic library).
650+
ctypes = import_helper.import_module('ctypes')
651+
names = ['PyThread_get_thread_native_id']
652+
653+
# Python/frozenmain.c fails to build on Windows when the symbols are
654+
# missing:
655+
# - PyWinFreeze_ExeInit
656+
# - PyWinFreeze_ExeTerm
657+
# - PyInitFrozenExtensions
658+
if os.name != 'nt':
659+
names.append('Py_FrozenMain')
660+
for name in names:
661+
with self.subTest(name=name):
662+
self.assertTrue(hasattr(ctypes.pythonapi, name))
663+
646664

647665
class TestPendingCalls(unittest.TestCase):
648666

Makefile.pre.in

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ DLLLIBRARY= @DLLLIBRARY@
265265
LDLIBRARYDIR= @LDLIBRARYDIR@
266266
INSTSONAME= @INSTSONAME@
267267
LIBRARY_DEPS= @LIBRARY_DEPS@
268+
LINK_PYTHON_DEPS=@LINK_PYTHON_DEPS@
268269
PY_ENABLE_SHARED= @PY_ENABLE_SHARED@
269270
STATIC_LIBPYTHON= @STATIC_LIBPYTHON@
270271

@@ -526,6 +527,8 @@ LIBRARY_OBJS= \
526527
Modules/getpath.o \
527528
Python/frozen.o
528529

530+
LINK_PYTHON_OBJS=@LINK_PYTHON_OBJS@
531+
529532
##########################################################################
530533
# DTrace
531534

@@ -721,8 +724,8 @@ clinic: check-clean-src $(srcdir)/Modules/_blake2/blake2s_impl.c
721724
$(PYTHON_FOR_REGEN) $(srcdir)/Tools/clinic/clinic.py --make --srcdir $(srcdir)
722725

723726
# Build the interpreter
724-
$(BUILDPYTHON): Programs/python.o $(LIBRARY_DEPS)
725-
$(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/python.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS)
727+
$(BUILDPYTHON): Programs/python.o $(LINK_PYTHON_DEPS)
728+
$(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/python.o $(LINK_PYTHON_OBJS) $(LIBS) $(MODLIBS) $(SYSLIBS)
726729

727730
platform: $(BUILDPYTHON) pybuilddir.txt
728731
$(RUNSHARED) $(PYTHON_FOR_BUILD) -c 'import sys ; from sysconfig import get_platform ; print("%s-%d.%d" % (get_platform(), *sys.version_info[:2]))' >platform
@@ -965,8 +968,8 @@ regen-test-frozenmain: $(BUILDPYTHON)
965968
# using Programs/freeze_test_frozenmain.py
966969
$(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Programs/freeze_test_frozenmain.py Programs/test_frozenmain.h
967970

968-
Programs/_testembed: Programs/_testembed.o $(LIBRARY_DEPS)
969-
$(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/_testembed.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS)
971+
Programs/_testembed: Programs/_testembed.o $(LINK_PYTHON_DEPS)
972+
$(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/_testembed.o $(LINK_PYTHON_OBJS) $(LIBS) $(MODLIBS) $(SYSLIBS)
970973

971974
############################################################################
972975
# "Bootstrap Python" used to run deepfreeze.py
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
When Python is built without :option:`--enable-shared`, the ``python``
2+
program is now linked to object files, rather than being linked to the Python
3+
static library (libpython.a), to make sure that all symbols are exported.
4+
Previously, the linker omitted some symbols like the :c:func:`Py_FrozenMain`
5+
function. Patch by Victor Stinner.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
When Python is configured with :option:`--without-static-libpython`, the Python
2+
static library (libpython.a) is no longer built. Patch by Victor Stinner.

configure

Lines changed: 57 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -775,8 +775,6 @@ MODULE__IO_TRUE
775775
MODULES_SETUP_STDLIB
776776
MODULE_BUILDTYPE
777777
TEST_MODULES
778-
LIBRARY_DEPS
779-
STATIC_LIBPYTHON
780778
OPENSSL_RPATH
781779
OPENSSL_LDFLAGS
782780
OPENSSL_LIBS
@@ -877,6 +875,10 @@ READELF
877875
ARFLAGS
878876
ac_ct_AR
879877
AR
878+
LINK_PYTHON_OBJS
879+
LINK_PYTHON_DEPS
880+
LIBRARY_DEPS
881+
STATIC_LIBPYTHON
880882
GNULD
881883
EXPORTSFROM
882884
EXPORTSYMS
@@ -1007,6 +1009,7 @@ with_cxx_main
10071009
with_emscripten_target
10081010
with_suffix
10091011
enable_shared
1012+
with_static_libpython
10101013
enable_profiling
10111014
with_pydebug
10121015
with_trace_refs
@@ -1048,7 +1051,6 @@ with_openssl_rpath
10481051
with_ssl_default_suites
10491052
with_builtin_hashlib_hashes
10501053
with_experimental_isolated_subinterpreters
1051-
with_static_libpython
10521054
enable_test_modules
10531055
'
10541056
ac_precious_vars='build_alias
@@ -1758,6 +1760,9 @@ Optional Packages:
17581760
Emscripten platform
17591761
--with-suffix=SUFFIX set executable suffix to SUFFIX (default is empty,
17601762
yes is mapped to '.exe')
1763+
--without-static-libpython
1764+
do not build libpythonMAJOR.MINOR.a and do not
1765+
install python.o (default is yes)
17611766
--with-pydebug build with Py_DEBUG defined (default is no)
17621767
--with-trace-refs enable tracing references for debugging purpose
17631768
(default is no)
@@ -1840,9 +1845,6 @@ Optional Packages:
18401845
--with-experimental-isolated-subinterpreters
18411846
better isolate subinterpreters, experimental build
18421847
mode (default is no)
1843-
--without-static-libpython
1844-
do not build libpythonMAJOR.MINOR.a and do not
1845-
install python.o (default is yes)
18461848

18471849
Some influential environment variables:
18481850
PKG_CONFIG path to pkg-config utility
@@ -6428,6 +6430,30 @@ fi
64286430
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
64296431
$as_echo "$enable_shared" >&6; }
64306432

6433+
# --with-static-libpython
6434+
STATIC_LIBPYTHON=1
6435+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-static-libpython" >&5
6436+
$as_echo_n "checking for --with-static-libpython... " >&6; }
6437+
6438+
# Check whether --with-static-libpython was given.
6439+
if test "${with_static_libpython+set}" = set; then :
6440+
withval=$with_static_libpython;
6441+
if test "$withval" = no
6442+
then
6443+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
6444+
$as_echo "no" >&6; };
6445+
STATIC_LIBPYTHON=0
6446+
else
6447+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
6448+
$as_echo "yes" >&6; };
6449+
fi
6450+
else
6451+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
6452+
$as_echo "yes" >&6; }
6453+
fi
6454+
6455+
6456+
64316457
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --enable-profiling" >&5
64326458
$as_echo_n "checking for --enable-profiling... " >&6; }
64336459
# Check whether --enable-profiling was given.
@@ -6550,6 +6576,31 @@ fi
65506576
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LDLIBRARY" >&5
65516577
$as_echo "$LDLIBRARY" >&6; }
65526578

6579+
# LIBRARY_DEPS, LINK_PYTHON_OBJS and LINK_PYTHON_DEPS variable
6580+
LIBRARY_DEPS='$(PY3LIBRARY) $(EXPORTSYMS)'
6581+
LINK_PYTHON_DEPS='$(LIBRARY_DEPS)'
6582+
if test "$PY_ENABLE_SHARED" = 1 || test "$enable_framework" ; then
6583+
LIBRARY_DEPS="\$(LDLIBRARY) $LIBRARY_DEPS"
6584+
if test "$STATIC_LIBPYTHON" = 1; then
6585+
LIBRARY_DEPS="\$(LIBRARY) $LIBRARY_DEPS"
6586+
fi
6587+
# Link Python program to the shared library
6588+
LINK_PYTHON_OBJS='$(BLDLIBRARY)'
6589+
else
6590+
if test "$STATIC_LIBPYTHON" = 0; then
6591+
# Build Python needs object files but don't need to build
6592+
# Python static library
6593+
LINK_PYTHON_DEPS="$LIBRARY_DEPS \$(LIBRARY_OBJS)"
6594+
fi
6595+
LIBRARY_DEPS="\$(LIBRARY) $LIBRARY_DEPS"
6596+
# Link Python program to object files
6597+
LINK_PYTHON_OBJS='$(LIBRARY_OBJS)'
6598+
fi
6599+
6600+
6601+
6602+
6603+
# ar program
65536604

65546605
if test -n "$ac_tool_prefix"; then
65556606
for ac_prog in ar aal
@@ -21213,48 +21264,6 @@ $as_echo "no" >&6; }
2121321264
fi
2121421265

2121521266

21216-
# --with-static-libpython
21217-
STATIC_LIBPYTHON=1
21218-
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-static-libpython" >&5
21219-
$as_echo_n "checking for --with-static-libpython... " >&6; }
21220-
21221-
# Check whether --with-static-libpython was given.
21222-
if test "${with_static_libpython+set}" = set; then :
21223-
withval=$with_static_libpython;
21224-
if test "$withval" = no
21225-
then
21226-
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
21227-
$as_echo "no" >&6; };
21228-
STATIC_LIBPYTHON=0
21229-
else
21230-
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
21231-
$as_echo "yes" >&6; };
21232-
fi
21233-
else
21234-
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
21235-
$as_echo "yes" >&6; }
21236-
fi
21237-
21238-
LIBRARY_DEPS='$(PY3LIBRARY) $(EXPORTSYMS)'
21239-
if test "$PY_ENABLE_SHARED" = 1 || test "$enable_framework" ; then
21240-
LIBRARY_DEPS="\$(LDLIBRARY) $LIBRARY_DEPS"
21241-
if test "$STATIC_LIBPYTHON" = 1; then
21242-
LIBRARY_DEPS="\$(LIBRARY) $LIBRARY_DEPS"
21243-
fi
21244-
else
21245-
LIBRARY_DEPS="\$(LIBRARY) $LIBRARY_DEPS"
21246-
fi
21247-
21248-
case $ac_sys_system/$ac_sys_emscripten_target in #(
21249-
Emscripten/browser) :
21250-
LIBRARY_DEPS="$LIBRARY_DEPS \$(WASM_STDLIB)" ;; #(
21251-
*) :
21252-
;;
21253-
esac
21254-
21255-
21256-
21257-
2125821267
# Check whether to disable test modules. Once set, setup.py will not build
2125921268
# test extension modules and "make install" will not install test suites.
2126021269
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --disable-test-modules" >&5

configure.ac

Lines changed: 42 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1231,6 +1231,23 @@ then
12311231
fi
12321232
AC_MSG_RESULT($enable_shared)
12331233

1234+
# --with-static-libpython
1235+
STATIC_LIBPYTHON=1
1236+
AC_MSG_CHECKING(for --with-static-libpython)
1237+
AC_ARG_WITH(static-libpython,
1238+
AS_HELP_STRING([--without-static-libpython],
1239+
[do not build libpythonMAJOR.MINOR.a and do not install python.o (default is yes)]),
1240+
[
1241+
if test "$withval" = no
1242+
then
1243+
AC_MSG_RESULT(no);
1244+
STATIC_LIBPYTHON=0
1245+
else
1246+
AC_MSG_RESULT(yes);
1247+
fi],
1248+
[AC_MSG_RESULT(yes)])
1249+
AC_SUBST(STATIC_LIBPYTHON)
1250+
12341251
AC_MSG_CHECKING(for --enable-profiling)
12351252
AC_ARG_ENABLE(profiling,
12361253
AS_HELP_STRING([--enable-profiling], [enable C-level code profiling with gprof (default is no)]))
@@ -1336,6 +1353,31 @@ fi
13361353

13371354
AC_MSG_RESULT($LDLIBRARY)
13381355

1356+
# LIBRARY_DEPS, LINK_PYTHON_OBJS and LINK_PYTHON_DEPS variable
1357+
LIBRARY_DEPS='$(PY3LIBRARY) $(EXPORTSYMS)'
1358+
LINK_PYTHON_DEPS='$(LIBRARY_DEPS)'
1359+
if test "$PY_ENABLE_SHARED" = 1 || test "$enable_framework" ; then
1360+
LIBRARY_DEPS="\$(LDLIBRARY) $LIBRARY_DEPS"
1361+
if test "$STATIC_LIBPYTHON" = 1; then
1362+
LIBRARY_DEPS="\$(LIBRARY) $LIBRARY_DEPS"
1363+
fi
1364+
# Link Python program to the shared library
1365+
LINK_PYTHON_OBJS='$(BLDLIBRARY)'
1366+
else
1367+
if test "$STATIC_LIBPYTHON" = 0; then
1368+
# Build Python needs object files but don't need to build
1369+
# Python static library
1370+
LINK_PYTHON_DEPS="$LIBRARY_DEPS \$(LIBRARY_OBJS)"
1371+
fi
1372+
LIBRARY_DEPS="\$(LIBRARY) $LIBRARY_DEPS"
1373+
# Link Python program to object files
1374+
LINK_PYTHON_OBJS='$(LIBRARY_OBJS)'
1375+
fi
1376+
AC_SUBST(LIBRARY_DEPS)
1377+
AC_SUBST(LINK_PYTHON_DEPS)
1378+
AC_SUBST(LINK_PYTHON_OBJS)
1379+
1380+
# ar program
13391381
AC_SUBST(AR)
13401382
AC_CHECK_TOOLS(AR, ar aal, ar)
13411383

@@ -6273,39 +6315,6 @@ else
62736315
fi],
62746316
[AC_MSG_RESULT(no)])
62756317

6276-
# --with-static-libpython
6277-
STATIC_LIBPYTHON=1
6278-
AC_MSG_CHECKING(for --with-static-libpython)
6279-
AC_ARG_WITH(static-libpython,
6280-
AS_HELP_STRING([--without-static-libpython],
6281-
[do not build libpythonMAJOR.MINOR.a and do not install python.o (default is yes)]),
6282-
[
6283-
if test "$withval" = no
6284-
then
6285-
AC_MSG_RESULT(no);
6286-
STATIC_LIBPYTHON=0
6287-
else
6288-
AC_MSG_RESULT(yes);
6289-
fi],
6290-
[AC_MSG_RESULT(yes)])
6291-
LIBRARY_DEPS='$(PY3LIBRARY) $(EXPORTSYMS)'
6292-
if test "$PY_ENABLE_SHARED" = 1 || test "$enable_framework" ; then
6293-
LIBRARY_DEPS="\$(LDLIBRARY) $LIBRARY_DEPS"
6294-
if test "$STATIC_LIBPYTHON" = 1; then
6295-
LIBRARY_DEPS="\$(LIBRARY) $LIBRARY_DEPS"
6296-
fi
6297-
else
6298-
LIBRARY_DEPS="\$(LIBRARY) $LIBRARY_DEPS"
6299-
fi
6300-
6301-
dnl browser needs a WASM assets stdlib bundle
6302-
AS_CASE([$ac_sys_system/$ac_sys_emscripten_target],
6303-
[Emscripten/browser], [LIBRARY_DEPS="$LIBRARY_DEPS \$(WASM_STDLIB)"],
6304-
)
6305-
6306-
AC_SUBST(STATIC_LIBPYTHON)
6307-
AC_SUBST(LIBRARY_DEPS)
6308-
63096318
# Check whether to disable test modules. Once set, setup.py will not build
63106319
# test extension modules and "make install" will not install test suites.
63116320
AC_MSG_CHECKING(for --disable-test-modules)

0 commit comments

Comments
 (0)
0