From 77f5139954a878b856b0ac4c76486b27b6f4ec26 Mon Sep 17 00:00:00 2001
From: xdegaye <xdegaye@gmail.com>
Date: Sat, 25 Nov 2017 17:25:30 +0100
Subject: [PATCH] bpo-32059: setup.py now also searches the sysroot paths
 (GH-4452)

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                                      | 44 ++++++++++++++++---
 2 files changed, 39 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 0000000000..a071bd8b32
--- /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 cbe6139dde..0678ddec41 100644
--- a/setup.py
+++ b/setup.py
@@ -60,6 +60,31 @@ 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:
+        var = 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 +584,23 @@ class PyBuildExt(build_ext):
             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.
+            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 = []
 
-- 
2.40.0