Skip to content

Commit

Permalink
Hooks: distutils: Fix no suitable dest location found for pyconfig.h.
Browse files Browse the repository at this point in the history
Locating `pyconfig.h` and the `makefile` gets into a mess when using
certain environment managers (pyenv-virtualenv) because PyInstaller,
whilst trying to find an appropriate `dest` path to put the files in,
gets confused by `sys.prefix` (or its varients) not being a parent dir of
the config and makefiles. As a (seemingly more rubust) alternative, this
commit uses `sysconfig.get_python_inc(prefix=".")` to choose a dest dir
instead. See pyinstaller#5018.
  • Loading branch information
bwoodsend committed Oct 3, 2020
1 parent 2d707ea commit be6db50
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 16 deletions.
55 changes: 39 additions & 16 deletions PyInstaller/hooks/hook-distutils.py
Expand Up @@ -17,19 +17,42 @@
runtime for platform-specific metadata.
"""

# TODO Verify that bundling Makefile and pyconfig.h is still required for Python 3.

import os
import sysconfig

from PyInstaller.utils.hooks import relpath_to_config_or_make

_CONFIG_H = sysconfig.get_config_h_filename()
_MAKEFILE = sysconfig.get_makefile_filename()

# Data files in PyInstaller hook format.
datas = [(_CONFIG_H, relpath_to_config_or_make(_CONFIG_H))]

# The Makefile does not exist on all platforms, eg. on Windows
if os.path.exists(_MAKEFILE):
datas.append((_MAKEFILE, relpath_to_config_or_make(_MAKEFILE)))
from distutils import sysconfig
import sys
from os import path

from PyInstaller.utils.hooks import logger


if sys.version_info < (3, 6):
# XXX: Pythons >= 3.6 no longer use these files. Once we drop 3.5 support
# we can delete this.

datas = []

# Locate the ``Include`` folder containing the two files.
INCLUDE = sysconfig.get_python_inc()
# Get a dist target location. This seems to handle venv and its many
# variants better than our own attempts involving ``sys.prefix``. See
# https://github.com/pyinstaller/pyinstaller/issues/4775.
DEST = sysconfig.get_python_inc(prefix=".")

for filename in ["pyconfig.h", "Makefile"]:
source = path.join(INCLUDE, filename)
if path.exists(source):
datas.append((source, DEST))
logger.debug("Add '{}' from '{}' to '{}'."
.format(filename, INCLUDE, DEST))
else:
logger.debug("Skip non-existent '{}' from '{}' to '{}'."
.format(filename, INCLUDE, DEST))

else:
# In Python 3.6 and later ``distutils.sysconfig`` takes on the same
# behaviour as regular ``sysconfig`` of moving the config vars to an
# extension module (see hook-sysconfig.py). But it doesn't use a nice
# `get extension module name` function like ``sysconfig`` does. However the
# extension module is the same file that ``sysconfig`` uses so if we run
# the hook for ``sysconfig``, the extension module will be located and
# included.
hiddenimports = ["sysconfig"]
1 change: 1 addition & 0 deletions news/5218.hooks.rst
@@ -0,0 +1 @@
Update hook for ``distutils.sysconfig`` to be compatible with pyenv-virtualenv.

0 comments on commit be6db50

Please sign in to comment.