From f444edb2bc4818b87719255c5a954ec9b7a261a8 Mon Sep 17 00:00:00 2001 From: Xavier de Gaye Date: Sat, 18 Nov 2017 11:22:22 +0100 Subject: [PATCH 1/2] bpo-32059: detect_modules() in setup.py now also searches the sysroot paths when cross-compiling --- .../2017-11-18-11-19-28.bpo-32059.a0Hxgp.rst | 2 + setup.py | 50 ++++++++++++++++--- 2 files changed, 45 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/Build/2017-11-18-11-19-28.bpo-32059.a0Hxgp.rst diff --git a/Misc/NEWS.d/next/Build/2017-11-18-11-19-28.bpo-32059.a0Hxgp.rst b/Misc/NEWS.d/next/Build/2017-11-18-11-19-28.bpo-32059.a0Hxgp.rst new file mode 100644 index 00000000000000..a071bd8b325048 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2017-11-18-11-19-28.bpo-32059.a0Hxgp.rst @@ -0,0 +1,2 @@ +``detect_modules()`` in ``setup.py`` now also searches the sysroot paths +when cross-compiling. diff --git a/setup.py b/setup.py index cbe6139ddec69f..4a3f27dffacba7 100644 --- a/setup.py +++ b/setup.py @@ -7,6 +7,7 @@ import importlib.util import sysconfig +import distutils from distutils import log from distutils.errors import * from distutils.core import Extension, setup @@ -60,6 +61,34 @@ def add_dir_to_list(dirlist, dir): return dirlist.insert(0, dir) +def sysroot_paths(make_vars, subdirs): + """Get the paths of sysroot sub-directories. + + * make_vars: a sequence of names of variables of the Makefile where + sysroot may be set. + * subdirs: a sequence of names of subdirectories used as the location for + headers or libraries. + """ + + dirs = [] + for var_name in make_vars: + # When cross-compiling, the variables from the sysconfig module are + # those of the native python process. We need those of the current + # build instead and use distutils.sysconfig. + var = distutils.sysconfig.get_config_var(var_name) + if var is not None: + m = re.search(r'--sysroot=([^"]\S*|"[^"]+")', var) + if m is not None: + sysroot = m.group(1).strip('"') + for subdir in subdirs: + if os.path.isabs(subdir): + subdir = subdir[1:] + path = os.path.join(sysroot, subdir) + if os.path.isdir(path): + dirs.append(path) + break + return dirs + def macosx_sdk_root(): """ Return the directory of the current OSX SDK, @@ -559,18 +588,25 @@ def detect_modules(self): add_dir_to_list(self.compiler.include_dirs, sysconfig.get_config_var("INCLUDEDIR")) + system_lib_dirs = ['/lib64', '/usr/lib64', '/lib', '/usr/lib'] + system_include_dirs = ['/usr/include'] # lib_dirs and inc_dirs are used to search for files; # if a file is found in one of those directories, it can # be assumed that no additional -I,-L directives are needed. if not cross_compiling: - lib_dirs = self.compiler.library_dirs + [ - '/lib64', '/usr/lib64', - '/lib', '/usr/lib', - ] - inc_dirs = self.compiler.include_dirs + ['/usr/include'] + lib_dirs = self.compiler.library_dirs + system_lib_dirs + inc_dirs = self.compiler.include_dirs + system_include_dirs else: - lib_dirs = self.compiler.library_dirs[:] - inc_dirs = self.compiler.include_dirs[:] + # Add the sysroot paths. 'sysroot' is a compiler option used to + # set the logical path of the standard system headers and + # libraries. The 'CFLAGS', 'LDFLAGS' and 'CPPFLAGS' variables are + # the 'PY_CFLAGS', 'PY_LDFLAGS' and 'PY_CPPFLAGS' of the Makefile + # when they are obtained from distutils.sysconfig. + lib_dirs = (self.compiler.library_dirs + + sysroot_paths(('LDFLAGS', 'CC'), system_lib_dirs)) + inc_dirs = (self.compiler.include_dirs + + sysroot_paths(('CPPFLAGS', 'CFLAGS', 'CC'), + system_include_dirs)) exts = [] missing = [] From 8f4803855e6bea8dfd815bdc9ad297485908fe06 Mon Sep 17 00:00:00 2001 From: Xavier de Gaye Date: Thu, 23 Nov 2017 15:27:27 +0100 Subject: [PATCH 2/2] Do not use distutils.sysconfig When cross-compiling the sysconfig module uses the newly built sysconfigdata file since setup.py is run with the _PYTHON_SYSCONFIGDATA_NAME environment variable set to its file name (see 92dec548ff1494b86f08bd3753ca91a9330b4ea9). --- setup.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/setup.py b/setup.py index 4a3f27dffacba7..0678ddec4149ec 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,6 @@ import importlib.util import sysconfig -import distutils from distutils import log from distutils.errors import * from distutils.core import Extension, setup @@ -72,10 +71,7 @@ def sysroot_paths(make_vars, subdirs): dirs = [] for var_name in make_vars: - # When cross-compiling, the variables from the sysconfig module are - # those of the native python process. We need those of the current - # build instead and use distutils.sysconfig. - var = distutils.sysconfig.get_config_var(var_name) + var = sysconfig.get_config_var(var_name) if var is not None: m = re.search(r'--sysroot=([^"]\S*|"[^"]+")', var) if m is not None: @@ -599,9 +595,7 @@ def detect_modules(self): else: # Add the sysroot paths. 'sysroot' is a compiler option used to # set the logical path of the standard system headers and - # libraries. The 'CFLAGS', 'LDFLAGS' and 'CPPFLAGS' variables are - # the 'PY_CFLAGS', 'PY_LDFLAGS' and 'PY_CPPFLAGS' of the Makefile - # when they are obtained from distutils.sysconfig. + # libraries. lib_dirs = (self.compiler.library_dirs + sysroot_paths(('LDFLAGS', 'CC'), system_lib_dirs)) inc_dirs = (self.compiler.include_dirs +