Skip to content

fix(build): compile C++ libraries carried in a STruC++ upload - #177

Open
MatthewReed303 wants to merge 5 commits into
Autonomy-Logic:developmentfrom
MatthewReed303:fix/strucpp-resource-library-includes
Open

MatthewReed303 wants to merge 5 commits into
Autonomy-Logic:developmentfrom
MatthewReed303:fix/strucpp-resource-library-includes

Conversation

@MatthewReed303

Copy link
Copy Markdown

Summary

An upload can carry ordinary C++ library folders under
core/generated/libraries/<name>/, but Makefile.strucpp could not build them:

  • GEN_CPP := $(wildcard $(GENERATED_DIR)/*.cpp) globbed the top level only, so a
    library's sources were never compiled and the link failed on its symbols.
  • Nothing put those libraries' headers on the include path, so a block's
    #include <Foo.h> did not resolve.
  • The %.o pattern rule assumed a flat object tree, so a nested source had
    nowhere to build to.

Three changes:

  • RESOURCE_LIB_INC derives an include root per library folder — its src/ when
    it has one, the folder itself otherwise — and adds them with addprefix -I.
  • Sources are discovered with find, so any depth is covered. Wrapped in sort
    for a reproducible order across filesystems.
  • The pattern rule gained mkdir -p $(@D), since
    libraries/foo/src/transport/bar.cpp now builds to
    $(BUILD_DIR)/libraries/foo/src/transport/bar.o.

An upload with no libraries/ directory compiles exactly as before — find
returns the same set the old wildcard did, and RESOURCE_LIB_INC is empty.

This is the runtime half of an editor change that lets a .stlib ship the C/C++
sources its blocks compile against; the Arduino half needs nothing from here.

Ticket

How it was tested

Built openplc-runtime in Docker from this branch, uploaded a program using a
library that ships its protocol sources as resources, and confirmed the runtime
compiled and loaded it:

-I core/generated/libraries/SensorKit/src -I core/generated/libraries/SensorNet/src
Compiling core/generated/libraries/SensorNet/src/transport/HostUdpTransport.cpp...
  -o build/libraries/SensorNet/src/transport/HostUdpTransport.o
Build complete: build/new_libplc.so
PLC started.

Every part of the change is exercised: the per-library include roots, recursive
discovery, and mkdir -p $(@D) for the nested objects. The loaded libplc_*.so
carries the library's symbols as real objects in the link.

Also confirmed an upload carrying no libraries/ directory builds unchanged.

Checklist

  • bash scripts/run-pytest.sh passes
  • pre-commit run clean
  • Docs updated if behavior changed (README, CLAUDE.md, docs/)
  • Follows docs/pr-reviews/PR_REVIEW_CHECKLIST.md

GEN_CPP globbed the top level only, so a library under
core/generated/libraries/<name>/ was never compiled and its headers were
off the include path. Discover sources recursively, add each library's
src/ as an include root, and mkdir the object directory for nested sources.
…source libraries

- Retain store no longer discards stored values when the program MD5 changes.
  The layout hash check one layer up decides whether they still fit.
- Makefile.strucpp now compiles .c files in vendored libraries with $(CC).
  It also reads `defines=` from each library's library.properties as -D flags.
…fusal reasons, 25 MB limit

- Retain restore: plc_retain_read() queued every restored value on the
  debug-write journal, drained at the end of a cycle, so scan 1 ran on
  initial values and the restore then overwrote what it wrote; with more
  retained leaves than the journal holds (128) the rest were dropped.
  Restore now runs after journal_init() and applies each write
  immediately, before any task is released.

- Retain save: the file store committed on a fixed timer, so a setpoint
  change waited up to a whole period. Now nothing is written without a
  change; a change after a quiet period is committed at once; changes
  within flush_seconds are held and committed, latest values only, when
  the period ends. Default flush_seconds 5 -> 10.

- Upload refusals: analyze_zip sent its reasons (a file over the limit,
  an unsafe path, a disallowed type, the compression ratio, the total
  size) only to the server logger, so the editor and CLI saw
  "Compilation failed" with empty logs. Each reason now also goes to the
  build log the status endpoint returns.

- Upload limit: a program with many function-block instances produces a
  debug-map.json over 10 MB (16.9 MB seen), so it was refused. The
  per-file limit is now 25 MB and the total 100 MB. MAX_CONTENT_LENGTH
  follows MAX_FILE_SIZE.

Tests: host test for the save timing, pytest for the refusal reasons.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant