Skip to content

Commit a21bedf

Browse files
vstinnerned-deily
authored andcommitted
[3.6] bpo-35257: Avoid leaking LTO linker flags into distutils (GH-10900) (GH-11265)
When compiling 3rd party C extensions, the linker flags used by the compiler for the interpreter and the stdlib modules, will get leaked into distutils. In order to avoid that, the PY_CORE_LDFLAGS and PY_LDFLAGS_NODIST are introduced to keep those flags separated. (cherry picked from commit cf10a75)
1 parent 70db385 commit a21bedf

File tree

8 files changed

+37
-18
lines changed

8 files changed

+37
-18
lines changed

Lib/_osx_support.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
_UNIVERSAL_CONFIG_VARS = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS', 'BASECFLAGS',
1818
'BLDSHARED', 'LDSHARED', 'CC', 'CXX',
1919
'PY_CFLAGS', 'PY_LDFLAGS', 'PY_CPPFLAGS',
20-
'PY_CORE_CFLAGS')
20+
'PY_CORE_CFLAGS', 'PY_CORE_LDFLAGS')
2121

2222
# configuration variables that may contain compiler calls
2323
_COMPILER_CONFIG_VARS = ('BLDSHARED', 'LDSHARED', 'CC', 'CXX')

Lib/test/pythoninfo.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,9 @@ def collect_sysconfig(info_add):
407407
'OPT',
408408
'PY_CFLAGS',
409409
'PY_CFLAGS_NODIST',
410+
'PY_CORE_LDFLAGS',
410411
'PY_LDFLAGS',
412+
'PY_LDFLAGS_NODIST',
411413
'Py_DEBUG',
412414
'Py_ENABLE_SHARED',
413415
'SHELL',

Lib/test/test__osx_support.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def setUp(self):
2424
for cv in ('CFLAGS', 'LDFLAGS', 'CPPFLAGS',
2525
'BASECFLAGS', 'BLDSHARED', 'LDSHARED', 'CC',
2626
'CXX', 'PY_CFLAGS', 'PY_LDFLAGS', 'PY_CPPFLAGS',
27-
'PY_CORE_CFLAGS'):
27+
'PY_CORE_CFLAGS', 'PY_CORE_LDFLAGS'):
2828
if cv in self.env:
2929
self.env.unset(cv)
3030

Makefile.pre.in

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ CONFIGURE_CFLAGS= @CFLAGS@
8484
# Use it when a compiler flag should _not_ be part of the distutils CFLAGS
8585
# once Python is installed (Issue #21121).
8686
CONFIGURE_CFLAGS_NODIST=@CFLAGS_NODIST@
87+
# LDFLAGS_NODIST is used in the same manner as CFLAGS_NODIST.
88+
# Use it when a linker flag should _not_ be part of the distutils LDFLAGS
89+
# once Python is installed (bpo-35257)
90+
CONFIGURE_LDFLAGS_NODIST=@LDFLAGS_NODIST@
8791
CONFIGURE_CPPFLAGS= @CPPFLAGS@
8892
CONFIGURE_LDFLAGS= @LDFLAGS@
8993
# Avoid assigning CFLAGS, LDFLAGS, etc. so users can use them on the
@@ -96,6 +100,7 @@ PY_CFLAGS_NODIST=$(CONFIGURE_CFLAGS_NODIST) $(CFLAGS_NODIST)
96100
# environment variables
97101
PY_CPPFLAGS= $(BASECPPFLAGS) -I. -I$(srcdir)/Include $(CONFIGURE_CPPFLAGS) $(CPPFLAGS)
98102
PY_LDFLAGS= $(CONFIGURE_LDFLAGS) $(LDFLAGS)
103+
PY_LDFLAGS_NODIST=$(CONFIGURE_LDFLAGS_NODIST) $(LDFLAGS_NODIST)
99104
NO_AS_NEEDED= @NO_AS_NEEDED@
100105
LDLAST= @LDLAST@
101106
SGI_ABI= @SGI_ABI@
@@ -106,6 +111,8 @@ ARFLAGS= @ARFLAGS@
106111
CFLAGSFORSHARED=@CFLAGSFORSHARED@
107112
# C flags used for building the interpreter object files
108113
PY_CORE_CFLAGS= $(PY_CFLAGS) $(PY_CFLAGS_NODIST) $(PY_CPPFLAGS) $(CFLAGSFORSHARED) -DPy_BUILD_CORE
114+
# Linker flags used for building the interpreter object files
115+
PY_CORE_LDFLAGS=$(PY_LDFLAGS) $(PY_LDFLAGS_NODIST)
109116
# Strict or non-strict aliasing flags used to compile dtoa.c, see above
110117
CFLAGS_ALIASING=@CFLAGS_ALIASING@
111118

@@ -145,7 +152,7 @@ CONFINCLUDEPY= $(CONFINCLUDEDIR)/python$(LDVERSION)
145152
SHLIB_SUFFIX= @SHLIB_SUFFIX@
146153
EXT_SUFFIX= @EXT_SUFFIX@
147154
LDSHARED= @LDSHARED@ $(PY_LDFLAGS)
148-
BLDSHARED= @BLDSHARED@ $(PY_LDFLAGS)
155+
BLDSHARED= @BLDSHARED@ $(PY_LDFLAGS_NODIST)
149156
LDCXXSHARED= @LDCXXSHARED@
150157
DESTSHARED= $(BINLIBDEST)/lib-dynload
151158

@@ -472,7 +479,7 @@ profile-opt:
472479
$(MAKE) profile-removal
473480

474481
build_all_generate_profile:
475-
$(MAKE) @DEF_MAKE_RULE@ CFLAGS_NODIST="$(CFLAGS_NODIST) $(PGO_PROF_GEN_FLAG)" LDFLAGS="$(LDFLAGS) $(PGO_PROF_GEN_FLAG)" LIBS="$(LIBS)"
482+
$(MAKE) @DEF_MAKE_RULE@ CFLAGS_NODIST="$(CFLAGS_NODIST) $(PGO_PROF_GEN_FLAG)" LDFLAGS_NODIST="$(LDFLAGS_NODIST) $(PGO_PROF_GEN_FLAG)" LIBS="$(LIBS)"
476483

477484
run_profile_task:
478485
: # FIXME: can't run for a cross build
@@ -482,7 +489,7 @@ build_all_merge_profile:
482489
$(LLVM_PROF_MERGER)
483490

484491
build_all_use_profile:
485-
$(MAKE) @DEF_MAKE_RULE@ CFLAGS_NODIST="$(CFLAGS_NODIST) $(PGO_PROF_USE_FLAG)" LDFLAGS="$(LDFLAGS)"
492+
$(MAKE) @DEF_MAKE_RULE@ CFLAGS_NODIST="$(CFLAGS_NODIST) $(PGO_PROF_USE_FLAG)" LDFLAGS_NODIST="$(LDFLAGS_NODIST)"
486493

487494
# Compile and run with gcov
488495
.PHONY=coverage coverage-lcov coverage-report
@@ -543,7 +550,7 @@ clinic: check-clean-src $(srcdir)/Modules/_blake2/blake2s_impl.c
543550

544551
# Build the interpreter
545552
$(BUILDPYTHON): Programs/python.o $(LIBRARY) $(LDLIBRARY) $(PY3LIBRARY)
546-
$(LINKCC) $(PY_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/python.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST)
553+
$(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/python.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST)
547554

548555
platform: $(BUILDPYTHON) pybuilddir.txt
549556
$(RUNSHARED) $(PYTHON_FOR_BUILD) -c 'import sys ; from sysconfig import get_platform ; print("%s-%d.%d" % (get_platform(), *sys.version_info[:2]))' >platform
@@ -608,7 +615,7 @@ libpython3.so: libpython$(LDVERSION).so
608615
$(BLDSHARED) $(NO_AS_NEEDED) -o $@ -Wl,-h$@ $^
609616

610617
libpython$(LDVERSION).dylib: $(LIBRARY_OBJS)
611-
$(CC) -dynamiclib -Wl,-single_module $(PY_LDFLAGS) -undefined dynamic_lookup -Wl,-install_name,$(prefix)/lib/libpython$(LDVERSION).dylib -Wl,-compatibility_version,$(VERSION) -Wl,-current_version,$(VERSION) -o $@ $(LIBRARY_OBJS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \
618+
$(CC) -dynamiclib -Wl,-single_module $(PY_CORE_LDFLAGS) -undefined dynamic_lookup -Wl,-install_name,$(prefix)/lib/libpython$(LDVERSION).dylib -Wl,-compatibility_version,$(VERSION) -Wl,-current_version,$(VERSION) -o $@ $(LIBRARY_OBJS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \
612619

613620

614621
libpython$(VERSION).sl: $(LIBRARY_OBJS)
@@ -633,7 +640,7 @@ $(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK): \
633640
$(LIBRARY) \
634641
$(RESSRCDIR)/Info.plist
635642
$(INSTALL) -d -m $(DIRMODE) $(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)
636-
$(CC) -o $(LDLIBRARY) $(PY_LDFLAGS) -dynamiclib \
643+
$(CC) -o $(LDLIBRARY) $(PY_CORE_LDFLAGS) -dynamiclib \
637644
-all_load $(LIBRARY) -Wl,-single_module \
638645
-install_name $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK) \
639646
-compatibility_version $(VERSION) \
@@ -686,15 +693,15 @@ Modules/Setup: $(srcdir)/Modules/Setup.dist
686693
fi
687694

688695
Programs/_testembed: Programs/_testembed.o $(LIBRARY) $(LDLIBRARY) $(PY3LIBRARY)
689-
$(LINKCC) $(PY_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/_testembed.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST)
696+
$(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/_testembed.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST)
690697

691698
############################################################################
692699
# Importlib
693700

694701
Programs/_freeze_importlib.o: Programs/_freeze_importlib.c Makefile
695702

696703
Programs/_freeze_importlib: Programs/_freeze_importlib.o $(LIBRARY_OBJS_OMIT_FROZEN)
697-
$(LINKCC) $(PY_LDFLAGS) -o $@ Programs/_freeze_importlib.o $(LIBRARY_OBJS_OMIT_FROZEN) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST)
704+
$(LINKCC) $(PY_CORE_LDFLAGS) -o $@ Programs/_freeze_importlib.o $(LIBRARY_OBJS_OMIT_FROZEN) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST)
698705

699706
.PHONY: regen-importlib
700707
regen-importlib: Programs/_freeze_importlib
@@ -776,7 +783,7 @@ Python/sysmodule.o: $(srcdir)/Python/sysmodule.c Makefile
776783
$(IO_OBJS): $(IO_H)
777784

778785
$(PGEN): $(PGENOBJS)
779-
$(CC) $(OPT) $(PY_LDFLAGS) $(PGENOBJS) $(LIBS) -o $(PGEN)
786+
$(CC) $(OPT) $(PY_CORE_LDFLAGS) $(PGENOBJS) $(LIBS) -o $(PGEN)
780787

781788
.PHONY: regen-grammar
782789
regen-grammar: $(PGEN)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Avoid leaking the linker flags from Link Time Optimizations (LTO)
2+
into distutils when compiling C extensions.

configure

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,7 @@ SHLIB_SUFFIX
666666
LIBTOOL_CRUFT
667667
OTHER_LIBTOOL_OPT
668668
UNIVERSAL_ARCH_FLAGS
669+
LDFLAGS_NODIST
669670
CFLAGS_NODIST
670671
BASECFLAGS
671672
CFLAGS_ALIASING
@@ -6716,7 +6717,7 @@ $as_echo "$as_me: llvm-ar found via xcrun: ${LLVM_AR}" >&6;}
67166717
fi
67176718

67186719
CFLAGS_NODIST="$CFLAGS_NODIST $LTOFLAGS"
6719-
LDFLAGS="$LDFLAGS $LTOFLAGS"
6720+
LDFLAGS_NODIST="$LDFLAGS_NODIST $LTOFLAGS"
67206721
fi
67216722

67226723
# Enable PGO flags.
@@ -6968,6 +6969,7 @@ fi
69686969

69696970

69706971

6972+
69716973
# The -arch flags for universal builds on OSX
69726974
UNIVERSAL_ARCH_FLAGS=
69736975

configure.ac

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1401,7 +1401,7 @@ if test "$Py_LTO" = 'true' ; then
14011401
fi
14021402

14031403
CFLAGS_NODIST="$CFLAGS_NODIST $LTOFLAGS"
1404-
LDFLAGS="$LDFLAGS $LTOFLAGS"
1404+
LDFLAGS_NODIST="$LDFLAGS_NODIST $LTOFLAGS"
14051405
fi
14061406

14071407
# Enable PGO flags.
@@ -1561,6 +1561,7 @@ fi
15611561

15621562
AC_SUBST(BASECFLAGS)
15631563
AC_SUBST(CFLAGS_NODIST)
1564+
AC_SUBST(LDFLAGS_NODIST)
15641565

15651566
# The -arch flags for universal builds on OSX
15661567
UNIVERSAL_ARCH_FLAGS=

setup.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,16 @@
1818

1919
cross_compiling = "_PYTHON_HOST_PLATFORM" in os.environ
2020

21-
# Add special CFLAGS reserved for building the interpreter and the stdlib
22-
# modules (Issue #21121).
23-
cflags = sysconfig.get_config_var('CFLAGS')
24-
py_cflags_nodist = sysconfig.get_config_var('PY_CFLAGS_NODIST')
25-
sysconfig.get_config_vars()['CFLAGS'] = cflags + ' ' + py_cflags_nodist
21+
# Set common compiler and linker flags derived from the Makefile,
22+
# reserved for building the interpreter and the stdlib modules.
23+
# See bpo-21121 and bpo-35257
24+
def set_compiler_flags(compiler_flags, compiler_py_flags_nodist):
25+
flags = sysconfig.get_config_var(compiler_flags)
26+
py_flags_nodist = sysconfig.get_config_var(compiler_py_flags_nodist)
27+
sysconfig.get_config_vars()[compiler_flags] = flags + ' ' + py_flags_nodist
28+
29+
set_compiler_flags('CFLAGS', 'PY_CFLAGS_NODIST')
30+
set_compiler_flags('LDFLAGS', 'PY_LDFLAGS_NODIST')
2631

2732
class Dummy:
2833
"""Hack for parallel build"""

0 commit comments

Comments
 (0)