-
-
Notifications
You must be signed in to change notification settings - Fork 29.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Avoid leaking linker flags into distutils: add PY_LDFLAGS_NODIST #79438
Comments
Through acb8c52 the CFLAGS_NODIST variable was created, in order to place there compiler flags used by the interpreter, but not intended to be propagated to C extensions. I saw a similar issue when working on backporting 67e997bcfdac55191033d57a16d1408aL1313 on python 3.6, where the -flto flag should be passed to CFLAGS_NODIST instead of BASECFLAGS, however even if that is fixed, the LDFLAGS will still be propagated to C extensions. Thus in order to provide more flexibility in that regard, I propose to add the LDFLAGS_NODIST variable, which in a similar vein as CFLAGS_NODIST, will hold the LDFLAGS intended to be used only by the interpreter. Thoughts or comments on this approach? |
Correction: The second commit is referring to #9908 |
So to better illustrate the actual issue I'll be using an example from the python documentation [0][1]. Get the demo.c and the setup.py. Compile cpython first with --with-lto and then compile the demo.c with ./python3 setup.py build. You will notice that various link time optimization linker flags are passed to the extension. [0] https://docs.python.org/3/extending/extending.html#keyword-parameters-for-extension-functions |
And here is the difference between compiling the extension with the current tip, comparing to applying my current draft PR: Master branch with the linker flags propagated: running build With introduction of the LDFLAGS_NODIST variable: running build |
PR has been finalized. |
Unfortunately, it appears this won't be resolved in time for 3.7.2rc1 and 3.6.8rc1 and it would not be appropriate to merge something this potentially disruptive without prior exposure. Since 3.6.8 is planned to be the final 3.6.x bugfix release, unless some critical problem is discovered prior to their final releases it's likely this will not be fixed for 3.6. |
An update: the cutoff for these releases has been extended until about 30 hours from now so there is perhaps a small chance that the PR for this could still be updated, reviewed, and merged in time. If not, it can wait. |
The PR is pending another round of review. |
There are multiple ways to configure and build Python, we should try most combinations:
Test:
I'm not how to test cross-compilation :-( |
TL; DR PR 10900 passed my manual tests ;-) I made some tests on PR 10900, commit d1655f9, using 3 shell scripts. (1) step1.sh:set -x -e
|
PGO+LTO build with PR 10900: I see PGO options (-fprofile-instr-generate then -fprofile-instr-use=code.profclangd) and LTO option (-flto) passed to the compiler and to the linker, as expected: $ git clean -fdx
$ ./configure CC=clang --with-lto --prefix /opt/py38 --enable-optimizations
$ sed -i -e 's/^PROFILE_TASK=.*/PROFILE_TASK=-c pass/' Makefile
$ make
...
# compile Python core
clang ... -flto ... -fprofile-instr-generate ... Modules/main.c
...
# link ./python program
clang -pthread -flto -g -fprofile-instr-generate -Xlinker -export-dynamic -o python Programs/python.o libpython3.8m.a -lpthread -ldl -lutil -lm -lm
...
# compile stdlib C extension
clang ... -flto ... -fprofile-instr-generate ... -c /home/vstinner/prog/python/master/Modules/_heapqmodule.c ...
...
rm -f profile-gen-stamp
...
# compile Python core
clang ... -flto ... -fprofile-instr-use=code.profclangd ... -o Programs/python.o ./Programs/python.c
...
# link ./python program
clang -pthread -flto -g -Xlinker -export-dynamic -o python Programs/python.o libpython3.8m.a -lpthread -ldl -lutil -lm -lm
...
# build struct extension
clang ... -flto ... -fprofile-instr-use=code.profclangd ... -c /home/vstinner/prog/python/master/Modules/_struct.c -o build/temp.linux-x86_64-3.8/home/vstinner/prog/python/master/Modules/_struct.o
warning: no profile data available for file "_struct.c" [-Wprofile-instr-unprofiled]
1 warning generated.
clang -pthread -shared -flto -g build/temp.linux-x86_64-3.8/home/vstinner/prog/python/master/Modules/_struct.o -L/opt/py38/lib -L/usr/local/lib -o build/lib.linux-x86_64-3.8/_struct.cpython-38m-x86_64-linux-gnu.so
... |
This change fixes a regression introduced in 3.6.8rc1 with https://bugs.python.org/issue31354 |
And also 3.7.2rc1 |
Small correction. This regression has been on 3.7 for some time now (since it was the master branch then), but then I requested to have the buggy commit backported to 3.6 to fix the --with-lto flag there. Which unfortunately introduced the issue to 3.6 anyway. Master branch is fixed now and backports are open for 3.7 and 3.6 if those are to be accepted by the release manager. |
I repeated the same tests for Python 3.7 on PR 11264. I replaced "38" with "37" and "3.8" and 3.7" and my 3 scripts :-) I modified step1.sh for PGO+LTO with -O0: set -x -e Test results: ./configure CC=clang --with-lto --prefix /opt/py38 (1) 4 ./configure CC=clang --with-lto --enable-shared (1) 4 ./configure CC=clang --with-lto --enable-optimizations (1) 8 => OK! |
I repeated the same tests for Python 3.6 on PR 11265: all tests are ok! I replaced "38" with "36" and "3.8" and 3.6" and my 3 scripts :-) I modified step1.sh for PGO+LTO and to compile with -O0 (just to make tests faster): similar script than in my previous message. ./configure CC=clang --with-lto --prefix /opt/py36 (1) 4 => OK! ./configure CC=clang --with-lto --prefix /opt/py36 --enable-shared (1) 4 => OK! ./configure CC=clang --with-lto --prefix /opt/py36 --enable-optimizations (1) 8 => OK! |
Just in case, I checked again 3.6 and 3.7 branches with "./configure CC=clang --with-lto --enable-shared": they still pass my manual tests ;-) |
1 similar comment
New changeset f14087a by Ned Deily (Victor Stinner) in branch '3.7': New changeset 92f9024 by Ned Deily (Miss Islington (bot)) in branch '3.7': |
New changeset 92f9024 by Ned Deily (Miss Islington (bot)) in branch '3.7': Since Ned pushed a new fix, I ran again my tests on the 3.7 branch with ./configure CC=clang --with-lto --prefix /opt/py37 --enable-shared: (1) 4 => ok Good! It works (in my tests). -- "make sharedmods" runs "LDSHARED=$BLDSHARED (...) ./python setup.py build" "make libpython(...)" uses $(BLDSHARED) to link libpython. Modules/makesetup uses BLDSHARED to build C extensions of the stdlib. Example from generated Makefile: "Modules/posix$(EXT_SUFFIX): Modules/posixmodule.o; $(BLDSHARED) Modules/posixmodule.o -o Modules/posix$(EXT_SUFFIX) (...)" distutils has a customize_compiler() function which uses LDSHARED from Makefile (can be overriden by environment variables): it doesn't use BLDSHARED. It seems like BLDSHARED is only used to build Python itself and stdlib modules. So I agree that it's ok to add PY_LDFLAGS_NODIST flags to BLDSHARED. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: