package lintcstubs-arity
Install
Dune Dependency
Authors
Maintainers
Sources
sha256=39a8e357ecc08fced6e9020edb0526e57999a0bf833700d6d9f759b85792c49b
sha512=0a509a862916f541692aed9569dc212b7fcf1c5d1eb08a01d77007c3d211b4e5dcba9f5ddd86689b16149c3799d185d885d768c08e21c1ab153b8831909f6edf
README.md.html
README.md
Lintcstubs_arity — check consistency between OCaml primitive declarations and implementation
These are a suite of tools and libraries for finding mismatches between the number of arguments declared in an .ml
file for a C primitive and its implementation in the corresponding .c
file.
lintcstubs_arity
is a tool that generates a C header file from an OCaml.ml
file that contains anexternal
declaration and works on OCaml 4.08+.lintcstubs_arity_cmt
generates the header file from a.cmt
file instead and works on OCaml 4.10+.lintcstubs-arity.primitives_of_cmt
is an OCaml library that can be used to iterate over all primitive declarations in a.cmt
file and works on OCaml 4.10+.
Their only dependency is compiler-libs
which is shipped with the compiler distribution.
Installation
Using opam
opam install lintcstubs-arity
Minimal
If you do not use opam
or dune
it is still possible to use this tool, see example/minimal for details.
Why?
If the number or type of arguments doesn't match between the declaration in the .ml
file or its implementation in .c
then this can result in undefined behaviour at runtime. Neither the C or OCaml compiler is aware of the requirements of the other module, and the linker only checks the presence of the symbol
, but not its type. By generating a .h
file such mismatches can be detected at build time by the C compiler.
The paper contains concrete examples of how such mismatches can occur in practice as software evolves.
Usage:
Consult the official manual on how to implement C primitives correctly.
On OCaml 4.10+
lintcstubs_arity_cmt ocamlfile.cmt >primitives.h
The generated primitives.h
can be included at the top of the .c
file implementing the OCaml primitives.
ocamlfile.cmt
is a -bin-annot
file for ocamlfile.ml
. Your build system should've produced one, check that it is using the -bin-annot
flag if not. You can also create one manually (add include and ocamlfind
flags as necessary):
ocamlc -bin-annot -c ocamlfile.ml
For more details see the build-system integration examples:
You can also commit the generated file to source control, thus requiring the tool to be present only when changing the .ml
file (or in a CI). This can be useful when the OCaml module is part of a larger system predominantly written in another language.
This is the recommended version of the tool if you meet the OCaml version requirements and can integrate header generation into the package's build system. The generated header contains both byte-code and native-code prototypes, and supports unboxed annotations.
On OCaml 4.08+ (bytecode only)
lintcstubs_arity ocamlfile.ml >primitives.h
ocamlfile.ml
is an OCaml file that declares a C primitive as defined in the manual.
After primitives.h
is generated, you can include it in the .c
files that implement the OCaml primitives defined in ocamlfile.ml
.
This can help detect simple mismatches between the number of arguments declared in the .ml
file and implemented in the .c
file.
This version of the tool doesn't support unboxed arguments, and therefore it doesn't generate prototypes for native code versions of the stubs. It only requires a source file and doesn't require setting up build paths or integrating into a build system, it is suitable to use on an unpacked source tarball directly.
How it works
This is part of a suite of static analysis tools for C stubs described in a paper submitted to the ICFP 2023 OCaml workshop.
If there is interest, its integration could be proposed into a future version of the compiler.
Design principles
All of these tools adhere to these principles:
No external dependencies (
compiler-libs
is available by default) to make it easy to reuse in other build systemsOptional dependencies for ecosystem integration (e.g.,
dune
, ormake
)Use the minimum version of Dune that has the features we require (e.g.,
cram
tests)Both of these tools rely on unstable compiler APIs. They use just the minimum information from the Parse- and Typed-trees to ensure the tool works on a wide range of OCaml compiler versions (and is easy to adapt if it breaks). Shape-analysis is out-of-scope.
Contains Cram tests to check for correct behaviour.