How should I dynamically generate and compile a C library for use with ctypes?

119 views Asked by At

I already have a working solution for my question, but I'd like more control.

Here's the full description of the desired behavior: due to efficiency issues, I need to execute some C code on numpy arrays. I have a Python module that generates this C code depending on some parameters that I give at runtime. I would like to compile this C code into a dynamic library, then load it with ctypes and call it for my numpy arrays. The prototype of the functions I'm using will never change, only their content, so the ctypes call itself is fixed and hidden somewhere else already.

The way I achieve this right now is with the following code:

self.write_cfile(cfile_name)
builder = distutils.command.build_ext.build_ext(
distutils.dist.Distribution({'name' : os.path.basename(cfile_name)}))
builder.extensions = [
        distutils.core.Extension(
               'lib' + os.path.basename(cfile_name),
               sources = [cfile_name + '.c'])]
builder.build_lib = os.path.abspath(lib_folder)
builder.build_temp = tempfile.gettempdir()
builder.swig_opts = []
builder.verbose = True
builder.run()
self.clib = np.ctypeslib.load_library(
               'lib' + os.path.basename(cfile_name),
               lib_folder)

I can then access self.clib with no issues, and the code works as intended. However, I don't see any of the output from the compilation itself (I originally assumed that verbose option would help) and I have no idea what compilation options are passed to the compiler (I'm just hoping the default -O2 is in there).

Could anyone provide an alternative to using distutils's build_ext command (I did notice that there's a ccompiler in there somewhere, but I couldn't get around the documentation), or maybe give me some pointers about better controlling the behavior of build_ext itself?

EDIT: After crawling through the distutils sources for a while, I did discover that there was a log object called in the spawn function, and this answer https://stackoverflow.com/a/14100459/4205267 showed me how I can control the verbosity. Now, when I import everything, I just add these two lines:

import distutils.log
distutils.log.set_verbosity(1)

I'm still not sure if this is the best way to do this though...

0

There are 0 answers