- CMakePresets.json: add 'fast' preset (clang+lld+ccache) - .gitignore: generalize build/ to build*/, add CMakeUserPresets.json - CMakeUserPresets.json: untrack (conan-generated, now gitignored) - src/Core/Archives.h: remove redundant 'using basic_xml_iarchive::load_override' in xml_iarchive; caused ambiguous overload with clang (diamond inheritance) - src/Core/Object.cpp: remove invalid explicit instantiations of non-template virtual Object::serialize (GCC extension, clang rejects) - README.md, CLAUDE.md: document GCC and LLVM/clang build workflows Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
103 lines
5.3 KiB
Markdown
103 lines
5.3 KiB
Markdown
|
|
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Build Commands
|
|
|
|
```bash
|
|
# Activate the conda environment (required before any build/run)
|
|
export MAMBA_EXE="/home/share/micromamba/bin/micromamba"
|
|
export MAMBA_ROOT_PREFIX="/home/share/micromamba"
|
|
eval "$(/home/share/micromamba/bin/micromamba shell hook --shell bash)"
|
|
micromamba activate mutom
|
|
|
|
# Configure (from repo root, using Conan preset — uses Ninja + ccache)
|
|
cmake --preset conan-release
|
|
|
|
# Build everything
|
|
cmake --build build -j$(nproc)
|
|
|
|
# Build a specific target
|
|
cmake --build build --target gcompose -j$(nproc)
|
|
|
|
# Run tests
|
|
cmake --build build --target test
|
|
# or
|
|
ctest --test-dir build
|
|
|
|
# Run a single test binary (example)
|
|
./build/src/Core/testing/CoreTest
|
|
|
|
# Run the gcompose GUI app
|
|
./build/app/gcompose/gcompose
|
|
```
|
|
|
|
First-time setup (if `build/` does not exist):
|
|
```bash
|
|
conan profile detect
|
|
conan install . --output-folder=build --build=missing
|
|
cmake --preset conan-release
|
|
```
|
|
|
|
### Build acceleration (already configured)
|
|
- **Ninja** generator — used automatically via the conan default profile (`~/.conan2/profiles/default`)
|
|
- **ccache** — enabled via `CMAKE_CXX_COMPILER_LAUNCHER=ccache`; cached rebuilds are nearly instant (~0.3s vs ~25s cold)
|
|
- **Clang 22 + lld** profile available (`~/.conan2/profiles/fast`) but blocked by template overload ambiguities in `src/Core/Archives.h` that need fixing for full compatibility
|
|
|
|
To reconfigure with the fast profile once Archives.h is fixed:
|
|
```bash
|
|
conan install . --output-folder=build --build=missing --profile=fast
|
|
cmake -B build -G Ninja -DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release
|
|
cmake --build build -j$(nproc)
|
|
```
|
|
|
|
## Architecture
|
|
|
|
**uLib** is a C++ framework for Cosmic Muon Tomography (CMT), structured as layered shared libraries:
|
|
|
|
```
|
|
mutomCore → mutomMath → mutomDetectors → mutomGeant
|
|
↘
|
|
mutomVtk → gcompose (Qt6 GUI app)
|
|
mutomRoot
|
|
```
|
|
|
|
### Core Object Model (`src/Core/`)
|
|
- All framework objects inherit from `uLib::Object`
|
|
- **Property system**: `Property<T>` wraps member pointers with change notification via `PropertyChanged` signal
|
|
- **Signal/slot**: `uLib::Object::connect(sender, &Sender::Signal, callback)` — resembles Qt but works for non-QObject classes
|
|
- **Serialization**: Boost archives (`xml_oarchive`, `text_oarchive`, `hrt_oarchive`); `hrp<T>` marks fields as "human-readable properties"
|
|
- `ObjectsContext` is a container owning a list of `Object*` pointers; signals `ObjectAdded`/`ObjectRemoved`
|
|
|
|
### VTK Layer (`src/Vtk/`)
|
|
- `Puppet` (inherits `uLib::Object`): wraps a VTK `vtkProp` for rendering. Has `GetContent()` returning the underlying domain object. Display-only properties are registered via `ULIB_ACTIVATE_DISPLAY_PROPERTIES` macro.
|
|
- `Viewport`: base class managing the VTK renderer, picking, selection logic. Maintains `m_Puppets` vector and `m_ObjectToPuppet` map.
|
|
- `QViewport` (inherits `QWidget` + `Viewport`): Qt-embedded VTK widget. Emits Qt signal `puppetSelected(Puppet*)` on click-selection via `OnSelectionChanged`.
|
|
- `vtkObjectsContext`: wraps `ObjectsContext`, creating/destroying `Puppet`s as objects come/go. Emits `PuppetAdded`/`PuppetRemoved`.
|
|
- Display properties: `serialize_display()` + `display_properties_archive` registers selected `hrp<T>` fields as `PropertyBase*` in the puppet's `m_DisplayProperties`. `PropertyEditor::setObject(obj, displayOnly=true)` shows only those.
|
|
|
|
### gcompose GUI App (`app/gcompose/src/`)
|
|
- `MainPanel`: top-level widget. Owns `ContextPanel` (left) and `ViewportPane` (right). Wires together viewport↔context selection via signals.
|
|
- `ContextPanel`: tree view of `ObjectsContext`. Emits `objectSelected(Object*)`. Contains an embedded `PropertiesPanel`.
|
|
- `PropertiesPanel`: shows `uLib::Object` properties via `PropertyEditor`.
|
|
- `ViewportPane`: embeds `QViewport` + a slide-out "Display Properties" panel (`PropertyEditor` in display-only mode).
|
|
- `PropertyEditor`: populates widgets from `Object::GetProperties()` (all) or `Puppet::GetDisplayProperties()` (display-only mode).
|
|
|
|
### Selection Sync Flow
|
|
```
|
|
Viewport click → Viewport::SelectPuppet() → QViewport::OnSelectionChanged()
|
|
→ emit puppetSelected(p)
|
|
→ MainPanel: contextPanel->selectObject(p->GetContent()) [updates tree + PropertiesPanel]
|
|
→ MainPanel: firstPane->setObject(p) [updates Display Properties panel]
|
|
|
|
ContextPanel tree click → emit objectSelected(obj)
|
|
→ MainPanel: viewport->SelectPuppet(puppet) [visual selection in VTK]
|
|
→ MainPanel: firstPane->setObject(puppet) [updates Display Properties panel]
|
|
```
|
|
|
|
### Key Patterns
|
|
- **Two signal systems coexist**: Qt signals (`Q_OBJECT`, `connect(...)`) for GUI; `uLib::Object::connect(...)` for domain signals.
|
|
- **Display properties** flow: `Puppet::serialize_display()` → `display_properties_archive` → `RegisterDisplayProperty()` → `PropertyEditor(displayOnly=true)`. Must call `ULIB_ACTIVATE_DISPLAY_PROPERTIES` in the puppet constructor.
|
|
- **Puppet ↔ Object map**: `Viewport::m_ObjectToPuppet` allows lookup by domain object; `vtkObjectsContext::GetPuppet(obj)` does the same.
|