setuptools: build shared libary from C++ code, then build Cython wrapper linked to shared libary

0 votes

We have a bunch of C++ files with classes that we wrap to Python using Cython. We use setuptools to build the Cython extension. This all works fine, we followed the guide herehttp://cython.readthedocs.io/en/latest/src/userguide/wrapping_CPlusPlus.html

We are basically doing something like this

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

setup(ext_modules = cythonize(
           "rect.pyx",                 # our Cython source
           sources=["Rectangle.cpp"],  # additional source file(s)
           language="c++",             # generate C++ code
      ))

We don't like about this that we have to recompile everything, even if only the Cython part changes, rect.pyx in this example. In fact we never touch the .cpp files, but change the .pyx files often.

We would like to compile the .cpp files separately into a static or shared libary, then build .pyxfiles independenty, which link to the library generated from the .cpp files. All this would be easy with make or cmake, but we want a pure Python solution that uses only setuptools. Mock-up code would look something like this:

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

class CppLibary:
    # somehow get that to work

# this should only recompile cpplib when source files changed
cpplib = CppLibary('cpplib',
                   sources=["Rectangle.cpp"], # put static cpp code here
                   include_dirs=["include"])

setup(ext_modules = cythonize(
           "rect.pyx",                 # our Cython source
           libraries=[cpplib],         # link to cpplib
           language="c++",             # generate C++ code
      ))

Sep 11, 2018 in Python by bug_seeker
• 15,350 points
31 views

1 answer to this question.

0 votes

There is a seemingly undocumented feature of setup that can do this, for example:

import os

from setuptools import setup
from Cython.Build import cythonize

ext_lib_path = 'rectangle'
include_dir = os.path.join(ext_lib_path, 'include')

sources = ['Rectangle.cpp']

# Use as macros = [('<DEFINITION>', '<VALUE>')]
# where value can be None
macros = None

ext_libraries = [['rectangle', {
               'sources': [os.path.join(ext_lib_path, src) for src in sources],
               'include_dirs': [include_dir],
               'macros': macros,
               }
]]

extensions = [Extension("rect",
              sources=["rect.pyx"],
              language="c++",
              include_dirs=[include_dir],
              libraries=['rectangle'],
)]

setup(ext_modules=cythonize(extensions),
      libraries=ext_libraries)

The libraries argument builds the external library found in directory rectangle, with include directory rectangle/include common between it and the extension.

Have also switched the import to setuptools from distutils which is deprecated, now part of setuptools.

Have not seen any documentation on this argument but seen it used in other projects.

This is untested, please provide sample files for testing if it does not work.

answered Sep 11, 2018 by Priyaj
• 56,900 points

Related Questions In Python

0 votes
1 answer

How to get status code from Python Requests?

Here's how you can get the status ...READ MORE

answered May 13 in Python by Rasheed
68 views
0 votes
1 answer

Python code to send an email message from my gmail to many others

Hey @Varsha, you can try out the ...READ MORE

answered Jun 11 in Python by Travis
74 views
0 votes
1 answer

Python code to send an email message from 1 email id to another

Hi @Deb, try out the following code: import ...READ MORE

answered Jun 11 in Python by Picentra
36 views
0 votes
1 answer

Is it possible to access .NET code written in C# from Python?

If you want to mainly base your ...READ MORE

answered Jul 18 in Python by Arvind
• 2,960 points
34 views
+1 vote
2 answers

how can i count the items in a list?

Syntax :            list. count(value) Code: colors = ['red', 'green', ...READ MORE

answered Jul 6 in Python by Neha
• 330 points

edited Jul 8 by Kalgi 330 views
0 votes
1 answer

setuptools: build shared libary from C++ code, then build Cython wrapper linked to shared libary

There is a seemingly undocumented feature of setup that ...READ MORE

answered Sep 21, 2018 in Python by Priyaj
• 56,900 points
173 views
0 votes
1 answer

How to exit from Python without traceback?

Perhaps you're trying to catch all exceptions ...READ MORE

answered Jul 31, 2018 in Python by Priyaj
• 56,900 points
757 views