Screenplay: Generated Code (add_custom_command()
)¶
What We Want¶
Imagine …
In the Linux variant, sensor configurations are read from
.ini
style config fileDeeply embedded cannot do this because there is no filesystem
Solution …
Can we generate code from these config files?
⟶ link-time polymorphism
Handwritten Prototype: What A Code Generator Could Do For Us¶
Lets say, sensor config files have the format
[bottom-right] Type = Const Value = -273.15 # ... more ...
In a dedicated
.cpp
file, we mirror that same information (this is what we will generate)#include "conf-sensors.h" // <--- THE config's extern declaration #include <sensor-const.h> SensorConfig conf_sensors; // <--- THE config's definition namespace { struct conf_sensors_init { conf_sensors_init() { conf_sensors.add_sensor("bottom-right", std::make_unique<ConstantSensor>(-273.15)); // ... more ... }; }; conf_sensors_init init; };
Main program uses
conf_sensors
from theextern
declaration#include "conf-sensors.h" // <--- conf_sensors' extern declaration DataLogger logger(conf_sensors, // <--- conf_sensors' usage ...);
One Deeply Embedded Application (2024-06-20-manual.cpp
)¶
data-logger-deeply-embedded.cpp
usesconf_sensors
⟶ defined in
2024-06-20-manual.cpp
… or any other file …
⟶ link-time decision
Build instructions for the
2024-06-20-manual.cpp
constellationadd_executable( app-data-logger-deeply-embedded-2024-06-20-manual data-logger-deeply-embedded.cpp 2024-06-20-manual.cpp # <--- polymorphic ) target_link_libraries(app-data-logger-deeply-embedded-2024-06-20-manual base data-logger) install(TARGETS app-data-logger-deeply-embedded-2024-06-20-manual DESTINATION bin)
Another Deeply Embedded Application (Generated From 2024-06-20.conf
)¶
Generator demo
$ pwd .../firmware $ ./config-generator.py 2024-06-20.conf /tmp/demo.cpp $ cat /tmp/demo.cpp
Build instructions: link with a not-yet-existig file,
2024-06-20.cpp
(from the build tree)add_executable( app-data-logger-deeply-embedded-2024-06-20 data-logger-deeply-embedded.cpp ${CMAKE_CURRENT_BINARY_DIR}/2024-06-20.cpp # <--- to be generated ) target_link_libraries(app-data-logger-deeply-embedded-2024-06-20 base data-logger) install(TARGETS app-data-logger-deeply-embedded-2024-06-20 DESTINATION bin)
Code generation:
add_custom_command()
add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/2024-06-20.cpp # <--- same as in add_executable() COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/config-generator.py ${CMAKE_CURRENT_SOURCE_DIR}/2024-06-20.conf ${CMAKE_CURRENT_BINARY_DIR}/2024-06-20.cpp DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/config-generator.py ${CMAKE_CURRENT_SOURCE_DIR}/2024-06-20.conf )
Discuss
DEPENDS
…Generated config includes
conf-sensors.h
from source directory ⟶PRIVATE
“include” propertytarget_include_directories(app-data-logger-deeply-embedded-2024-06-20 PRIVATE .)