Skip to content

gh-82909: Update PC/pyconfig.h to allow disabling pragma based auto-linking #19740

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

Merged
merged 5 commits into from
Mar 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 44 additions & 12 deletions Doc/extending/windows.rst
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,13 @@ gives you access to spam's names, but does not create a separate copy. On Unix,
linking with a library is more like ``from spam import *``; it does create a
separate copy.

.. c:macro:: Py_NO_LINK_LIB

Turn off the implicit, ``#pragma``-based linkage with the Python
library, performed inside CPython header files.

.. versionadded:: 3.14


.. _win-dlls:

Expand All @@ -108,21 +115,46 @@ Using DLLs in Practice
Windows Python is built in Microsoft Visual C++; using other compilers may or
may not work. The rest of this section is MSVC++ specific.

When creating DLLs in Windows, you must pass :file:`pythonXY.lib` to the linker.
To build two DLLs, spam and ni (which uses C functions found in spam), you could
use these commands::
When creating DLLs in Windows, you can use the CPython library in two ways:

1. By default, inclusion of :file:`PC/pyconfig.h` directly or via
:file:`Python.h` triggers an implicit, configure-aware link with the
library. The header file chooses :file:`pythonXY_d.lib` for Debug,
:file:`pythonXY.lib` for Release, and :file:`pythonX.lib` for Release with
the `Limited API <stable-application-binary-interface>`_ enabled.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See also #134830


To build two DLLs, spam and ni (which uses C functions found in spam), you
could use these commands::

cl /LD /I/python/include spam.c
cl /LD /I/python/include ni.c spam.lib

The first command created three files: :file:`spam.obj`, :file:`spam.dll`
and :file:`spam.lib`. :file:`Spam.dll` does not contain any Python
functions (such as :c:func:`PyArg_ParseTuple`), but it does know how to find
the Python code thanks to the implicitly linked :file:`pythonXY.lib`.

The second command created :file:`ni.dll` (and :file:`.obj` and
:file:`.lib`), which knows how to find the necessary functions from spam,
and also from the Python executable.

2. Manually by defining :c:macro:`Py_NO_LINK_LIB` macro before including
:file:`Python.h`. You must pass :file:`pythonXY.lib` to the linker.

To build two DLLs, spam and ni (which uses C functions found in spam), you
could use these commands::

cl /LD /I/python/include spam.c ../libs/pythonXY.lib
cl /LD /I/python/include ni.c spam.lib ../libs/pythonXY.lib
cl /LD /DPy_NO_LINK_LIB /I/python/include spam.c ../libs/pythonXY.lib
cl /LD /DPy_NO_LINK_LIB /I/python/include ni.c spam.lib ../libs/pythonXY.lib

The first command created three files: :file:`spam.obj`, :file:`spam.dll` and
:file:`spam.lib`. :file:`Spam.dll` does not contain any Python functions (such
as :c:func:`PyArg_ParseTuple`), but it does know how to find the Python code
thanks to :file:`pythonXY.lib`.
The first command created three files: :file:`spam.obj`, :file:`spam.dll`
and :file:`spam.lib`. :file:`Spam.dll` does not contain any Python
functions (such as :c:func:`PyArg_ParseTuple`), but it does know how to find
the Python code thanks to :file:`pythonXY.lib`.

The second command created :file:`ni.dll` (and :file:`.obj` and :file:`.lib`),
which knows how to find the necessary functions from spam, and also from the
Python executable.
The second command created :file:`ni.dll` (and :file:`.obj` and
:file:`.lib`), which knows how to find the necessary functions from spam,
and also from the Python executable.

Not every identifier is exported to the lookup table. If you want any other
modules (including Python) to be able to see your identifiers, you have to say
Expand Down
4 changes: 4 additions & 0 deletions Doc/whatsnew/3.14.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1381,6 +1381,10 @@ Build changes
* GNU Autoconf 2.72 is now required to generate :file:`configure`.
(Contributed by Erlend Aasland in :gh:`115765`.)

* ``#pragma``-based linking with ``python3*.lib`` can now be switched off
with :c:expr:`Py_NO_LINK_LIB`. (Contributed by Jean-Christophe
Fillion-Robin in :gh:`82909`.)

.. _whatsnew314-pep761:

PEP 761: Discontinuation of PGP signatures
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
``#pragma``-based linking with ``python3*.lib`` can now be switched off with
:c:expr:`Py_NO_LINK_LIB`. Patch by Jean-Christophe Fillion-Robin.
8 changes: 6 additions & 2 deletions PC/pyconfig.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -311,9 +311,13 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */
#ifdef MS_COREDLL
# if !defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_BUILTIN)
/* not building the core - must be an ext */
# if defined(_MSC_VER)
# if defined(_MSC_VER) && !defined(Py_NO_LINK_LIB)
Comment on lines 311 to +314
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This whole set of conditions is pretty ugly... any interest in simplifying?

Ideally in this order:

  • check if the feature is explicitly disabled (new variable)
  • check if we're in a context where it should be implicitly disabled (Py_BUILD_CORE[_BUILTIN])
  • check if the compiler supports it (_MSC_VER)

The order doesn't need to be spelled out to anyone reading it, but it should make it easiest to read (the first check has the best name) and easiest to maintain (alternate compilers can be supported in the "middle", not the edges).

It also really doesn't need to be indented by 8 characters. Four would be plenty.

/* So MSVC users need not specify the .lib
file in their Makefile */
/* Define Py_NO_LINK_LIB to build extension disabling pragma
based auto-linking.
This is relevant when using build-system generator (e.g CMake) where
the linking is explicitly handled */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment isn't important for this file, though a short header above the entire block (something like "automatically reference python3x.lib") might make it easier to understand the purpose without reading the whole way through.

# if defined(Py_GIL_DISABLED)
# if defined(_DEBUG)
# pragma comment(lib,"python314t_d.lib")
Expand All @@ -331,7 +335,7 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */
# pragma comment(lib,"python314.lib")
# endif /* _DEBUG */
# endif /* Py_GIL_DISABLED */
# endif /* _MSC_VER */
# endif /* _MSC_VER && !Py_NO_LINK_LIB */
# endif /* Py_BUILD_CORE */
#endif /* MS_COREDLL */

Expand Down
Loading
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy