Skip to content

Generated Code Layout

Oleksandr Geronime edited this page Jun 27, 2026 · 2 revisions

Generated Code Layout

Understanding the gen/ versus src/ split is fundamental to working with SERP. The rule is simple: gen/ is fully disposable and regenerated on every serpgen generate-workspace run; src/ is user-owned and never touched by serpgen.

The Core Rule

Directory Owner Rule
gen/ serpgen Delete and regenerate at will. Never hand-edit.
src/ You Business logic lives here. serpgen never writes to it.
specs/ You Source of truth. Changes here drive regeneration.

Full Directory Layout

specs/
  serp.sidl                            # workspace root
  interfaces/IClimate.sidl.yaml        # interface contract
  services/ClimateManager.sidl         # service spec

gen/                                   # DISPOSABLE — regenerated every time
  components/
    Climate/
      src/services/ClimateManager/
        IClimateManager.hpp            # Generated typed interface
        impl/
          ClimateManagerBase.hpp       # Generated base class (handler wiring)
          ClimateManagerBase.cpp
          ClimateManager.hpp           # Default stub (do not hand-edit)
          ClimateManager.cpp
  deployments/
    monolith/
      main.cpp                         # Process entry point
      CMakeLists.txt                   # Build targets
    multiprocess_dbus/
      climate_hal_app/
        main.cpp
        CMakeLists.txt
      car_service_app/
        main.cpp
        CMakeLists.txt
      lifecycle/
        climate_hal_app.service        # systemd unit
        car_service_app.service

src/                                   # USER-OWNED — never overwritten
  components/
    Climate/
      services/
        ClimateManager/
          ClimateManagerImpl.hpp       # Your implementation
          ClimateManagerImpl.cpp

build/                                 # Build output (gitignored)
tests/                                 # Your test code
scripts/                               # build.sh, run.sh, etc.

Service Inheritance Chain

Every service follows the same four-layer inheritance pattern:

IClimateManager          (generated interface — abstract, typed calls/props/notifications)
       ↑
ClimateManagerBase       (generated — wires handlers, injects dependencies)
       ↑
ClimateManager           (generated default stub — safe no-op implementations)
       ↑
ClimateManagerImpl       (your code — business logic lives here)

Layer Responsibilities

IClimateManager.hpp — The public contract. Declares all methods, attribute accessors, and notification subscriptions as pure virtual functions. Generated from the interface spec.

ClimateManagerBase.hpp/.cpp — Handles all generated wiring: registering method handlers with the framework, property change callbacks, broadcast emit helpers, and constructor injection of uses dependencies. Regenerated every time serpgen runs.

ClimateManager.hpp/.cpp — Default stub that extends ClimateManagerBase. Provides empty or no-op implementations of every method so the project compiles immediately after generation. Never manually edited — regenerated every time.

ClimateManagerImpl.hpp/.cpp — Your implementation. Extends ClimateManager. This is where business logic lives. Written by you; serpgen creates it once if it does not exist, then never touches it again.

What to Edit and What Not To

Path Edit? Reason
gen/ (any file) Never Regenerated on every serpgen run — changes are lost
gen/deployments/*/main.cpp Never Generated process wiring
src/components/.../Impl.hpp/.cpp Yes Your business logic
specs/ Yes Source of truth — edit specs, then regenerate
tests/ Yes Your test code
scripts/ Yes Build and run scripts

Adding a New Method to an Existing Service

  1. Add the method to the interface spec in specs/interfaces/IMyService.sidl.yaml.
  2. Run serpgen generate-workspace -w specs/serp.sidl.
  3. gen/ is updated — IMyService.hpp, MyServiceBase, and MyService stub all gain the new method.
  4. src/.../MyServiceImpl.hpp/.cpp is untouched. Override the new method there.

gitignore Recommendations

gen/
build/

The gen/ directory should be gitignored. It is fully reproducible from the specs. Committing generated code leads to merge conflicts and drift between specs and generated output.

Related Pages

Clone this wiki locally