Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Headers processing

Filtering header content

A C/C++ header can contains different zone, some of which are parts of the public API, and some of which may correspond to specific low-level options.

litgen (and srcmlcpp) can filter a header based on preprocessor #ifdef / #ifndef occurrences.

Let’s look at an example header: its code is defined in the cpp_code variable below.

cpp_code = """
#ifndef MY_HEADER_H   // This is an inclusion guard, it should not be filtered out

void Foo() {}

#ifdef ARCANE_OPTION
    // We are entering a zone that handle arcane options that should not be included in the bindings
    void Foo2() {}
#else
    // this should also not be included in the bindings
    void Foo3() {}
#endif

#ifdef COMMON_OPTION
    // We are entering a zone for which we would like to publish bindings
    void Foo4();
#endif

#endif // #ifndef MY_HEADER_H
"""

Let’s try to generate bindings for it:

import litgen
from litgen.demo import litgen_demo

options = litgen.LitgenOptions()
litgen_demo.demo(options, cpp_code)
Loading...

We see that elements inside #ifdef ARCANE_OPTION were not processed. However, elements inside #ifdef COMMON_OPTION were not processed. Let’s correct this by adjusting the options:

options = litgen.LitgenOptions()

# the default value for header_filter_acceptable__regex was
#     "__cplusplus|_h_$|_h$|_H$|_H_$|hpp$|HPP$|hxx$|HXX$"
# (which includes support for common header guards)
# Let's add support for COMMON_OPTION
options.srcmlcpp_options.header_filter_acceptable__regex = "_H$|^COMMON_OPTION$"
litgen_demo.demo(options, cpp_code)
Loading...

API Prefixes

In a given header files, function can have an “API Prefix”, that denotes whether they should be published or not in a shared library.

cpp_code = """
// This function has an API marker and is exported in a shared library
MY_API int add(int, int b);

// This function does not have an API marker, and is probably private
int mul(int a, int b);
"""

You can set the API marker in the options:

options = litgen.LitgenOptions()
options.srcmlcpp_options.functions_api_prefixes = "MY_API"
litgen_demo.demo(options, cpp_code)
Loading...

You can also decide to export non API function, with an optional comment.

options = litgen.LitgenOptions()
options.srcmlcpp_options.functions_api_prefixes = "MY_API"
options.fn_exclude_non_api = False
options.fn_non_api_comment = "Private API!"
litgen_demo.demo(options, cpp_code)
Loading...

Header preprocessing

If you need to preprocess header code before the generation, you can create a function that transforms the source code, and store it inside options.srcmlcpp_options.code_preprocess_function.

For example:

def preprocess_change_int(code: str) -> str:
    return code.replace("int", "Int32")  # This is a *very* dumb preprocessor


cpp_code = """
int add(int, int b);
"""
options = litgen.LitgenOptions()
options.srcmlcpp_options.code_preprocess_function = preprocess_change_int
generated_code = litgen.generate_code(options, cpp_code)
litgen_demo.show_cpp_code(generated_code.stub_code)
Loading...