-
Notifications
You must be signed in to change notification settings - Fork 0
Frama‐C module implementation
This Wiki is made in order to discuss the way to integrate a Frama-C modulle into meson, and how to define the exported API (function signatures and logic) to meson users
Module conception model, question to solve:
Module integration:
- Do we consider the module as a test() derivative ? (i.e. triggered by
meson test
? - Do we support specific meson target (i.e. new
meson proof
target) ? - Do we define the module API as generic targets, that can be a dependency of any others (like
custom_target()
meaning that the user is free to describe dependencies in other targets such astest()
but also other ones.
The third solution seems better as it is less intrusive into meson core, and leave the integration model into projects to project's developers.
Module import is a standard meson mechanism:
framac = import('framac')
API signature definition. Required fields are prefixed by *
Frama-C execution configuration API
parsing signature:
void parse(
*str: name, # unique identifier
*input: list(files|source_set|build_tgt) # source to parse (list of sources, being a configured source set, files or files list
# supporting generated sources is clearly a requirements (through, for e.g. build_tgt)
*entrypoint: str, # entrypoint from which the kernel start analysis
timeout: int # analysis timeout (default 300 ?)
machdep: str # str is not strict enough... default to x86_32 ?
cpp_extra_flags: list(str), # extra CPP cflags if needed, should be, most of the time, useless
depends: list(build_dep) # target dependencies if required (source generation, etc.)
)
To note: the input would probably be only a build-target, at least to start with, because:
- in a given repository, multiple build target exists
- given a repo, we may which to parse:
- sources associated to a given executable() (being the executable build target)
- sources associated to a given library()
This is logic to require to analyse a build target, as associated to it, all derivative dependencies being reachable through the meson internals. In that case, this is normal to consider that:
- considering a target (executable or library, this information being useful as it impacts the frama-c options)
- getting the overall sources (known by meson)
- considering the associated API (for libraries, being defined in the library infos, through include_directory field
We can:
- use a given entrypoint (may be manually written)
- reduce WP analysis to the API functions (setting the
-wp-fct
flag) when being a library
For example, considering the following library:
my_lib = static_library(
'mylib',
sources: [
mylib_set_config.sources(),
mylib_header_set_config.sources(),
],
include_directories: mylib_inc,
c_args: [ target_arch_args, global_build_args ],
install: false,
dependencies: [ mylib_source_set_config.dependencies(), external_deps],
)
the sources and include directories are useful for Frama-C, while some others can also be acceded through the meson internal informations used to generate the build_command.json file. As a consequence, the build_command.json is no more needed as the frama-c plugin has access to the meson current context.
We then can imagine:
framac = import('frama-c')
enrypoint = files('mylib_eva_main.c')
framac.parse(
'frama-c-mylib-parse',
input: my_lib,
entrypoint: entrypoint,
timeout: 300,
machdep: 'x86_32.gcc'
)
If a part of the sources have dependencies in order to be generated, this can be, probably, naturally handled by meson, as the lib being an input of the function, all its own dependencies would be resolved and build for those for which it is required.
the session output dir can easily be forged in the same way meson targets do: using, in the above case, a frama-c-arch-eva.session.p
, for example, in the build directory in a similar path to the source directory (meson keeping homogeneous hierarchy between source and build directories).
There are two ways, it seems, to interact with Frama-C:
- detect the Frama-C binary (in the way
find_program()
meson function does) and use it directly through python - using the Frama-C server associated to Ivette, in order to use a programmatic mechanism. In that later case:
- the server is started by the module
- the module check for server existence, then, if needed, start it
- the server start is under the user's responsability
- it is possible to start (and configure the server's IP/port) in the plugin, and instead fallbacking to manual or spawning mode
This needs to be analyzed afterward. The configurable server interface may be interesting for various use cases, such as using a remote service for analysis, supporting a SAAS at cloud or local LAN level, and so on. This is mostly dependent of what CEA-LSL wish to do