Using setuptools to create a cython package calling an external C library
Question: I am trying to compile, install and run a package that we'll call `myPackage`.
It contains a `*.pyx` file that calls the function `fftw_set_timelimit()` from
library `fftw`. Currently, when I run a script `clientScript.py` that imports
the package I obtain the following error message :

    
    
    Traceback (most recent call last):
      File "clientScript.py", line 5, in <module>
        import myPackage.myModule
    ImportError: /usr/local/lib/python2.7/dist-packages/myPackage/myModule.so: undefined symbol: fftw_set_timelimit
    

From what I understand (I am quite new to python and cython), the linking with
the C library is not yet performed in my package. Indeed, my `setup.py` file
looks like this :

    
    
    from setuptools   import setup,find_packages
    from Cython.Build import cythonize
    import os
    
    setup(
        name = "myPackage",
        version = "0.0.1",
        url = "none",
        author = "me",
        author_email = "me@me.me",
        packages=find_packages(),
        ext_modules = cythonize("pyClo/pyClo.pyx"),
    )
    

As you can see my `setup.py` file uses `setuptools`. I decided to do so since
it is recommended by the [Python Packaging User Guide](https://python-
packaging-user-guide.readthedocs.org/en/latest/current.html). However, the
instructions in the [Cython
documentation](http://docs.cython.org/src/tutorial/cython_tutorial.html) use
`distutils` instead. Linking libraries is done through a call to
`distutils.Extension('file',['file.pyx'],libraries='fftw')`. How do I achieve
the same result using `setuptools` ?


Answer: It turns out `setuptools` has a module `setuptools.extension.Extension` which
is used in the same way as the `distutils.extension.Extension` module .

In the end, the `setup.py` file looks something like :

    
    
    from setuptools import setup, find_packages
    from setuptools.extension import Extension
    from Cython.Build import cythonize
    
    extensions = [
        Extension(
            "myPackage/myModule",
            ["myPackage/myModule.pyx"],
            include_dirs=['/some/path/to/include/'], # not needed for fftw unless it is installed in an unusual place
            libraries=['fftw3', 'fftw3f', 'fftw3l', 'fftw3_threads', 'fftw3f_threads', 'fftw3l_threads'],
            library_dirs=['/some/path/to/include/'], # not needed for fftw unless it is installed in an unusual place
        ),
    ]
    
    setup(
        name = "myPackage",
        packages = find_packages(),
        ext_modules = cythonize(extensions)
    )
    

Here is an overview of my installation directory :

    
    
    .
    ├── MANIFEST.in
    ├── myPackage
    │   └── myModule.pyx
    ├── README.rst
    └── setup.py
    

where `myModule.pyx` is the file that calls `fftw_set_timelimit()`.

`MANIFEST.in` contains :

    
    
    include myPackage/*.*
    

and `README.rst` is a mere plain text file.

