Search code examples
pythonnumpydistutils

Odd choice of architecture by numpy.distutils


I'm trying to create a Python package with some C code and NumPy dependency, and I thought using numpy.distutils would be the simplest way to achieve that. So far I have setup.py file

from numpy.distutils.core import setup
from numpy.distutils.misc_util import Configuration
from distutils.extension import Extension

ext_modules=[
    Extension("test",
              sources=["test.c"],
              libraries=["gmp"],
    )
]

configuration = Configuration(
    package_name = "test",
    ext_modules = ext_modules,
)

setup(**configuration.todict())

and empty test.c in the same directory.

But for some reason, it adds awkward -arch i386 -arch x86_64 flags during compilation (the system is Mac OS X), which leads to

ld: warning: ignoring file /usr/local/lib/libgmp.dylib, 
file was built for x86_64 which is not the architecture being linked (i386):  
/usr/local/lib/libgmp.dylib

warning and further problems in invoking C functions.

How do I fix that behavior? Can I specify the target architecture somehow?

UPD. Currently I just do

ARCHFLAGS="-arch x86_64" python setup.py build_ext  --inplace

But I'd like it to work on any platform without a priori knowledge of architecture, so that I could deploy it.


Solution

  • I don't believe these are added by numpy.distutils but distutils itself. distutils gets these flags from how Python was built, which in your case, was built as a fat binary with both 32-bit and 64-bit architectures. This information is obtained from the $PREFIX/lib/python<version>/config/Makefile file.

    This is a pretty normal thing for people building packages with binary dependencies to have to deal with. You don't know whether their Python was built fat or thin, nor do you know how they built their libgmp.dylib. With a lot of effort, you could write some code in your setup.py that locates the libgmp.dylib, interrogates it for its architecture, then configures distutils to only use the right flags (and still correctly operate when this isn't necessary, fail gracefully, etc.). But you probably get more bang for your development effort by simply documenting that this may come up and the ARCHFLAGS= solution.