C header → Object Pascal binding generator. Reads a .h file via
libclang and emits external function prototypes, record layouts,
enums, and #define constants in one of three dialects: Free Pascal
(FPC), Blaise, or RapidQ-ll BASIC.
Not a C compiler. Not a hand-port replacement. Just a focused tool
that turns a header into a uses-able Pascal unit (or a flat .bas
file for rqbasic) so you can link against the underlying C library
without writing externs by hand.
# Build
pasbuild
# Generate (clang flags after `--`)
./target/pascal_bindgen --fpc \
--header /usr/include/gtk-4.0/gtk/gtk.h \
--output gtk4_fpc.pas \
--unit-name gtk4_fpc \
--library libgtk-4 \
-- $(pkg-config --cflags gtk4)
# Use
echo "uses gtk4_fpc;" > app.pas # ...write your program...
fpc app.pasEnd-to-end walkthrough with a working demo: docs/example_gtk4.adoc.
Pass --target SYMBOL:TRIPLE (repeatable) to parse the header for
multiple clang targets in a single run. Decls that differ across
targets emit inside {$IFDEF SYMBOL} guards; identical decls stay
unguarded.
./target/pascal_bindgen --fpc --header foo.h --output foo.pas \
--target UNIX:x86_64-pc-linux-gnu \
--target WINDOWS:x86_64-w64-mingw32 \
--target-args 'WINDOWS=-isystem /usr/x86_64-w64-mingw32/include'Single-target (or no --target) runs are byte-identical to the
legacy output. See docs/overview.adoc for caveats around Win32 vs
Win64 and calling-convention handling.
Pick one with a flag:
--fpc-
Free Pascal / Delphi-mode.
{$mode objfpc}{$H+},{$PACKRECORDS C},uses ctypes,cdecl;modifier,external 'libfoo';directive. --blaise-
Blaise compiler dialect. No
{$mode}/{$PACKRECORDS}, noctypes,external name '…'syntax. --rqbasic-
RapidQ-ll BASIC (
.bas). FlatTYPE/CONST/DECLAREstatements; no unit wrapper.
The parser and IR are dialect-neutral; only the emitters differ. See docs/cli.adoc for the full flag list and docs/overview.adoc for the architecture.
.h file(s)
|
v libclang via FFI shim
+-----------------+
| parser |
+-----------------+
|
v
+-----------------+
| binding IR | dialect-neutral
+-----------------+
|
+-- emit --> .pas (--fpc)
+-- emit --> .pas (--blaise)
+-- emit --> .bas (--rqbasic)The FFI shim (src/main/c/libclang_shim.c) wraps libclang’s
by-value CXCursor / CXString / CXType surface behind opaque
pointers so a Pascal frontend without full SysV ABI support can
still talk to libclang. Required for Blaise; FPC could in principle
go direct but uses the same shim for parity.
In scope:
-
externfunction declarations, including varargs -
typedefaliases (resolved to underlying type when possible) -
struct/unionlayouts -
enumconstants -
#definesimple value macros (integer / string literals) -
Pointer, array, function-pointer parameter types
-
Calling conventions (cdecl by default, stdcall / fastcall where annotated)
-
Bit-fields (best effort, comment when not representable)
Out of scope (v1):
-
Function-like macros with bodies (
#define ADD(a,b) a)+(b) -
C++ headers (overloads, templates, namespaces, references)
-
Inline function bodies — declared, body dropped
-
_Generic,attribute…-driven semantic changes
The examples/ tree has generated bindings + demo programs for:
-
GTK 4 (FPC, Blaise, rqbasic)
-
SDL 2 (rqbasic)
-
Raylib (rqbasic, including a two-player Pong demo)
-
Vulkan (FPC, Blaise)
-
OpenGL / EGL (FPC, rqbasic)
-
SQLite (FPC, Blaise, rqbasic)
-
zlib (FPC, Blaise)
-
Win32 (Blaise)
Each example folder contains a build*.sh script. examples/build_all_rqbasic.sh
smoke-builds the rqbasic set.
-
Free Pascal 3.3.1+ (or compatible) for the build itself.
-
pasbuildto drive compilation. -
libclang 17 dev package + headers (Debian:
libclang-17-dev). The FFI shim is linked against libclang at build time. -
For the examples: whatever headers the target wraps (
libgtk-4-dev,libvulkan-dev, etc.).
-
overview — what the tool is and isn’t.
-
cli — every flag, exit codes.
-
example_gtk4 — end-to-end walkthrough.
-
blaise_compat — Blaise-vs-FPC quirks hit while dual-building this tool.
-
comments — what the emitters write into output beyond the bare declarations.
BSD-3-Clause. See LICENSE.
Generated bindings under examples/ are derivative of their upstream
headers (GTK, Vulkan, SQLite, zlib, OpenGL/EGL, Win32 SDK, …) and
inherit those projects' licenses; they are excluded from this
project’s BSD-3 copyright via resources/copyright_blacklist.txt.