I have recently discovered the cffi
Python module and I would like to use it to write unit tests for some C code I have written in Python. One (arguably simple) thing that I can't wrap my head around is how to compile several C source files into one Python module that can then be imported by Python code.
Say for example I have four C files, a.c
, a.h
, b.c
and b.h
such that a.c
includes both a.h
and b.h
and calls functions implemented in b.c
. And b.c
only includes b.h
.
If I wanted to write unit tests for functions implemented in b.c
I could simply do this:
import cffi
with open('b.h', 'r') as f:
b_h = f.read()
with open('b.c', 'r') as f:
b_c = f.read()
ffi = cffi.FFI()
ffi.cdef(b_h)
ffi.set_source('_b', b_c)
# import _b ...
But what if I want to write unit tests for functions defined in a.c
?
The core idea is to use:
ffi.set_source("_mytest", '''
#include "a.h"
''', sources=["a.c", "b.c"])
to compile a module containing both a.c
and b.c
and including a.h
, which itself includes b.h
. This uses the distutils argument sources=[..]
to give additional source files to be compiled into the same extension module. Above that line, you can use ffi.cdef()
on the C declarations that are of interest to you---usually a subset of both a.h
and b.h
. (You can call ffi.cdef()
more than once, or just once on a string made by concatenating several pieces.)