pypa / distutils

distutils as found in cpython

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Allow overriding SYSROOT for e.g. cross-compilation

thesamesam opened this issue · comments

When cross-compiling distutils packages, distutils injects -I/usr/include/python3.10 which isn't prefixed and doesn't respect SYSROOT.

In this case, it should be -I/usr/include/armv7a-unknown-linux-gnueabihf/python3.10 instead.

Bad example:

armv7a-unknown-linux-gnueabihf-gcc -Wno-unused-result -Wsign-compare -DNDEBUG -O2 -pipe -fomit-frame-pointer -fPIC -I/usr/include/python3.10 -c pydantic/__init__.c -o build/temp.linux-x86_64-cpython-310/pydantic/__init__.o
In file included from /usr/include/python3.10/Python.h:50,
                 from pydantic/__init__.c:18:
/usr/include/python3.10/pyport.h:746:2: error: #error "LONG_BIT definition appears wrong for platform (bad gcc/glibc config?)."

The following patch (thanks @Arfrever) works when tested in Gentoo but I'm not filing a PR with it yet in case it's the wrong approach:

--- a/_distutils/command/build_ext.py
+++ b/_distutils/command/build_ext.py
@@ -134,6 +134,8 @@
     def finalize_options(self):  # noqa: C901
         from distutils import sysconfig
 
+        sysroot = os.environ.get("SYSROOT", "")
+
         self.set_undefined_options(
             'build',
             ('build_lib', 'build_lib'),
@@ -166,9 +168,9 @@
 
         # Put the Python "system" include dir at the end, so that
         # any local include dirs take precedence.
-        self.include_dirs.extend(py_include.split(os.path.pathsep))
+        self.include_dirs.extend(sysroot + x for x in py_include.split(os.path.pathsep))
         if plat_py_include != py_include:
-            self.include_dirs.extend(plat_py_include.split(os.path.pathsep))
+            self.include_dirs.extend(sysroot + x for x in plat_py_include.split(os.path.pathsep))
 
         self.ensure_string_list('libraries')
         self.ensure_string_list('link_objects')
@@ -238,7 +240,7 @@
         if sysconfig.get_config_var('Py_ENABLE_SHARED'):
             if not sysconfig.python_build:
                 # building third party extensions
-                self.library_dirs.append(sysconfig.get_config_var('LIBDIR'))
+                self.library_dirs.append(sysroot + sysconfig.get_config_var('LIBDIR'))
             else:
                 # building python standard extensions
                 self.library_dirs.append('.')

I'm not sure I follow. What is SYSROOT set to such that prefixing that value transforms /usr/include/python3.10 to /usr/include/armv7a-unknown-linux-gnueabihf/python3.10? Can you write a test that captures the missed expectation? Please also see #206, where cross-compilation concerns continue to be a problem without a thorough design.