marius
marius

Reputation: 1442

Can I create a static Cython library using distutils?

I'd like to build a static Cython library using distutils. I don't care about having it be a true Python extension module that can be import'ed. I just want to compile the code and put the objects in a static library. The code to create a dynamic library is very simple,

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

setup(
   cmdclass = {'build_ext':build_ext},
   ext_modules = [Extension("test",["test.pyx"])]
)

Is there a simple way to make it static instead?

Upvotes: 7

Views: 2988

Answers (3)

Adnan Y
Adnan Y

Reputation: 3230

Assuming that you have a sources, include_dirs and build_dir in your setup.py, this is how you can build a static library

from distutils.ccompiler import new_compiler 
from sysconfig import get_paths 
import os

project_name = "slimey_project"
source = ['source1.c']
include_dirs = ['include']
build_dir = os.path.join(os.path.dirname(__file__), 'build')

class StaticLib(Command): 
    description = 'build static lib' 
    user_options = [] # do not remove, needs to be stubbed out! 
    python_info = get_paths() 

    def initialize_options(self):
        pass

    def finalize_options(self):
        pass

    def run(self):
        # Create compiler with default options
        c = new_compiler()

        # Optionally add include directories etc.
        for d in include_dirs:
            c.add_include_dir(d)

        c.add_include_dir(self.python_info['include'])
        # Compile into .o files
        objects = c.compile(sources)

        # Create static or shared library
        c.create_static_lib(objects, project_name, output_dir=build_dir)

Source: https://gist.github.com/udnaan/d549950a33fd82d13f9e6ba4aae82964

Upvotes: 0

marius
marius

Reputation: 1442

Fyi, this works using numpy distutils, but obviously is nowhere near the simplicity or probably portability of the original code for a shared library,

from Cython.Compiler.Main import compile
from numpy.distutils.misc_util import Configuration

compile('test.pyx')
config = Configuration(...)
config.add_installed_library('test',
                         ['test.c'],
                         'test',
                         {'include_dirs':[get_python_inc()]})

Upvotes: 1

lothario
lothario

Reputation: 1868

Distutils is very limited and not set up for static builds. I would advise you to use something else to compile the static library part of your project.

If your use case is to call into Cython code from other C code, then you want to use the public or api declarations along with your cdef declared functions and variables in your Cython code. Cython will allow the so-declared objects to be called from external C code, and it will generate a .h file alongside the .c file for you.

Upvotes: 2

Related Questions