Basics and targets

Dependencies

About Merlin sources hierarchy

Merlin library

The Merlin library is the main build target of the project. It is compiled as a static library (libmerlin.a) from the sources described below.

Source layout

Sources are organised under three subdirectories of src/:

src/
├── buses/
│   ├── i2c/       # I2C bus driver
│   ├── usb/       # USB bus driver
│   ├── usart/     # USART bus driver
│   └── spi/       # SPI bus driver (reserved)
├── platform/      # hardware abstraction layer (HAL)
└── externals/     # external device drivers

Public headers are exposed under include/merlin/:

include/
└── merlin/
    ├── buses/          # public bus APIs (i2c.h, usb.h, usart.h, spi.h)
    ├── platform/       # platform driver API (driver.h)
    ├── arch/           # register-access primitives, per architecture
    │   ├── asm-cortex-m/
    │   ├── asm-rv32/
    │   └── asm-generic/
    ├── io.h            # I/O primitives entry point
    └── helpers.h       # common utilities

Source integration

The build system uses the Meson sourceset module to assemble sources conditionally. Each subdirectory of src/ appends its files to the merlin_common_src list, which is then wrapped in a source_set and filtered against the active Kconfig symbols:

merlin_sourceset = ssmod.source_set()
# ... each subdirectory feeds merlin_common_src
merlin_sourceset.add(merlin_common_src)
merlin_sourceset_config = merlin_sourceset.apply(kconfig_data, strict: false).sources()

This allows drivers to be included or excluded automatically based on the active Kconfig configuration, without any manual edits to the meson.build files.

DeviceTree-generated headers

Each bus driver provides a template file *_dt.h.in that is processed by the dts2src tool against the compiled DeviceTree to produce a private C header. These generated headers (e.g. i2c_dt.h, usb_dt.h) are tracked as generated_private_headers and added as a dependency of the library target:

i2c_dt_h = custom_target('gen_i2c_dt_h',
    input:   i2c_dt_h_template,
    output:  '@BASENAME@',
    command: [ dts2src, '-d', dts.full_path(), '-t', '@INPUT@', '@OUTPUT@' ],
    depends: [ dts ],
)
generated_private_headers += [ i2c_dt_h ]

Final target

The library is assembled in a static_library target that brings together:

  • the sources selected by the Kconfig-filtered source_set,

  • kconfig.h, force-included (-include) into every compilation unit,

  • the public headers from include/,

  • the external shield and uapi dependencies.

A merlin_dep Meson dependency object is declared so that examples and downstream projects can consume the library with a single dependency() call:

merlin_dep = declare_dependency(
    link_with:           merlin_lib,
    dependencies:        [ external_deps ],
    include_directories: merlin_inc,
)

Merlin examples

Built by default: false

-Dwith_examples=false