diff options
authorEli Schwartz <>2023-09-10 22:18:37 -0400
committerMichał Górny <>2023-09-14 07:30:08 +0200
commit597762f0cd480abcd18792f519db370a6c249e25 (patch)
treed2566cba5192f494d6ae8c4eb3c8fabeb82bbea4 /eclass/distutils-r1.eclass
parentperl-module.eclass: fix Unquoted Variable (diff)
distutils-r1.eclass: teach setuptools to respect (some) build options
Previously, was handled by: - manually passing makejobs, with a heuristic to guess whether it was a time saver to do so. - rm -rf'ing the build directory in between python versions to prevent cross-version contamination This is because in PEP 517 mode, it doesn't accept build options specific to a setuptools phase. So a crude hack is to just build_ext twice, once explicitly and once internally as part of bdist_wheel, and pray that in the latter case it detects that there's nothing to do. Unfortunately, sometimes build_ext does NOT detect that there is nothing to do -- e.g. for codegen tools such as mypyc, that produce *.c files which are different every time you try building. As for build directories, those were given up on as hopeless. There's a better hack which is to set a magic environment variable for a setup.cfg file which is parsed additionally to the one provided by the project. It can contain additional settings, such as the build-base and parallelism, which means that bdist_wheel intrinsically builds extensions in parallel the only time it is called. And we can set the output directory for all build artifacts to outside of the source tree, so it is no longer necessary to delete them (which among other things, makes debugging difficult). This is similar to .pydistutils.cfg, but is processed later and can be in arbitrary locations. Since we store it in the per-impl build directory we don't need to wipe it after using it to avoid leakage. Signed-off-by: Eli Schwartz <> Signed-off-by: Michał Górny <>
Diffstat (limited to 'eclass/distutils-r1.eclass')
1 files changed, 10 insertions, 38 deletions
diff --git a/eclass/distutils-r1.eclass b/eclass/distutils-r1.eclass
index 91de144e1110..56afcdc5bcb8 100644
--- a/eclass/distutils-r1.eclass
+++ b/eclass/distutils-r1.eclass
@@ -1461,12 +1461,6 @@ distutils_pep517_install() {
[[ -n ${wheel} ]] || die "No wheel name returned"
distutils_wheel_install "${root}" "${WHEEL_BUILD_DIR}/${wheel}"
- # clean the build tree; otherwise we may end up with PyPy3
- # extensions duplicated into CPython dists
- if [[ ${DISTUTILS_USE_PEP517:-setuptools} == setuptools ]]; then
- rm -rf build || die
- fi
# @FUNCTION: distutils-r1_python_compile
@@ -1478,9 +1472,6 @@ distutils_pep517_install() {
# If DISTUTILS_USE_PEP517 is set to any other value, builds a wheel
# using the PEP517 backend and installs it into ${BUILD_DIR}/install.
-# May additionally call build_ext prior to that when using setuptools
-# and the eclass detects a potential benefit from parallel extension
-# builds.
# In legacy mode, runs ' build'. Any parameters passed to this
# function will be appended to invocation, i.e. passed
@@ -1495,40 +1486,21 @@ distutils-r1_python_compile() {
# call build when using setuptools (either via PEP517
# or in legacy mode)
- if [[ ${DISTUTILS_USE_PEP517} ]]; then
- if [[ -d build ]]; then
- eqawarn "A 'build' directory exists already. Artifacts from this directory may"
- eqawarn "be picked up by setuptools when building for another interpreter."
- eqawarn "Please remove this directory prior to building."
- fi
- else
- _distutils-r1_copy_egg_info
- fi
# distutils is parallel-capable since py3.5
local jobs=$(makeopts_jobs "${MAKEOPTS} ${*}")
if [[ ${DISTUTILS_USE_PEP517} ]]; then
- # issue build_ext only if it looks like we have at least
- # two source files to build; setuptools is expensive
- # to start and parallel builds can only benefit us if we're
- # compiling at least two files
- #
- # see for list of suffixes
- # .pyx is added for Cython
- #
- # does not respect SYSROOT, so skip it there
- if [[ -z ${SYSROOT} && ${DISTUTILS_EXT} && 1 -ne ${jobs}
- && 2 -eq $(
- find '(' -name '*.c' -o -name '*.cc' -o -name '*.cpp' \
- -o -name '*.cxx' -o -name '*.c++' -o -name '*.m' \
- -o -name '*.mm' -o -name '*.pyx' ')' -printf '\n' |
- head -n 2 | wc -l
- )
- ]]; then
- build_ext -j "${jobs}" "${@}"
- fi
+ mkdir -p "${BUILD_DIR}" || die
+ local -x DIST_EXTRA_CONFIG="${BUILD_DIR}/extra-setup.cfg"
+ cat > "${DIST_EXTRA_CONFIG}" <<-EOF || die
+ [build]
+ build_base = ${BUILD_DIR}/build
+ [build_ext]
+ parallel = ${jobs}
+ _distutils-r1_copy_egg_info build -j "${jobs}" "${@}"