A command line tool and library for creating Common Lisp language bindings from C header files.
Features:
- Generates CFFI bindings for function declarations, enums, variables, unions, and structures.
- Handles nested and anonymous structures, unions, and enums. (See #15)
- Warns when it cannot produce a correct binding.
- Documentation comments from the C source files are lispified and included with the generated bindings when available.
- Provides a powerful way to customize how names are translated into lisp symbols.
cl-bindgen requires libclang, which is not installed with the other Python
dependencies and not available on PyPi. It is recommended to install it first before installing
cl-bindgen. Use your distribution's package manager to install it.
Once libclang is installed, you can then install cl-bindgen from
source or from PyPI.
From PyPI:
pip install cl-bindgenFrom source:
git clone --depth=1 https://github.com/sdilts/cl-bindgen
cd cl-bindgen
pip install --user .To process individual files, use the f command and specify one or
more files to process. By default, output will be printed to
stdout, but the output file can be specified with the -o option. To see
a full list of options, run cl-bindgen f -h.
# Process test.h and print the results to stdout:
cl-bindgen f test.h
# Process the files test1.h, test2.h, and place the output in output.lisp:
cl-bindgen f -o output.lisp test1.h test2.hcl-bindgen can use a yaml file to process many header
files with a single invocation. Use the b command
to specify one or more batch files to process:
cl-bindgen b my_library.yamlBatch files use the YAML format. Multiple documents can be contained in each input file.
Required Fields:
output: where to place the generated codefiles: a list of files to process
Optional Fields:
package: The name of the Common Lisp package of the generated filearguments: Arguments to pass to clangforce: Ignore errors while parsing. Valid values areTrueorFalsepkg-config: A list of package names needed by the library. Adds the flags needed to compile the given header files as told bypkg-config --cflagspointer-expansion(experimental): Used to provide either a regex or a list of pointer types to expand or not expand in the output.make-inline(experimental): Used to provide either a regex or a list of names matching functions that should be declaredinline. Uses the same yml keys asponter-expansion.
To see example batch files, look in the examples directory.
If you need to specify additional command line arguments to the clang
processor, you can use the -a option, and list any clang arguments after.
cl-bindgen b batch_file.yaml -a -I include_dir1 -I include_dir2
# Use -- to stop collecting clang arguments:
# Note that instead of directly calling pkg-config when using a batch
# file, you can use the pkg-config option instead.
cl-bindgen f -a `pkg-config --cflags mylibrary` -- header.hIf a header file isn't found while processing the input files,
cl-bindgen will halt and produce no output. This is to avoid producing
incorrect bindings: while bindings can still be produced when header
files are missing, they are likely to be incorrect. To ignore missing
header files and other fatal errors, the -f flag can be used:
cl-bindgen b -f batch_file.yaml
cl-bindgen f -f header.ccl-bindgen attempts to provide a reasonable interface that is usable in most cases. However, if you need to customize how C names are converted into lisp names or embed cl-bindgen into another application, cl-bindgen is available as a library.
The cl_bindgen package is broken up into modules: the processfile,
mangler, util and macro_util modules. The processfile module provides the
functions to generate the lisp bindings, the mangler module provides
functions to convert C names into lisp names, and the util module
provides functions to use batch files and cl-bingen's command line
interface.
This module exports two functions: process_file and process_files,
which work on a single header file or many, respectively. Both
functions take two arguments: the file(s) to be processed and an
ProcessOptions object.
The ProcessOptionsclass is the way to specify how the
processing functions generate their output. It has the following
fields:
typedef_mangers,enum_manglers,type_manglers,name_manglersandconstant_manglers: See the mangler module section for what these do.output: The path of the file where the output is placed.":stdout"or":stderr"can be specified to use standard out or standard error.package: If notNone, this specifies the package the generated output should be placed in.arguments: The command line arguments that should be given to the clang processor.force: If true, then ignore errors while parsing the input files.macro_detector: The macro detctor function used to detect header macrosexpand_pointer_p: A function that takes a typename and returns whether or not pointers of this type should be fully expanded or left as:pointer.
cl-bindgen uses a set of classes called manglers to translate C
names so that they follow lisp naming conventions. Each mangler class
provides one or more transformations to a symbol. For example, the
UnderscoreMangler class converts underscores (_) into dashes
(-). A series of manglers are applied to each C name to make it
follow lisp naming conventions.
To maximize customization, a list of manglers is associated with each type of name that can be converted. enums, variable names, typedefs, constants, and record types all use a different set of manglers.
Built-in manglers:
UnderscoreMangler: Converts underscores to dashes.ConstantMangler: Converts a string to follow Common Lisp's constant style recomendation.KeywordMangler: Adds a:to the beginning of a string to make it a symbol. Doesn't perform any action if the string has a package prefix.RegexSubMangler: Substitutes the substring matched by a regex with the given string.CamelCaseConverter: Convert TitleCase and camelCase strings to lisp-case strings that are all lower case.
Mangler classes follow a simple interface:
can_mangle(string): returns true if the mangler can perform its operations on the given stringmangle(string): returns a string with the desired transformations applied.
The util module provides functions for using batch files and
composing objects together, processing arguments, etc.
process_batch_file(batch_file, options): Processes the given batch file usingoptionsas the default options.dispatch_from_arguments(arguments, options): Uses the provided command line arguments to perform the actions of cl-bindgen usingoptionsas the default options.find_clang_resource_dir(): This is needed if you build your ownProcessOptionsobject and do not use thedispatch_from_argumentsfunction. The path returned by this function needs to be appended to the clang arguments in order for the script to find built-in headers. See theadd_clang_dirfunction in this module.
This module provides the macro_matches_file_path function that is used
by default to check if a macro is a header guard, and the
convert_literal_token that converts literal tokens into CL literals.
The macro_matches_file_path is a macro detector function. Macro
detector functions are used to determine if a C macro is a header
guard. They take two arguments: the location of the file and the name
of the file as a string.
The best example of how to use cl-bindgen as a library is to look at its main
function found in
cl_bindgen/__main__.py
and the
cl_bindgen/util.py
file, specifically the build_default_options function.