# as-built — what is actually running **Copied out of the live `openplc-runtime` container on 2026-09-02**, from `/workdir/core/generated/`. This is the compiled artefact set the running PLC was built from — the ground truth, as opposed to `../src/`, which is the intent. > [!WARNING] > **Do not edit anything in this folder and do not build from it.** It is a > snapshot for reference and recovery. The editable source is `../src/`. ## Why keep it The running PLC is a **`docker commit` image**. The compiled program lives in the container's writable layer, not in a volume and not in any registry. If that image is lost, and the OpenPLC Editor is still unavailable (`../DEPLOY.md` §0), this folder is the only remaining copy of the compiled form of the program. It is also the proof of what is deployed: you can read the C++ the PLC is actually executing, rather than inferring it from the ST. ## Contents | File | What | |---|---| | `program.st` | The ST as the Editor serialised and uploaded it | | `generated.hpp` | STruC++ declarations for every POU and global | | `pou_CONTROL.cpp` etc. | One C++ file per POU — the compiled logic | | `configuration.cpp` | The task configuration: `plc_task`, 100 ms, three program instances | | `generated_debug.cpp`, `debug-map.json` | Variable maps for the Editor's debugger | | `program.st.map.json` | Line map from the generated C++ back to `program.st` | | `strucpp_runtime/include/` | The STruC++ runtime headers the build needs | | `conf/modbus_slave.json` | **The Modbus buffer layout** — `qw_count: 1024` is why `%MW0` is HR 1024 | | `conf/ethercat.json` | 0 bytes. Emitted by the Editor by default; it is what leaves the EtherCAT plugin enabled for no reason. | | `c_blocks.h`, `defines.h` | Small generated headers | Built **2026-08-14**. Loaded as `libplc_1786668930820554523.so`. ## Verified against `../src/` on 2026-09-02 `program.st` was compared with `build/wrps.st` generated from `../src/`, after stripping comments and normalising whitespace: ``` POU structure identical - FB_PUMP, FB_DUTY_SELECT, FB_LEVEL_CTRL, FB_HEADROOM, CONTROL, IO_MUX, SIMULATION, CONFIGURATION Config0, three task instances Non-declaration lines 0 differences, in either direction Declaration lines differ in formatting only - the Editor requires one declaration per line, and holds VAR_GLOBAL in project.json rather than in the ST ``` **The deployed program is this repo's source.** `../src/` is canonical, and the running PLC agrees with it. ## Using this for an emergency change If the Editor is unavailable and something must change *now*, the container can rebuild from these files without any external toolchain — g++ 12.2 and Make are inside it: ```bash # on yau-sls-poc-lin001 docker exec -it openplc-runtime bash # edit core/generated/pou_*.cpp ./scripts/compile.sh # rebuilds build/new_libplc.so ``` > [!CAUTION] > **This is break-glass, not a workflow.** You would be editing generated C++, > which immediately diverges from `../src/`, and the next proper deployment > silently discards your change. The PLC also stops while it reloads. If you do > it, record what you changed and port it back into `../src/` the same day. Prefer restoring the Editor. See `../DEPLOY.md` §0.