def main(filename): ffi = FFI() ffi.set_source( "pylibsize", """ # include "libsize.h" """, extra_objects=["libsize.so"], include_dirs=["."], ) ffi.cdef( """\ struct Size_return { int r0; /* w */ int r1; /* h */ }; extern struct Size_return Size(char* p0); """ ) ffi.compile(verbose=True, debug=True) from pylibsize import lib, ffi sizeinfo = lib.Size(filename.encode("utf-8")) print(sizeinfo, sizeinfo.r0, sizeinfo.r1)
def build_ffi(include_recovery=False, include_schnorr=False, include_ecdh=False): ffi = FFI() source = "#include <secp256k1.h>" cdefs = definitions if include_recovery: cdefs += definitions_recovery source += "\n#include <secp256k1_recovery.h>" if include_schnorr: cdefs += definitions_schnorr source += "\n#include <secp256k1_schnorr.h>" if include_ecdh: cdefs += definitions_ecdh source += "\n#include <secp256k1_ecdh.h>" incpath = [os.environ['INCLUDE_DIR']] if 'INCLUDE_DIR' in os.environ else None libpath = [os.environ['LIB_DIR']] if 'LIB_DIR' in os.environ else None ffi.set_source( "_libsecp256k1", source, libraries=["secp256k1"], library_dirs=libpath, include_dirs=incpath) ffi.cdef(cdefs) return ffi
def setup_class(cls): stack_ffi = FFI() stack_ffi.cdef(""" typedef intptr_t ptr_t; int vmp_binary_search_ranges(ptr_t ip, ptr_t * l, int count); int vmp_ignore_ip(ptr_t ip); int vmp_ignore_symbol_count(void); ptr_t * vmp_ignore_symbols(void); void vmp_set_ignore_symbols(ptr_t * symbols, int count); int vmp_read_vmaps(const char * fname); void vmp_native_disable(); """) with open("src/vmp_stack.c", "rb") as fd: source = fd.read().decode() libs = [] #['unwind', 'unwind-x86_64'] if sys.platform.startswith('linux'): libs = ['unwind', 'unwind-x86_64'] # trick: compile with _CFFI_USE_EMBEDDING=1 which will not define Py_LIMITED_API stack_ffi.set_source("vmprof.test._test_stack", source, include_dirs=['src'], define_macros=[('_CFFI_USE_EMBEDDING',1), ('PY_TEST',1), ('VMP_SUPPORTS_NATIVE_PROFILING',1)], libraries=libs, extra_compile_args=['-Werror', '-g']) stack_ffi.compile(verbose=True) from vmprof.test import _test_stack as clib cls.lib = clib.lib cls.ffi = clib.ffi
def _ffi( module_name=MODULE_NAME, headers=HEADER_FILES, sources=SOURCE_FILES, libraries=LIBRARIES): """ Returns an instance of :class:`FFI` without compiling the module. This function is used internally but also as an entrypoint in the setup.py for `cffi_modules`. :keyword str module_name: Optional module name to use when setting the source. :keyword tuple headers: Optional path(s) to the header files. :keyword tuple sources: Optional path(s) to the source files. """ logger.debug( "_ffi(module_name=%r, headers=%r, sources=%r)", module_name, headers, sources) header = _read(*headers) source = _read(*sources) ffi = FFI() ffi.set_unicode(True) ffi.set_source(module_name, source, libraries=libraries) # Windows uses SAL annotations which can provide some helpful information # about the inputs and outputs to a function. Rather than require these # to be stripped out manually we should strip them out programmatically. ffi.cdef(REGEX_SAL_ANNOTATION.sub(" ", header)) return ffi
def main(defs_file, parser_file, verbose): ffi = FFI() with open(defs_file) as f: ffi.embedding_api(f.read()) ffi.set_source('parser_interface', '#include "%s"' % defs_file) with open(parser_file) as f: ffi.embedding_init_code(f.read()) interpreter, _, _ = os.path.basename(sys.executable).partition('.') ffi.compile(target='libplease_parser_%s.*' % interpreter, verbose=verbose)
def test_no_cross_include(): baseffi = FFI() baseffi.set_source('test_no_cross_include_base', "..source..") # ffi = FFI() ffi.include(baseffi) target = udir.join('test_no_cross_include.py') py.test.raises(VerificationError, make_py_source, ffi, 'test_no_cross_include', str(target))
def _buildlib(): cdef, src = _getcode() libname = _getlibname() from cffi import FFI ffibuilder = FFI() ffibuilder.cdef(cdef) ffibuilder.set_source(libname, src) dir = os.path.abspath(os.path.dirname(__file__)) ffibuilder.compile(tmpdir=dir,verbose=True)
def setup_module(mod): SRC = """ #include <string.h> #define FOOBAR (-42) static const int FOOBAZ = -43; #define BIGPOS 420000000000L #define BIGNEG -420000000000L int add42(int x) { return x + 42; } int add43(int x, ...) { return x; } int globalvar42 = 1234; const int globalconst42 = 4321; const char *const globalconsthello = "hello"; struct foo_s; typedef struct bar_s { int x; signed char a[]; } bar_t; enum foo_e { AA, BB, CC }; void init_test_re_python(void) { } /* windows hack */ void PyInit__test_re_python(void) { } /* windows hack */ """ tmpdir = udir.join('test_re_python') tmpdir.ensure(dir=1) c_file = tmpdir.join('_test_re_python.c') c_file.write(SRC) ext = ffiplatform.get_extension( str(c_file), '_test_re_python', export_symbols=['add42', 'add43', 'globalvar42', 'globalconst42', 'globalconsthello'] ) outputfilename = ffiplatform.compile(str(tmpdir), ext) mod.extmod = outputfilename mod.tmpdir = tmpdir # ffi = FFI() ffi.cdef(""" #define FOOBAR -42 static const int FOOBAZ = -43; #define BIGPOS 420000000000L #define BIGNEG -420000000000L int add42(int); int add43(int, ...); int globalvar42; const int globalconst42; const char *const globalconsthello = "hello"; int no_such_function(int); int no_such_globalvar; struct foo_s; typedef struct bar_s { int x; signed char a[]; } bar_t; enum foo_e { AA, BB, CC }; int strlen(const char *); """) ffi.set_source('re_python_pysrc', None) ffi.emit_python_code(str(tmpdir.join('re_python_pysrc.py'))) mod.original_ffi = ffi # sys.path.insert(0, str(tmpdir))
def test_struct_included(): baseffi = FFI() baseffi.cdef("struct foo_s { int x; };") baseffi.set_source('test_struct_included_base', None) # ffi = FFI() ffi.include(baseffi) target = udir.join('test_struct_included.py') make_py_source(ffi, 'test_struct_included', str(target)) assert target.read() == r"""# auto-generated file
def create_module(): hfiles = header_files() # remove ws.h due to https://github.com/nanomsg/nanomsg/issues/467 hfiles.pop('ws.h', None) ffi = FFI() ffi.cdef(functions(hfiles)) ffi.set_source('_nnpy', '\n'.join('#include <%s>' % fn for fn in hfiles), libraries=['nanomsg'], include_dirs=INCLUDE) return ffi
def build_ffi(): ffi = FFI() source = [] source.extend(raw_typedefs) source.extend(function_defs.values()) source.extend(enum_defs) ffi.set_source('sdl2._gl', '\n'.join(source)) ffi.cdef('\n'.join(typedefs.values())) ffi.cdef('\n'.join(function_defs.values())) ffi.cdef('\n'.join(enum_defs)) return ffi
def find_curses_library(): for curses_library in ['ncursesw', 'ncurses']: ffi = FFI() ffi.set_source("_curses_cffi_check", "", libraries=[curses_library]) try: ffi.compile() except VerificationError as e: e_last = e continue else: return curses_library # If none of the libraries is available, present the user a meaningful # error message raise e_last
def _mk_ffi(sources, name="_libsecp256k1", bundled=True, **kwargs): ffi = FFI() code = [] if "INCLUDE_DIR" in os.environ: kwargs["include_dirs"] = [absolute(os.environ["INCLUDE_DIR"])] if "LIB_DIR" in os.environ: kwargs["library_dirs"] = [absolute(os.environ["LIB_DIR"])] for source in sources: with open(source.h, "rt") as h: ffi.cdef(h.read()) code.append(source.include) if bundled: code.append("#define PY_USE_BUNDLED") ffi.set_source(name, "\n".join(code), **kwargs) return ffi
def create_module(): # Set defaults set_source_args = { 'include_dirs': DEFAULT_INCLUDE_DIRS } host_library = DEFAULT_HOST_LIBRARY # Read overrides for cross-compilation support from site.cfg if os.path.isfile(SITE_CFG): parser = cfgparser.ConfigParser() if parser.read(SITE_CFG): parsed_cfg = parser.defaults() for param in ['include_dirs', 'library_dirs']: if param in parsed_cfg: set_source_args[param] = parsed_cfg[param].split(',') if 'host_library' in parsed_cfg: host_library = parsed_cfg['host_library'] # Add some more directories from the environment if 'CPATH' in os.environ: cpaths = os.getenv('CPATH').split(os.pathsep) set_source_args['include_dirs'] += [os.path.join(p, 'nanomsg') for p in cpaths] hfiles = header_files(set_source_args['include_dirs']) # remove ws.h due to https://github.com/nanomsg/nanomsg/issues/467 hfiles.pop('ws.h', None) # Build FFI module and write out the constants ffi = FFI() ffi.cdef(DEFINITIONS) ffi.cdef(functions(hfiles)) ffi.set_source('_nnpy', '\n'.join('#include <%s>' % fn for fn in hfiles), libraries=['nanomsg'], **set_source_args) with open('nnpy/constants.py', 'w') as f: f.write(symbols(ffi, host_library)) return ffi
def load_ool_module(): """ Compile an out-of-line module, return the corresponding ffi and module objects. """ from cffi import FFI defs = """ double sin(double x); double cos(double x); void vsSin(int n, float* x, float* y); void vdSin(int n, double* x, double* y); int foo(int a, int b, int c); """ source = """ static int foo(int a, int b, int c) { return a + b * c; } void vsSin(int n, float* x, float* y) { int i; for (i=0; i<n; i++) y[i] = sin(x[i]); } void vdSin(int n, double* x, double* y) { int i; for (i=0; i<n; i++) y[i] = sin(x[i]); } """ ffi = FFI() ffi.set_source('cffi_usecases_ool', source) ffi.cdef(defs, override=True) tmpdir = static_temp_directory('test_cffi') ffi.compile(tmpdir=tmpdir) sys.path.append(tmpdir) try: import cffi_usecases_ool as mod cffi_support.register_module(mod) return mod.ffi, mod finally: sys.path.remove(tmpdir)
def maker(): """ Generate the bindings module. Invoked by cffi's setuptools integration. """ _cffi_src = os.path.dirname(__file__) ffibuilder = FFI() with open(os.path.join(_cffi_src, "set_source.h")) as set_source: ffibuilder.set_source( "posix_spawn._bindings", set_source.read()) with open(os.path.join(_cffi_src, "cdef.h")) as cdef: ffibuilder.cdef(cdef.read()) return ffibuilder
def build(**kwargs): """Build the C slitfunc library""" CWD = os.path.dirname(__file__) ffibuilder = FFI() with open(os.path.join(CWD, "slit_func_bd.h")) as f: ffibuilder.cdef(f.read(), override=True) with open(os.path.join(CWD, "slit_func_bd.c"), "r") as f: ffibuilder.set_source("clib._slitfunc_bd", f.read()) ffibuilder.compile(**kwargs) ffibuilder = FFI() with open(os.path.join(CWD, "slit_func_2d_xi_zeta_bd.h")) as f: ffibuilder.cdef(f.read(), override=True) with open(os.path.join(CWD, "slit_func_2d_xi_zeta_bd.c"), "r") as f: ffibuilder.set_source("clib._slitfunc_2d", f.read()) ffibuilder.compile(**kwargs)
def build(**kwargs): """Build the cluster C library""" ffibuilder = FFI() CWD = os.path.dirname(__file__) with open(os.path.join(CWD, "cluster.h")) as f: ffibuilder.cdef(f.read(), override=True) with open(os.path.join(CWD, "cluster.c"), "r") as f: ffibuilder.set_source( "clib._cluster", f.read(), # libraries=["c"], # sources=[os.path.join(CWD, "cluster.c")], # library_dirs=["."] # include_dirs=[os.path.join()] ) ffibuilder.compile(**kwargs)
def test_include(): ffi = FFI() ffi.cdef("#define ABC 123") ffi.set_source('test_include', None) target = udir.join('test_include.py') make_py_source(ffi, 'test_include', str(target)) assert target.read() == r"""# auto-generated file import _cffi_backend ffi = _cffi_backend.FFI('test_include', _version = 0x2601, _types = b'', _globals = (b'\xFF\xFF\xFF\x1FABC',123,), ) """ # ffi2 = FFI() ffi2.include(ffi) target2 = udir.join('test2_include.py') make_py_source(ffi2, 'test2_include', str(target2)) assert target2.read() == r"""# auto-generated file
def setup_class(cls): ffi = FFI() ffi.cdef(""" void native_gzipgzipgzip(void); """) source = """ #include "zlib.h" unsigned char input[100]; unsigned char output[100]; void native_gzipgzipgzip(void) { z_stream defstream; defstream.zalloc = Z_NULL; defstream.zfree = Z_NULL; defstream.opaque = Z_NULL; defstream.next_in = input; // input char array defstream.next_out = output; // output char array deflateInit(&defstream, Z_DEFAULT_COMPRESSION); int i = 0; while (i < 10000) { defstream.avail_in = 100; defstream.avail_out = 100; deflate(&defstream, Z_FINISH); i++; } deflateEnd(&defstream); } """ libs = [] if sys.platform.startswith('linux'): libs.append('z') # trick: compile with _CFFI_USE_EMBEDDING=1 which will not define Py_LIMITED_API ffi.set_source("vmprof.test._test_native_gzip", source, include_dirs=['src'], define_macros=[('_CFFI_USE_EMBEDDING',1),('_PY_TEST',1)], libraries=libs, extra_compile_args=['-Werror', '-g', '-O0']) ffi.compile(verbose=True) from vmprof.test import _test_native_gzip as clib cls.lib = clib.lib cls.ffi = clib.ffi
def _build_c_extension(): ffi = FFI() ffi.cdef(""" typedef int... off_t; #define PROT_READ ... #define PROT_WRITE ... #define PROT_EXEC ... #define PROT_NONE ... #define MAP_PRIVATE ... #define MAP_FIXED ... #define MAP_SHARED ... void mmap_init(off_t offset); uint16_t mmap_peek16(off_t offset); void mmap_poke16(off_t offset, uint16_t value); """) ffi.set_source("_cmmapwrapper", """ #include<sys/mman.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> volatile uint16_t *map = 0; void mmap_init(off_t offset){ int fd; fd = open("/dev/mem", O_RDWR|O_SYNC); map = mmap(0, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, fd, offset); } uint16_t mmap_peek16(off_t offset){ uint16_t n; n = map[offset/2]; return n; } void mmap_poke16(off_t offset, uint16_t value){ map[offset/2] = value; } """) ffi.compile(tmpdir='build')
def test_include_1(): sub_ffi = FFI() sub_ffi.cdef("static const int k2 = 121212;") sub_ffi.include(original_ffi) assert 'macro FOOBAR' in original_ffi._parser._declarations assert 'macro FOOBAZ' in original_ffi._parser._declarations sub_ffi.set_source('re_python_pysrc', None) sub_ffi.emit_python_code(str(tmpdir.join('_re_include_1.py'))) # if sys.version_info[:2] >= (3, 3): import importlib importlib.invalidate_caches() # issue 197 (but can't reproduce myself) # from _re_include_1 import ffi assert ffi.integer_const('FOOBAR') == -42 assert ffi.integer_const('FOOBAZ') == -43 assert ffi.integer_const('k2') == 121212 lib = ffi.dlopen(extmod) # <- a random unrelated library would be fine assert lib.FOOBAR == -42 assert lib.FOOBAZ == -43 assert lib.k2 == 121212 # p = ffi.new("bar_t *", [5, b"foobar"]) assert p.a[4] == ord('a')
int nvx_utf8vld_validate (void* utf8vld, const uint8_t* data, size_t length); void nvx_utf8vld_free (void* utf8vld); int nvx_utf8vld_set_impl(void* utf8vld, int impl); int nvx_utf8vld_get_impl(void* utf8vld); """) with open(os.path.join(os.path.dirname(__file__), '_utf8validator.c')) as fd: c_source = fd.read() ffi.set_source("_nvx_utf8validator", c_source, libraries=[], extra_compile_args=[ '-std=c99', '-Wall', '-Wno-strict-prototypes', '-O3', '-march=native' ]) class Utf8Validator: def __init__(self): self.ffi = ffi from _nvx_utf8validator import lib self.lib = lib self._vld = self.ffi.gc(self.lib.nvx_utf8vld_new(), self.lib.nvx_utf8vld_free) print(self.lib.nvx_utf8vld_get_impl(self._vld))
"""Build the _nvtx module.""" from cffi import FFI ffibuilder = FFI() ffibuilder.set_unicode(True) ffibuilder.set_source("._nvtx", "#include <nvtx3/nvToolsExt.h>\n", include_dirs=['/usr/local/cuda/include']) ffibuilder.cdef(r""" typedef ...* nvtxDomainHandle_t; typedef ...* nvtxStringHandle_t; #define NVTX_VERSION ... #define NVTX_EVENT_ATTRIB_STRUCT_SIZE ... typedef union { const char *ascii; const wchar_t *unicode; nvtxStringHandle_t registered; ...; } nvtxMessageValue_t; typedef enum { NVTX_COLOR_UNKNOWN, NVTX_COLOR_ARGB, ... } nvtxColorType_t; typedef enum { NVTX_MESSAGE_UNKNOWN, NVTX_MESSAGE_TYPE_ASCII,
from cffi import FFI ffibuilder = FFI() with open("lib/clips.c") as source_file: CLIPS_SOURCE = source_file.read() with open("lib/clips.cdef") as cdef_file: CLIPS_CDEF = cdef_file.read() ffibuilder.set_source("_clips", CLIPS_SOURCE, libraries=["clips"]) ffibuilder.cdef(CLIPS_CDEF) if __name__ == "__main__": ffibuilder.compile(verbose=True)
def build_quest_so(): lib_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'pyquest_cffi/questlib/') quest_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "QuEST/QuEST") if platform.system() == 'Darwin': questlib = os.path.join(lib_path, "libQuEST.dylib") else: questlib = os.path.join(lib_path, "libQuEST.so") include = [os.path.join(quest_path, "include")] _questlib = ctypes.CDLL(questlib) QuESTPrecFunc = _questlib['getQuEST_PREC'] QuESTPrecFunc.restype = ctypes.c_int QuESTPrec = QuESTPrecFunc() if QuESTPrec == 1: qreal = "float" elif QuESTPrec == 2: qreal = "double" elif QuESTPrec == 4: qreal = "longdouble" else: raise TypeError('Unable to determine precision of qreal') del (QuESTPrec) del (QuESTPrecFunc) with open(os.path.join(include[0], "QuEST.h"), "r") as f: lines = [line for line in f] lines += [ "void statevec_setAmps(Qureg qureg, long long int startInd," + " qreal* reals, qreal* imags, long long int numAmps);" ] lines += [ "qreal densmatr_calcProbOfOutcome(Qureg qureg, const int measureQubit, int outcome);" ] lines += [ "qreal statevec_calcProbOfOutcome(Qureg qureg, const int measureQubit, int outcome);" ] lines += [ "int generateMeasurementOutcome(qreal zeroProb, qreal *outcomeProb);" ] lines += ["int getQuEST_PREC(void);"] _lines = [] no_def = True skip = False for line in lines: if not line.find("getEnvironmentString") >= 0: if skip: if line.startswith('#endif'): skip = False elif line.startswith('#ifndef __cplusplus'): skip = True elif no_def and not line.startswith("#"): _lines.append(line) elif line.startswith("#ifdef"): no_def = False elif line.startswith("#endif"): no_def = True _lines = "".join(_lines).replace('qreal', qreal) ffibuilder = FFI() ffibuilder.cdef(_lines) ffibuilder.set_source( "_quest", r''' #include <QuEST.h> ''', libraries=["QuEST"], include_dirs=include, library_dirs=[lib_path], extra_link_args=['-Wl,-rpath,$ORIGIN'], # extra_link_args=['-Wl,-rpath={}'.format(lib_path)], ) ffibuilder.compile(verbose=True)
def generateIntermediateApi(): ffibuilder = FFI() ffibuilder.set_source("intermediateApi", r"""#include "open62541.h" #define UA_STATUSCODE_GOOD 0x00 #define UA_NS0ID_SERVER_SERVERSTATUS_CURRENTTIME 2258 #define UA_TYPES_COUNT 190 #define UA_TYPES_DATETIME 12 """, include_dirs=[dirname + r"/open62541/build"], library_dirs=[dirname + r"/open62541/build/bin"], libraries=['open62541']) ffibuilder.cdef(""" typedef struct UA_Client UA_Client; typedef uint32_t UA_StatusCode; typedef struct UA_ClientConfig UA_ClientConfig; UA_Client *UA_Client_new(void); UA_StatusCode UA_ClientConfig_setDefault(UA_ClientConfig *config); UA_ClientConfig *UA_Client_getConfig(UA_Client *client); UA_StatusCode UA_Client_connect(UA_Client *client, const char *endpointUrl); typedef uint16_t UA_UInt16; typedef uint32_t UA_UInt32; struct UA_DataType {...;}; typedef struct UA_DataType UA_DataType; const UA_DataType UA_TYPES[190]; #define UA_TYPES_DATETIME 12 typedef bool UA_Boolean; typedef int64_t UA_DateTime; typedef struct { void *data; /* Points to the scalar or array data */ ...;} UA_Variant; void UA_Variant_init(UA_Variant *p); UA_Boolean UA_Variant_hasScalarType(const UA_Variant *v, const UA_DataType *type); typedef struct {...;} UA_NodeId; UA_NodeId UA_NODEID_NUMERIC(UA_UInt16 nsIndex, UA_UInt32 identifier); UA_StatusCode UA_Client_readValueAttribute(UA_Client *client, const UA_NodeId nodeId, UA_Variant *outValue); typedef enum { UA_LOGCATEGORY_NETWORK = 0, UA_LOGCATEGORY_SECURECHANNEL, UA_LOGCATEGORY_SESSION, UA_LOGCATEGORY_SERVER, UA_LOGCATEGORY_CLIENT, UA_LOGCATEGORY_USERLAND, UA_LOGCATEGORY_SECURITYPOLICY } UA_LogCategory; typedef struct {...;} UA_Logger; typedef struct UA_DateTimeStruct { UA_UInt16 nanoSec; UA_UInt16 microSec; UA_UInt16 milliSec; UA_UInt16 sec; UA_UInt16 min; UA_UInt16 hour; UA_UInt16 day; /* From 1 to 31 */ UA_UInt16 month; /* From 1 to 12 */ UA_UInt16 year; } UA_DateTimeStruct; UA_Logger *UA_Log_Stdout; UA_DateTimeStruct UA_DateTime_toStruct(UA_DateTime t); #define UA_STATUSCODE_GOOD 0x00 #define UA_NS0ID_SERVER_SERVERSTATUS_CURRENTTIME 2258 void UA_LOG_INFO(const UA_Logger *logger, UA_LogCategory category, const char *msg, ...); """) os.system("mkdir build") os.chdir(dirname + r"/build") ffibuilder.compile(verbose=True) print("finished building intermediateApi")
import os from cffi import FFI siphash_source_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'siphash24.c') ffibuilder = FFI() ffibuilder.cdef( '''int siphash(const uint8_t *in, uint64_t inlen, const uint8_t *k, uint8_t *out, const size_t outlen);''' ) with open(siphash_source_file) as siphash_source: ffibuilder.set_source('csiphash._siphash', siphash_source.read()) if __name__ == '__main__': ffibuilder.compile(verbose=True)
from os import path from cffi import FFI ffibuilder = FFI() base_path = path.abspath(path.dirname(__file__)) header_path = path.join(base_path, 'vendor/binaryen-c.h') with open(header_path, 'r') as header_file: source = header_file.read() ffibuilder.set_source( '_binaryen_c', r""" #include <stddef.h> #include <stdint.h> {}""".format(source), libraries=['binaryen'], library_dirs=['vendor'], ) ffibuilder.cdef(source) if __name__ == '__main__': ffibuilder.compile(verbose=True)
from cffi import FFI ffi = FFI() ffi.cdef(""" int foo (int x); """) if __name__ == "__main__": ffi.set_source("_example", """ #include <x86intrin.h> const __m128i* ptr = 0; int foo (int x) { ptr += 1; return x + ((int) ptr); }; """, libraries=[]) ffi.compile()
#!/usr/bin/python from cffi import FFI ffibuilder = FFI() ffibuilder.set_source("fnfqueue._fnfqueue", """ #include "fnfqueue.h" """, sources=["src/fnfqueue.c"], extra_compile_args=["-O3"], include_dirs=["include"]) ffibuilder.cdef(""" #define NF_DROP ... #define NF_ACCEPT ... #define NF_STOLEN ... #define NF_QUEUE ... #define NF_REPEAT ... #define NF_STOP ... #define MANGLE_MARK ... #define MANGLE_PAYLOAD ... #define MANGLE_CT ... #define MANGLE_EXP ... #define MANGLE_VLAN ... #define NFQNL_COPY_NONE ... #define NFQNL_COPY_META ... #define NFQNL_COPY_PACKET ...
void free(void *ptr); """) ffi.set_source( '_regex2dfa', """ #include "%s" extern "C" { extern const char * cffi_regex2dfa(char *regex, uint32_t len) { const std::string input_regex = std::string(regex, len); std::string minimized_dfa; regex2dfa::Regex2Dfa(input_regex, &minimized_dfa); return strdup(minimized_dfa.c_str()); } } """ % regex2dfa_header, source_extension='.cpp', library_dirs=['.libs'], libraries=['regex2dfa'], extra_compile_args=[ '-O3', '-fstack-protector-all', '-D_FORTIFY_SOURCE', '-fPIC', ], ) if __name__ == '__main__': ffi.compile()
lines = [] src_lines = iter(headerfile_src) try: while True: line = next(src_lines).strip() if "deprecated" in line: while ";" not in line: line = next(src_lines).strip() else: lines.append(line) except StopIteration: pass headerfile = "\n".join(lines) ffi_c_source = """ #include <binaryen-c.h> """ else: headerfile = open(header_location, "rt").read() ffi_c_source = headerfile return headerfile, ffi_c_source headerfile, ffi_c_source = parse_header_file() ffibuilder = FFI() ffibuilder.cdef(headerfile) ffibuilder.set_source("_binaryen", ffi_c_source, libraries=['binaryen']) if __name__ == "__main__": ffibuilder.compile(verbose=True)
float *transition_probs, float *states, float *initial_values, int n_generators, int n_simulations, int n_transitions, int n_states, int random_seed, int simulate_streaks); """) # with open('psrmodels/_c/libtimedependence.h','r') as f: # ffibuilder.cdef(f.read()) header = "#include \"" + os.path.dirname( os.path.abspath(__file__)) + "/../c/libtimedependence.h\"" ffibuilder.set_source( "_c_ext_timedependence", # name of the output C extension # """ # #include "../../psrmodels/_c/libtimedependence.h" # """, header, sources=[ 'psrmodels/c/libtimedependence.c', 'psrmodels/c/mtwist-1.5/mtwist.c' ], libraries=['m']) # on Unix, link with the math library if __name__ == "__main__": ffibuilder.compile(verbose=True)
########## # FFI Build ########## _groove_source = r""" #include <groove/groove.h> #include <groove/queue.h> #include <groove/encoder.h> #include <groovefingerprinter/fingerprinter.h> #include <grooveloudness/loudness.h> #include <grooveplayer/player.h> """ # TODO: set these differently depending on platform/compiler libs = [ ':libgroove.so.4', ':libgroovefingerprinter.so.4', ':libgrooveloudness.so.4', ':libgrooveplayer.so.4', ] ffi_groove = FFI() ffi_groove.set_source('groove._groove', _groove_source, libraries=libs) ffi_groove.cdef(_groove_header) ffi_groove.cdef(_queue_header) ffi_groove.cdef(_encoder_header) ffi_groove.cdef(_fingerprinter_header) ffi_groove.cdef(_loudness_header) ffi_groove.cdef(_player_header) if __name__ == '__main__': ffi_groove.compile()
from cffi import FFI ffi = FFI() ffi.set_source( "pyhello", """ #include "hello.h" """, extra_objects=["../hello.so"], include_dirs=["../"], ) ffi.cdef(""" extern void Hello(); """) if __name__ == "__main__": ffi.compile(verbose=True) from pyhello.lib import Hello Hello()
def build_callback_fn(function_string, userdata_names=[]): ''' Builds a C callback function and returns a function pointer int. function_string : str This is a string of the C function to be compiled userdata_names : list or tuple This is an optional list to defince convenience names We compile and link and load the function, and return a function pointer. See `MjSim.set_substep_callback()` for an example use of these callbacks. The callback function should match the signature: void fun(const mjModel *m, mjData *d); Here's an example function_string: ``` """ #include <stdio.h> void fun(const mjModel* m, mjData* d) { printf("hello"); } """ ``` Input and output for the function pass through userdata in the data struct: ``` """ void fun(const mjModel* m, mjData* d) { d->userdata[0] += 1; } """ ``` `userdata_names` is expected to match the model where the callback is used. These can bet set on a model with: `model.set_userdata_names([...])` If `userdata_names` is supplied, convenience `#define`s are added for each. For example: `userdata_names = ['my_sum']` Will get gerenerated into the extra line: `#define my_sum d->userdata[0]` And prepended to the top of the function before compilation. Here's an example that takes advantage of this: ``` """ void fun(const mjModel* m, mjData* d) { for (int i = 0; i < m->nu; i++) { my_sum += d->ctrl[i]; } } """ ``` Note these are just C `#define`s and are limited in how they can be used. After compilation, the built library containing the function is loaded into memory and all of the files (including the library) are deleted. To retain these for debugging set the `MUJOCO_PY_DEBUG_FN_BUILDER` envvar. To save time compiling, these function pointers may be re-used by many different consumers. They are thread-safe and don't acquire the GIL. See the file `tests/test_substep.py` for additional examples, including an example which iterates over contacts to compute penetrations. ''' assert isinstance(userdata_names, (list, tuple)), \ 'invalid userdata_names: {}'.format(userdata_names) ffibuilder = FFI() ffibuilder.cdef('extern uintptr_t __fun;') name = '_fn_' + ''.join(choice(ascii_lowercase) for _ in range(15)) source_string = '#include <mujoco.h>\n' # Add defines for each userdata to make setting them easier for i, data_name in enumerate(userdata_names): source_string += '#define {} d->userdata[{}]\n'.format(data_name, i) source_string += function_string source_string += '\nuintptr_t __fun = (uintptr_t) fun;' # Link against mujoco so we can call mujoco functions from within callback ffibuilder.set_source(name, source_string, include_dirs=[join(mujoco_path, 'include')], library_dirs=[join(mujoco_path, 'bin')], libraries=['mujoco200']) # Catch compilation exceptions so we can cleanup partial files in that case try: library_path = ffibuilder.compile(verbose=True) except Exception as e: build_fn_cleanup(name) raise e # On Mac the MuJoCo library is linked strangely, so we have to fix it here if sys.platform == 'darwin': fixed_library_path = manually_link_libraries(mujoco_path, library_path) move(fixed_library_path, library_path) # Overwrite with fixed library module = load_dynamic_ext(name, library_path) # Now that the module is loaded into memory, we can actually delete it build_fn_cleanup(name) return module.lib.__fun
# file "simple_example_build.py" # Note: this particular example fails before version 1.0.2 # because it combines variadic function and ABI level. from cffi import FFI ffi = FFI() ffi.set_source("_simple_example", None) ffi.cdef(""" int printf(const char *format, ...); """) if __name__ == "__main__": ffi.compile()
'graph.h', 'index.h', 'merge.h', 'net.h', 'refspec.h', 'repository.h', 'revert.h', 'stash.h', 'submodule.h', 'callbacks.h', # Bridge from libgit2 to Python ] h_source = [] for h_file in h_files: h_file = os.path.join(dir_path, 'decl', h_file) with codecs.open(h_file, 'r', 'utf-8') as f: h_source.append(f.read()) C_HEADER_SRC = '\n'.join(h_source) # ffi _, libgit2_kw = get_libgit2_paths() ffi = FFI() ffi.set_source( "pygit2._libgit2", "#include <git2.h>", # preamble **libgit2_kw) ffi.cdef(C_HEADER_SRC) if __name__ == '__main__': ffi.compile()
sos_include_dir = "" sos_lib_dir = "" if len(sys.argv) > 1: sos_include_dir = sys.argv[1] sos_lib_dir = sys.argv[2] else: sos_build_dir = str(os.environ.get("SOS_BUILD_DIR")) sos_include_dir = str(sos_build_dir) + "/include" sos_lib_dir = str(sos_build_dir) + "/lib" ffibuilder.set_source("ssos_python", """ #include "ssos.h" #include "sosa.h" """, sources=["../ssos.c"], libraries=["sos"], library_dirs=[sos_lib_dir], include_dirs=[sos_include_dir]) #extra_compile_args=["-Wno-unused-variable"]) #extra_compile_args=["-Wno-unused-variable", "-DUSE_MUNGE=1"]) ffibuilder.cdef(""" typedef struct { void *sos_context; char *query_sql; uint64_t query_guid; double exec_duration;
# which depend on '_pypy_winbase_cffi' already. # # Note that if you need to regenerate _pypy_winbase_cffi and # can't use a preexisting PyPy to do that, then running this # file should work as long as 'subprocess' is not imported # by cffi. I had to hack in 'cffi._pycparser' to move an #'import subprocess' to the inside of a function. (Also, # CPython+CFFI should work as well.) # # This module supports both msvcrt.py and _subprocess.py. from cffi import FFI ffi = FFI() ffi.set_source("_pypy_winbase_cffi", None) # ---------- MSVCRT ---------- ffi.cdef(""" typedef unsigned short wint_t; int _open_osfhandle(intptr_t osfhandle, int flags); intptr_t _get_osfhandle(int fd); int _setmode(int fd, int mode); int _locking(int fd, int mode, long nbytes); int _kbhit(void); int _getch(void); wint_t _getwch(void); int _getche(void);
# -*- coding: utf-8 -*- from cffi import FFI try: system_types = open('inc/system_types.h', 'r').read() fuse_types = open('inc/fuse_types.h', 'r').read() except Exception: print('missing types headers!') else: ffibuilder = FFI() ffibuilder.set_source("_fuse", r""" #include <fuse3/fuse.h> """, libraries=['fuse3'], define_macros=[ ("FUSE_USE_VERSION", "32"), ], extra_compile_args=[], extra_link_args=[]) ffibuilder.cdef(system_types + fuse_types) if __name__ == '__main__': ffibuilder.compile(verbose=True)
import logging import struct from collections import defaultdict import os try: from cffi.backend_ctypes import long, unicode except ImportError: pass try: from ._ffi_moco_packet import ffi except ImportError: from cffi import FFI ffi = FFI() ffi.set_source("moco._ffi_moco_packet", None, libraries=[]) dpt_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), '../../embedded/firmware/communication/data_packet_types.h') with open(dpt_path, 'r') as dpt_file: ffi_data = dpt_file.readlines() ffi.cdef(''.join(ffi_data[7:-2])) import six from .util.datatypes import update, set_values, AttributeDict logger = logging.getLogger("Motive." + __name__) MAX_DATA_SIZE = 512 ffi = ffi PACKET_LEN = ffi.sizeof("GenericPacket")
import os from cffi import FFI ffibuilder = FFI() ffibuilder.set_source("grblas.backends.suitesparse._suitesparse_grblas", r"""#include "GraphBLAS.h" """, libraries=['graphblas']) thisdir = os.path.dirname(__file__) gb_cdef = open(os.path.join(thisdir, 'suitesparse_graphblas_3.1.1.h')) ffibuilder.cdef(gb_cdef.read()) if __name__ == '__main__': ffibuilder.compile(verbose=True)
# -*- coding: utf-8 -*- """ CFFI API for SecureTransport. """ from cffi import FFI ffibuilder = FFI() ffibuilder.set_source( "_securetransport", """ #include <stdlib.h> #include <Security/SecCertificate.h> #include <Security/SecTrust.h> #include <Security/SecureTransport.h> """, extra_link_args=['-framework', 'Security', '-framework', 'CoreFoundation'], ) ffibuilder.cdef(""" typedef bool Boolean; typedef uint8_t UInt8; typedef uint32_t UInt32; typedef signed long OSStatus; typedef signed long long CFIndex; typedef ... *CFArrayRef; typedef ... *CFDataRef; typedef ... *CFAllocatorRef; typedef ... *SSLContextRef; typedef ... *SecCertificateRef; typedef ... *SecTrustRef;
def setup_module(mod): SRC = """ #include <string.h> #define FOOBAR (-42) static const int FOOBAZ = -43; #define BIGPOS 420000000000L #define BIGNEG -420000000000L int add42(int x) { return x + 42; } int add43(int x, ...) { return x; } int globalvar42 = 1234; const int globalconst42 = 4321; const char *const globalconsthello = "hello"; struct foo_s; typedef struct bar_s { int x; signed char a[]; } bar_t; enum foo_e { AA, BB, CC }; void init_test_re_python(void) { } /* windows hack */ void PyInit__test_re_python(void) { } /* windows hack */ """ tmpdir = udir.join('test_re_python') tmpdir.ensure(dir=1) c_file = tmpdir.join('_test_re_python.c') c_file.write(SRC) ext = ffiplatform.get_extension(str(c_file), '_test_re_python', export_symbols=[ 'add42', 'add43', 'globalvar42', 'globalconst42', 'globalconsthello' ]) outputfilename = ffiplatform.compile(str(tmpdir), ext) # test with a non-ascii char ofn, oext = os.path.splitext(outputfilename) if sys.platform == "win32": unicode_name = ofn + (u + '\u03be') + oext else: unicode_name = ofn + (u + '\xe9') + oext try: unicode_name.encode(sys.getfilesystemencoding()) except UnicodeEncodeError: unicode_name = None if unicode_name is not None: print(repr(outputfilename) + ' ==> ' + repr(unicode_name)) os.rename(outputfilename, unicode_name) outputfilename = unicode_name mod.extmod = outputfilename mod.tmpdir = tmpdir # ffi = FFI() ffi.cdef(""" #define FOOBAR -42 static const int FOOBAZ = -43; #define BIGPOS 420000000000L #define BIGNEG -420000000000L int add42(int); int add43(int, ...); int globalvar42; const int globalconst42; const char *const globalconsthello = "hello"; int no_such_function(int); int no_such_globalvar; struct foo_s; typedef struct bar_s { int x; signed char a[]; } bar_t; enum foo_e { AA, BB, CC }; int strlen(const char *); struct with_union { union { int a; char b; }; }; union with_struct { struct { int a; char b; }; }; struct NVGcolor { union { float rgba[4]; struct { float r,g,b,a; }; }; }; """) ffi.set_source('re_python_pysrc', None) ffi.emit_python_code(str(tmpdir.join('re_python_pysrc.py'))) mod.original_ffi = ffi # sys.path.insert(0, str(tmpdir))
int Tcl_GetBignumFromObj(Tcl_Interp *interp, Tcl_Obj *obj, mp_int *value); Tcl_Obj *Tcl_NewBignumObj(mp_int *value); int mp_unsigned_bin_size(mp_int *a); int mp_to_unsigned_bin_n(mp_int * a, unsigned char *b, unsigned long *outlen); int mp_read_radix(mp_int *a, const char *str, int radix); int mp_init(mp_int *a); void mp_clear(mp_int *a); """) tkffi.set_source("_tkinter.tklib_cffi", """ #define HAVE_LIBTOMMATH %(HAVE_LIBTOMMATH)s #define HAVE_WIDE_INT_TYPE %(HAVE_WIDE_INT_TYPE)s #include <tcl.h> #include <tk.h> #if HAVE_LIBTOMMATH #include <tclTomMath.h> #endif char *get_tk_version(void) { return TK_VERSION; } char *get_tcl_version(void) { return TCL_VERSION; } """ % globals(), include_dirs=incdirs, libraries=linklibs, library_dirs = libdirs ) if __name__ == "__main__": tkffi.compile(os.path.join(os.path.dirname(sys.argv[0]), '..'))
for l in cpropep_libs: prefix = 'pypropep/cpropep/' + l + '/src/' src_files += glob(prefix + '*.c') for ef in exclude_c_files: if (prefix + ef) in src_files: print('Excluding {} from source list'.format(prefix+ef)) src_files.remove(prefix + ef) inc_files = '' for i in inc_dir: files = glob(i + '/*.h') for f in files: inc_files += '#include "%s"\n' % (os.path.basename(f)) ffibuilder.set_source("pypropep.cpropep._cpropep", inc_files, sources=src_files, include_dirs=inc_dir) # TODO:Find a way to scrape #defines from headers rather than hard coding const ffibuilder.cdef(""" //**** libcpropep/type.h ****// typedef enum { GAS, CONDENSED, STATE_LAST, ... } state_t; typedef enum {
int count; float threshold; ccv_bbf_feature_t* feature; float* alpha; } ccv_bbf_stage_classifier_t; typedef struct { int count; ccv_size_t size; ccv_bbf_stage_classifier_t* stage_classifier; } ccv_bbf_classifier_cascade_t; ccv_bbf_classifier_cascade_t* ccv_bbf_read_classifier_cascade(const char*); ccv_array_t* ccv_bbf_detect_objects( ccv_dense_matrix_t*, ccv_bbf_classifier_cascade_t**, int, ccv_bbf_param_t); void ccv_bbf_classifier_cascade_free(ccv_bbf_classifier_cascade_t* cascade); extern ccv_bbf_param_t ccv_bbf_default_params; """) ffi.set_source('_ccv', '#include <ccv.h>', include_dirs=[os.getenv('INCDIR') or '.'], library_dirs=[os.getenv('LIBDIR') or '.'], libraries=['ccv']) if __name__ == "__main__": res = ffi.compile() print res
from cffi import FFI ffibuilder = FFI() _path = os.path.dirname(__file__) sourcefile = os.path.join(_path, 'seclink.cc') with open(sourcefile, 'r') as f: source = f.read() ffibuilder.set_source( "_libseclink", source, source_extension='.cc', extra_compile_args=['-Wall', '-Wextra', '-std=gnu++17', '-O3'], include_dirs=["./", "_cffi_build/"], libraries=['seal'], sources=[ '_cffi_build/encrypt.cc', '_cffi_build/decrypt.cc', '_cffi_build/multiply.cc', '_cffi_build/secure-linkage.cc' ]) ffibuilder.cdef(""" typedef struct seclink_ctx *seclink_ctx_t; void seclink_init_ctx(seclink_ctx_t *ctx, size_t polmod_deg, uint64_t plain_mod, uint64_t prng_seed[2]); void seclink_clear_ctx(seclink_ctx_t ctx);
import sys import os.path import setuptools # Fix distutils issues from cffi import FFI ffi = FFI() mod_name = 'instrumental.drivers.cameras._pixelfly.errortext' if sys.platform.startswith('win'): ffi.set_source(mod_name, """ #define PCO_ERR_H_CREATE_OBJECT #define PCO_ERRT_H_CREATE_OBJECT #include <windows.h> #include "PCO_errt.h" """, include_dirs=[os.path.dirname(__file__)]) ffi.cdef("void PCO_GetErrorText(DWORD dwerr, char* pbuf, DWORD dwlen);") else: ffi.set_source(mod_name, '') if __name__ == '__main__': ffi.compile()
# file "testCFFI_build.py" # Note: this particular example fails before version 1.0.2 # because it combines variadic function and ABI level. from cffi import FFI ffi = FFI() ffi.set_source("_testCFFI", None) ffi.cdef(""" void printHello(); void printMessage(char *myMessage); double sumVector(int size, double* vec); """) if __name__ == "__main__": ffi.compile()
from cffi import FFI ffi = FFI() ffi.cdef(""" typedef ... Display; typedef struct { ...; } Window; typedef struct { int type; ...; } XEvent; Display *XOpenDisplay(char *display_name); Window DefaultRootWindow(Display *display); int XMapRaised(Display *display, Window w); Window XCreateSimpleWindow(Display *display, Window parent, int x, int y, unsigned int width, unsigned int height, unsigned int border_width, unsigned long border, unsigned long background); int XNextEvent(Display *display, XEvent *event_return); """) ffi.set_source('_xclient_cffi', """ #include <X11/Xlib.h> """, libraries=['X11']) if __name__ == '__main__': ffi.compile(verbose=True)
#include <stdlib.h> #define FNV1A_32_OFFSET 2166136261UL #define FNV1A_32_PRIME 16777619 /** * 32-bits unsigned FNV1a returning into hash, using p to as variable to * walk over metric up to firstspace */ #define fnv1a_32(hash, p, metric, firstspace) \ hash = FNV1A_32_OFFSET; \ for (p = metric; p < firstspace; p++) \ hash = (hash ^ (unsigned int)*p) * FNV1A_32_PRIME; static unsigned short fnv1a_hashpos(const char *key, int len) { unsigned int hash; const char *end = key + len; fnv1a_32(hash, key, key, end); return (unsigned short)((hash >> 16) ^ (hash & (unsigned int)0xFFFF)); } ''' ffi.set_source("_fnv1a", header+src) ffi.cdef(header) ffi.compile() from _fnv1a import ffi lib = ffi.dlopen(None) fnv1a_hashpos = lib.fnv1a_hashpos if __name__ == "__main__": print fnv1a_hashpos('test', 4)
void *src, int srclen, void *dst ); int hypua_decoder_decode_ucs4( void *decoder, void *src, int srclen, void *dst ); int hypua_decoder_decode_flush_ucs2(void *decoder, void *dst); int hypua_decoder_decode_flush_ucs4(void *decoder, void *dst); ''' # noqa ) if sys.platform == 'win32': library = 'build/hypua2jamo-c/HanyangPUA.lib' else: library = 'build/hypua2jamo-c/libHanyangPUA.a' ffi.set_source( 'hypua2jamo._cffi', '', extra_objects=[ library, ], )
ffi.cdef("int ldns_ok(struct ldns_info *ldi);") ffi.cdef("uint16_t get_short(uint8_t *bp, uint16_t x);") ffi.set_source("cpldns", # .so to be created """ // passed to the real C compiler #include <ldns/ldns.h> struct ldns_info { struct ldns_struct_pkt *ldpkt; /* ldns_pkt typedef in ldns/packet.h */ int status; /* enum in ldns */ }; int get_ldns_info(struct ldns_info *ldi, uint8_t *dns_msg, int dns_len) { ldi->status = ldns_wire2pkt(&ldi->ldpkt, dns_msg, dns_len); return ldi->ldpkt != NULL; /* True if all's well */ } int ldns_ok(struct ldns_info *ldi) { return ldi->status == LDNS_STATUS_OK; } uint16_t get_short(uint8_t *bp, uint16_t x) { uint16_t v = *(uint16_t *)&bp[x]; return ntohs(v); } """, libraries=["ldns", "c"]) # list of libraries to link with ffi.cdef( """ struct ldns_info {
from cffi import FFI ffi = FFI() ffi.cdef(""" typedef ... Display; typedef struct { ...; } Window; typedef struct { int type; ...; } XEvent; Display *XOpenDisplay(char *display_name); Window DefaultRootWindow(Display *display); int XMapRaised(Display *display, Window w); Window XCreateSimpleWindow(Display *display, Window parent, int x, int y, unsigned int width, unsigned int height, unsigned int border_width, unsigned long border, unsigned long background); int XNextEvent(Display *display, XEvent *event_return); """) ffi.set_source('_xclient_cffi', """ #include <X11/Xlib.h> """, libraries=['X11']) if __name__ == '__main__': ffi.compile()
from cffi import FFI ffibuilder = FFI() source = """ typedef unsigned char MP_U8; typedef unsigned int MP_U32; int lzmat_encode(MP_U8 *pbOut, MP_U32 *pcbOut, MP_U8 *pbIn, MP_U32 cbIn); int lzmat_decode(MP_U8 *pbOut, MP_U32 *pcbOut, MP_U8 *pbIn, MP_U32 cbIn); """ ffibuilder.set_source( "_pylzmat", # name of the output C extension """#include "lzmat.h" """, sources=['src/lzmat/lzmat_enc.c', 'src/lzmat/lzmat_dec.c'], # includes pi.c as additional sources include_dirs=['src/lzmat'] ) # ffibuilder.cdef("int lzmat_encode(char *pbOut, int *pcbOut, char *pbIn, int cbIn);") # ffibuilder.cdef("int lzmat_decode(char *pbOut, int *pcbOut, char *pbIn, int cbIn);") ffibuilder.cdef(source) if __name__ == "__main__": ffibuilder.compile(verbose=True)
'repository.h', 'revert.h', 'stash.h', 'submodule.h', ] h_source = [] for h_file in h_files: h_file = os.path.join(dir_path, 'decl', h_file) with codecs.open(h_file, 'r', 'utf-8') as f: h_source.append(f.read()) C_HEADER_SRC = '\n'.join(h_source) # Preamble preamble = "#include <git2.h>" # C_KEYWORDS libgit2_bin, libgit2_include, libgit2_lib = get_libgit2_paths() C_KEYWORDS = dict(libraries=['git2'], library_dirs=[libgit2_lib], include_dirs=[libgit2_include]) # ffi ffi = FFI() ffi.set_source("pygit2._libgit2", preamble, **C_KEYWORDS) ffi.cdef(C_HEADER_SRC) if __name__ == '__main__': ffi.compile()
def build_ffi(module_name, cdef_source, verify_source, libraries=[], extra_compile_args=[], extra_link_args=[]): ffi = FFI() ffi.cdef(cdef_source) ffi.set_source( module_name, verify_source, libraries=libraries, extra_compile_args=extra_compile_args, extra_link_args=extra_link_args, ) return ffi