Skip to content
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

bpo-44133: Link Python executable with object files #30556

Merged
merged 3 commits into from
Jan 13, 2022
Merged

bpo-44133: Link Python executable with object files #30556

merged 3 commits into from
Jan 13, 2022

Conversation

vstinner
Copy link
Member

@vstinner vstinner commented Jan 12, 2022

When Python is built without --enable-shared, the "python" program is
now linked to object files, rather than be linked the Python static
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.

  • Reorganize configure.ac to check --without-static-libpython
    earlier.
  • Add LINK_PYTHON_OBJS and LINK_PYTHON_DEPS variables to Makefile.

https://bugs.python.org/issue44133

@vstinner
Copy link
Member Author

With this change, import ctypes; assert hasattr(ctypes.pythonapi, 'Py_FrozenMain') no longer fails: the symbol is now available in all tests. I tested 4 cases.

The "python" file only exports the symbol when it's not linked to libpython.so.

When libpython.so exists, il always exports the symbol.

Case 1 (no option):

$ ls *.a *.so
# no file
# grep '^LINK_PYTHON_' Makefile
LINK_PYTHON_DEPS=$(LIBRARY_DEPS)
LINK_PYTHON_OBJS=$(LIBRARY_OBJS)
++ objdump -T ./python | grep Py_FrozenMain
00000000006722b2 g    DF .text	0000000000000285  Base        Py_FrozenMain
# ./python test.py
python binary has Py_FrozenMain symbol? True

Case 2, --without-static-libpython --enable-shared:

$ ls *.a *.so
libpython3.11d.so
$ grep '^LINK_PYTHON_' Makefile
LINK_PYTHON_DEPS=$(LIBRARY_DEPS)
LINK_PYTHON_OBJS=$(BLDLIBRARY)
$ objdump -T ./python | grep Py_FrozenMain
# not found
$ objdump -T libpython3.11d.so | grep Py_FrozenMain
00000000003b368a g    DF .text	00000000000002a9  Base        Py_FrozenMain
# ./python test.py
python binary has Py_FrozenMain symbol? True

Case 3, --without-static-libpython:

$ ls *.a *.so
# no file
$ grep '^LINK_PYTHON_' Makefile
LINK_PYTHON_DEPS=$(LIBRARY_DEPS)
LINK_PYTHON_OBJS=$(LIBRARY_OBJS)
$ objdump -T ./python | grep Py_FrozenMain
00000000006722b2 g    DF .text	0000000000000285  Base        Py_FrozenMain
# ./python test.py
python binary has Py_FrozenMain symbol? True

Case 4, --enable-shared:

$ ls *.a *.so
libpython3.11d.a  libpython3.11d.so
$ grep '^LINK_PYTHON_' Makefile
LINK_PYTHON_DEPS=$(LIBRARY_DEPS)
LINK_PYTHON_OBJS=$(BLDLIBRARY)
$ objdump -T ./python | grep Py_FrozenMain
# no result
$ objdump -T libpython3.11d.so | grep Py_FrozenMain
00000000003b368a g    DF .text	00000000000002a9  Base        Py_FrozenMain
$ ./python test.py
python binary has Py_FrozenMain symbol? True

@vstinner
Copy link
Member Author

I don't know how to test this change on macOS to build Python with the "framework".

@vstinner
Copy link
Member Author

@tiran @erlend-aasland: Would you mind to review this change?

cc @encukou

@vstinner
Copy link
Member Author

On my Fedora 35, if I compare objdump -T ./python output on Python configure with --without-static-libpython, the difference with this PR is a single additional symbol: Py_FrozenMain() is now exported. Hopefully, no other symbol was missing previously.

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.
@vstinner
Copy link
Member Author

PR rebased to fix merge conflicts.

@vstinner
Copy link
Member Author

I may be a good idea to test this build change on buildbots before merging the PR :-) Fedora and RHEL buildbots use --without-static-libpython.

@shihai1991
Copy link
Member

The gate failed. the test of this PR should be skipped in wins?

@shihai1991 shihai1991 added the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Jan 13, 2022
@bedevere-bot
Copy link

🤖 New build scheduled with the buildbot fleet by @shihai1991 for commit c5c7102 🤖

If you want to schedule another build, you need to add the ":hammer: test-with-buildbots" label again.

@bedevere-bot bedevere-bot removed the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Jan 13, 2022
@vstinner vstinner requested a review from a team as a code owner January 13, 2022 11:06
@vstinner
Copy link
Member Author

@shihai1991: "The gate failed. the test of this PR should be skipped in wins?"

No, the symbol must be present on all platforms. I pushed a fix.

@vstinner
Copy link
Member Author

Ah, adding frozenmain.c to the pythoncore project makes the Windows build to fail:

frozenmain.obj : error LNK2001: unresolved external symbol _PyWinFreeze_ExeTerm [D:\a\cpython\cpython\PCbuild\pythoncore.vcxproj]
frozenmain.obj : error LNK2001: unresolved external symbol _PyInitFrozenExtensions [D:\a\cpython\cpython\PCbuild\pythoncore.vcxproj]
frozenmain.obj : error LNK2001: unresolved external symbol _PyWinFreeze_ExeInit [D:\a\cpython\cpython\PCbuild\pythoncore.vcxproj]

@vstinner
Copy link
Member Author

vstinner commented Jan 13, 2022

Ok, I give up for this PR (I skip the test on Windows): I have no idea how to add Py_FrozenMain() on Windows if it requires 3 symbols when Python is linked.

Maybe Py_FrozenMain() should be modified to load these symbols at runtime on Windows?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants