You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Use pkg-config autoconf macros to detect flags for Modules/Setup #89736
pkg-config [1] is a standard tool on Linux and other platforms to detect presence of dependencies as well as to figure out which compiler and linker flags they require. Development packages provide a .pc file, e.g. ncurses provides a ncursesw.pc file.
I propose to use a modified version of pkg-config's PKG_HAVE_DEFINE_WITH_MODULES macro in our configure script. On succss the modified macro defines:
HAVE_FOO=1
FOO_CFLAGS="some compile flags"
FOO_LIBS="some library flags for linker"
On error, it sets nothing and does not cause configure to stop with an error.
The macro also allows users to override flags by setting FOO_CFLAGS and FOO_LIBS env vars. HAVE_FOO is added to pyconfig.h. The FOO_CFLAGS/LIBS are added to Makefile, from where it can be consumed by Modules/Setup.
Eventually Python could use the flags in setup.py, too. For now I would like to start with Modules/Setup. It is only used by some power users and has less risk of breaking the setup of beginners.
I added some whitespace to Modules/Setup. All lines starting with #([a-z_]) compile cleanly on Fedora 34 with all dependencies available. dbm, tkinter, and sqlite are missing or untested.
We can detect majority of our dependencies with pkg-config. The use of pkg-config has some benefits:
Distro's provide the .pc files in their -dev / -devel packages. The presence of a .pc file indicates that all development dependencies are available.
pkg-config does the right thing for non-standard include and libraries directories as well as multiarch builds. In case a library or header is not on the default search path, pkg-config returns necessary -I and -L flags.
At least the pkgconf implementation of pkg-config standard search /usr/local and ~/.local/ directories for .pc files. Cases like bpo-45774: Autoconfiscate SQLite detection (GH-29507) #29507 are handled correctly. On FreeBSD "pkgconf sqlite3 --cflags --libs" returns "-I/usr/local/include -L/usr/local/lib -lsqlite3".
pkg-config understands dependencies. For example "pkg-config --libs tk" returns linker flags for TK *and* TCL.
pkg-config can check for module version, e.g. "pkg-config sqlite3 --atleast-version=3.7.15"
This all sounds great. I think a goal here should be to remove all header and lib file searching from setup.py as that has always been a bug magnet. Perhaps one workaround for those libs that don't (yet) provide .pc files would be for us to supply reasonable default .pc for them, if possible, so that most builders wouldn't have to set the MODULE_xxx_*FLAGS variables while still removing the header/lib file searching from setup.py? Also it would be great to document how using pkg-config works in generic cross-compiling cases; we should strive to make at least the most common cases just work with minimal tweaking of configure arguments.
gdbmmodule and dbmmodule need special treatment anyway. macOS has dbm-API build into libc. Linux has either libgdbm_compat, libndbm, or libdb. The --with-dbmliborder makes it even more interesting. Users can override in which order they want to probe for gdbm, ndbm, and libdb. We have to keep the "manual" library and header checks.
Is traditional cross-compiling work still useful these days anyway? Emulation has made big leaps in the last decade. Emulated cross compiling with qemu has become widespread. It also has the big advantage that you can run the test suite on the emulated hardware and verify that your binaries work. AFAIK Fedora's build system uses qemu for a bunch of hardware targets.
Erlend implemented pkg-config for sqlite3 in bpo-45774. Thanks to his tireless effort we now have a blue print how to port other checks to optional pkg-config lookup.
Activity
tiran commentedon Oct 22, 2021
pkg-config [1] is a standard tool on Linux and other platforms to detect presence of dependencies as well as to figure out which compiler and linker flags they require. Development packages provide a .pc file, e.g. ncurses provides a ncursesw.pc file.
I propose to use a modified version of pkg-config's PKG_HAVE_DEFINE_WITH_MODULES macro in our configure script. On succss the modified macro defines:
On error, it sets nothing and does not cause configure to stop with an error.
The macro also allows users to override flags by setting FOO_CFLAGS and FOO_LIBS env vars. HAVE_FOO is added to pyconfig.h. The FOO_CFLAGS/LIBS are added to Makefile, from where it can be consumed by Modules/Setup.
Eventually Python could use the flags in setup.py, too. For now I would like to start with Modules/Setup. It is only used by some power users and has less risk of breaking the setup of beginners.
[1] https://www.freedesktop.org/wiki/Software/pkg-config/
tiran commentedon Oct 22, 2021
I added some whitespace to Modules/Setup. All lines starting with
#([a-z_])compile cleanly on Fedora 34 with all dependencies available. dbm, tkinter, and sqlite are missing or untested.tiran commentedon Oct 22, 2021
tiran commentedon Nov 10, 2021
We can detect majority of our dependencies with pkg-config. The use of pkg-config has some benefits:
Distro's provide the .pc files in their -dev / -devel packages. The presence of a .pc file indicates that all development dependencies are available.
pkg-config does the right thing for non-standard include and libraries directories as well as multiarch builds. In case a library or header is not on the default search path, pkg-config returns necessary -I and -L flags.
At least the pkgconf implementation of pkg-config standard search /usr/local and ~/.local/ directories for .pc files. Cases like bpo-45774: Autoconfiscate SQLite detection (GH-29507) #29507 are handled correctly. On FreeBSD "pkgconf sqlite3 --cflags --libs" returns "-I/usr/local/include -L/usr/local/lib -lsqlite3".
pkg-config understands dependencies. For example "pkg-config --libs tk" returns linker flags for TK *and* TCL.
pkg-config can check for module version, e.g. "pkg-config sqlite3 --atleast-version=3.7.15"
pkg-config modules:
readline, libedit
ncursesw, ncurses, panel, tinfo
sqlite3
zlib
bzip2
liblzma
expat
uuid (Linux's util-linux uuid)
libffi
libnsl, libtirpc
libcrypt
tcl, tk
openssl, libssl, libcrypto
modules / libraries without pkg-config modules:
decimal: libmpdec
gdbm: gdbm
dbm: gdbm_compat, ndbm, libdb (bdb)
To simplify use of flags in Modules/Setup, I propose to add two make variables for each module that needs cflags and ldflags:
f"MODULE_{ext.name.upper()}CFLAGS"
f"MODULE{ext.name.upper()}_LDFLAGS"
e.g. for the _ssl module:
Then use the flags from Makefile in setup.py:
Finally update Modules/makesetup to use the new variables, too.
brettcannon commentedon Nov 10, 2021
SGTM!
ned-deily commentedon Nov 10, 2021
SGTM,2
This all sounds great. I think a goal here should be to remove all header and lib file searching from setup.py as that has always been a bug magnet. Perhaps one workaround for those libs that don't (yet) provide .pc files would be for us to supply reasonable default .pc for them, if possible, so that most builders wouldn't have to set the MODULE_xxx_*FLAGS variables while still removing the header/lib file searching from setup.py? Also it would be great to document how using pkg-config works in generic cross-compiling cases; we should strive to make at least the most common cases just work with minimal tweaking of configure arguments.
tiran commentedon Nov 10, 2021
gdbmmodule and dbmmodule need special treatment anyway. macOS has dbm-API build into libc. Linux has either libgdbm_compat, libndbm, or libdb. The --with-dbmliborder makes it even more interesting. Users can override in which order they want to probe for gdbm, ndbm, and libdb. We have to keep the "manual" library and header checks.
Cross-compilation with pkg-config uses a trivial wrapper script, https://autotools.io/pkgconfig/cross-compiling.html . The build system has to create and provide a script with correct sysroot setting.
Is traditional cross-compiling work still useful these days anyway? Emulation has made big leaps in the last decade. Emulated cross compiling with qemu has become widespread. It also has the big advantage that you can run the test suite on the emulated hardware and verify that your binaries work. AFAIK Fedora's build system uses qemu for a bunch of hardware targets.
tiran commentedon Nov 14, 2021
New changeset c399786 by Christian Heimes in branch 'main':
bpo-45573: Use Makefile's dependencies in setup.py (GH-29559)
c399786
brettcannon commentedon Nov 15, 2021
Yes for things like WebAssembly where there is no equivalent of an emulated CPU under QEMU.
tiran commentedon Nov 18, 2021
New changeset 25ecc04 by Christian Heimes in branch 'main':
bpo-45573: Introduce extension module flags in Makefile (GH-29594)
25ecc04
tiran commentedon Nov 18, 2021
New changeset 5275e59 by Christian Heimes in branch 'main':
bpo-45573: check for ossaudiodev in configure (GH-29614)
5275e59
tiran commentedon Nov 18, 2021
New changeset e4bb22f by Christian Heimes in branch 'main':
bpo-45573: Add Modules/Setup.stdlib with conditional modules (GH-29615)
e4bb22f
tiran commentedon Nov 19, 2021
Erlend implemented pkg-config for sqlite3 in bpo-45774. Thanks to his tireless effort we now have a blue print how to port other checks to optional pkg-config lookup.
tiran commentedon Nov 19, 2021
New changeset 7e44dc0 by Christian Heimes in branch 'main':
bpo-45573: Move mandatory core modules to Modules/Setup.bootstrap (GH-29616)
7e44dc0
erlend-aasland commentedon Jan 22, 2023
AFAICS, this is implemented. If you disagree, please re-open or create a new issue describing the problem.