28

It seems that by default setup from distutils.core with cmdclass set to build_ext, compiles a cpp or c file in the current working directory. Is there a way to determine where the generated c code is written to? Otherwise, a repository will be littered with generated code.

For example this file setup.py will write a file example.c to the current working directory:

from distutils.core import setup
from Cython.Build import cythonize

setup(
      ext_modules = cythonize("example.pyx"))
Michael WS
  • 2,450
  • 4
  • 24
  • 46

3 Answers3

22

You can pass the option build_dir="directory name" to Cythonize

# rest of file as before
setup(
      ext_modules = cythonize("example.pyx",
                              build_dir="build"))

The above code will put the generated c files in the directory "build" (which makes sense, since by default it's where distutils puts temporary object files and so forth when it's building).


My original answer had working, not build_dir. Thanks to @ArthurTacca for pointing out that that no longer seems to be right.

DavidW
  • 29,336
  • 6
  • 55
  • 86
  • 1
    The correct option seems to be "build_dir" not "working". Perhaps it changed in a recent version of Cython. To avoid clashing with other build files, it's probably best not to just use "build". A subdirectory like "build/cython" would be better. – Arthur Tacca Mar 31 '17 at 14:57
  • At a quick glance you look to be right - thanks. Looking at the code on github I can't see where it's changed since 2015 so who knows where I got it from (but I imagine it must have worked at the time...). I'll update it once I've confirmed that it does work. – DavidW Mar 31 '17 at 15:27
  • 4
    But how to specify a path to build the .so files? – Sayan Sen Jun 02 '20 at 06:20
14

After initializing an Extension, the parameters can be set to create c in temp directory.

module  = Extension("temp", "temp.pyx")
module.cython_c_in_temp = True 
Josh Correia
  • 3,807
  • 3
  • 33
  • 50
Michael WS
  • 2,450
  • 4
  • 24
  • 46
9

Your setup.py is fine.

To get it to build to a different location, invoke python in the following way:

python setup.py build_ext --build-lib <build directory>

I use the following make rules to automate this:

python_lib_dir=src/lib

cython_output = $(patsubst $(python_lib_dir)/%.pyx,$(python_lib_dir)/%.so, $(shell find $(python_lib_dir) -name '*.pyx'))

$(cython_output):%.so:%.pyx      
    python setup.py build_ext --build-lib $(python_lib_dir)