Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,11 @@ test --test_output=errors

common --registry=https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/
common --registry=https://bcr.bazel.build

build:linux_aarch64 --platforms=//platforms:linux_aarch64
build:qnx_aarch64 --platforms=//platforms:qnx_aarch64

build:qnx_aarch64 --action_env=QNX_HOST=/work/toolchains/qnx710/qnx710/host/linux/x86_64
build:qnx_aarch64 --action_env=QNX_TARGET=/work/toolchains/qnx710/qnx710/target/qnx7
build:qnx_aarch64 --action_env=PATH=/work/toolchains/qnx710/qnx710/host/linux/x86_64/usr/bin:/usr/bin:/bin
build:qnx_aarch64 --action_env=COMPILER_PATH=/work/toolchains/qnx710/qnx710/host/linux/x86_64/usr/bin/aarch64-unknown-nto-qnx7.1.0/8.3.0:/work/toolchains/qnx710/qnx710/host/linux/x86_64/usr/bin:/work/toolchains/qnx710/qnx710/host/linux/x86_64/usr/lib/gcc/aarch64-unknown-nto-qnx7.1.0/8.3.0:/work/toolchains/qnx710/qnx710/host/linux/x86_64/usr/lib/gcc/aarch64-unknown-nto-qnx7.1.0:/work/toolchains/qnx710/qnx710/host/linux/x86_64/usr/lib/gcc/aarch64-unknown-nto-qnx7.1.0/8.3.0/../../../../aarch64-unknown-nto-qnx7.1.0/bin/aarch64-unknown-nto-qnx7.1.0/8.3.0:/work/toolchains/qnx710/qnx710/host/linux/x86_64/usr/lib/gcc/aarch64-unknown-nto-qnx7.1.0/8.3.0/../../../../aarch64-unknown-nto-qnx7.1.0/bin
20 changes: 14 additions & 6 deletions BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,24 @@ copyright_checker(
visibility = ["//visibility:public"],
)

dash_license_checker(
src = "//examples:cargo_lock",
file_type = "", # let it auto-detect based on project_config
project_config = PROJECT_CONFIG,
visibility = ["//visibility:public"],
)
# dash_license_checker only supports rust and python
# dash_license_checker(
# src = "//examples:cargo_lock",
# file_type = "", # let it auto-detect based on project_config
# project_config = PROJECT_CONFIG,
# visibility = ["//visibility:public"],
# )

# Add target for formatting checks
use_format_targets()

# Documentation generation tool
alias(
name = "doc-gen",
actual = "//tools:doc_gen",
visibility = ["//visibility:public"],
)

docs(
source_dir = "docs",
)
6 changes: 6 additions & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ bazel_dep(name = "rules_cc", version = "0.2.1")

# LLVM Toolchains Rules - host configuration
bazel_dep(name = "toolchains_llvm", version = "1.4.0")
bazel_dep(name = "platforms", version = "0.0.11")

llvm = use_extension("@toolchains_llvm//toolchain/extensions:llvm.bzl", "llvm")
llvm.toolchain(
Expand All @@ -48,6 +49,11 @@ use_repo(llvm, "llvm_toolchain_llvm")

register_toolchains("@llvm_toolchain//:all")

register_toolchains(
"//toolchains:linux_aarch64_toolchain",
"//toolchains:qnx_aarch64_toolchain",
)

# tooling
bazel_dep(name = "score_tooling", version = "1.0.1")
bazel_dep(name = "aspect_rules_lint", version = "1.5.3")
Expand Down
230 changes: 230 additions & 0 deletions docs/README_DOC_GENERATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
# Documentation Generation for SCORE Time Synchronization

This guide explains how to automatically generate documentation (.rst and .puml files) from C++ source code.

## Quick Start

### Generate All Documentation

```bash
# Using bazel (recommended)
bazel run //:doc-gen -- --all

# Or directly with Python
python3 tools/generate_docs.py --all
```

### Build HTML Documentation

```bash
bazel run //:docs
```

### View Documentation

Open `bazel-bin/docs/docs/html/index.html` in your browser.

## Available Options

The documentation generator supports several options:

```bash
# Generate only API documentation
bazel run //:doc-gen -- --api

# Generate only architecture diagrams
bazel run //:doc-gen -- --arch

# Generate only sequence diagrams
bazel run //:doc-gen -- --seq

# Generate all and update index.rst
bazel run //:doc-gen -- --all --update-index
```

## Generated Files

After running `--all`, you will have:

```
docs/
├── api/
│ ├── index.rst # API overview
│ ├── core_types.rst # SharedState, SyncLogEntry, enums
│ ├── ipc.rst # ShmRegion, seqlock functions
│ └── utilities.rst # ClockNs, ParseInteger, PthreadLockGuard
├── diagrams/
│ ├── index.rst # Diagrams overview
│ ├── architecture.puml # High-level system architecture
│ ├── class_relationships.puml # Core class diagram
│ └── sequence_gptp_sync.puml # gPTP synchronization workflow
└── index.rst (updated) # Main documentation index
```

## Using with Claude Code

You can use the `/doc-gen` skill with Claude Code:

```
User: Generate documentation for score_time
Assistant: [Automatically runs documentation generator]
```

The skill is defined in `.claude/skills/doc_generator_skill.md`.

## Customization

### Adding New Diagrams

To add a new PlantUML diagram:

1. Create the `.puml` file in `docs/diagrams/`
2. Reference it in `docs/diagrams/index.rst`:

```rst
.. uml:: diagrams/my_new_diagram.puml
:caption: My New Diagram Description
```

### Extending API Documentation

The generator automatically extracts classes from:
- `src/common/include/score_time/` (public API)
- `src/tsyncd/engine/` (daemon implementation)

To improve extraction:
1. Add Doxygen-style comments to your C++ code:

```cpp
/**
* @brief Brief description of the class
*
* Detailed description here.
*/
class MyClass {
/**
* @brief Brief description of method
* @param arg1 Description of arg1
* @return Description of return value
*/
int MyMethod(int arg1);
};
```

2. Re-run the generator:

```bash
bazel run //:doc-gen -- --api
```

### Manual Tweaks

After auto-generation, you can manually edit:
- `docs/api/*.rst` files to add examples
- `docs/diagrams/*.puml` files to refine visual layout
- `docs/index.rst` to reorganize structure

**Important:** Remember that re-running the generator will overwrite your changes. Consider:
1. Committing generated files to git
2. Using separate `*_custom.rst` files for manual content
3. Editing `tools/generate_docs.py` to customize templates

## Integration with CI/CD

To ensure documentation stays up-to-date:

### GitHub Actions Example

```yaml
name: Documentation

on:
push:
branches: [main]
pull_request:

jobs:
build-docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Generate Documentation
run: bazel run //:doc-gen -- --all

- name: Build HTML Documentation
run: bazel run //:docs

- name: Upload Documentation
uses: actions/upload-artifact@v3
with:
name: documentation
path: bazel-bin/docs/docs/html/
```

### Pre-commit Hook

Add to `.git/hooks/pre-commit`:

```bash
#!/bin/bash
# Regenerate docs before commit
bazel run //:doc-gen -- --all
git add docs/
```

## Troubleshooting

### "Module 'sphinx_needs' not found"

Ensure you have the required Sphinx extensions:

```bash
pip install sphinx sphinx-design sphinx-needs sphinxcontrib-plantuml
```

### "PlantUML diagrams not rendering"

Install PlantUML:

```bash
# Ubuntu/Debian
sudo apt-get install plantuml

# macOS
brew install plantuml
```

Configure path in `docs/conf.py`:

```python
plantuml = 'java -jar /path/to/plantuml.jar'
```

### "Cannot find header file"

Check that the paths in `tools/generate_docs.py` match your project structure:

```python
include_dirs = [
project_root / "src" / "common" / "include" / "score_time",
project_root / "src" / "tsyncd" / "engine",
]
```

## Contributing

When adding new C++ components:

1. Write Doxygen comments for public APIs
2. Run `/doc-gen --all` to update documentation
3. Review generated `.rst` and `.puml` files
4. Add custom examples if needed
5. Commit both code and documentation

## References

- [Sphinx Documentation](https://www.sphinx-doc.org/)
- [PlantUML Guide](https://plantuml.com/)
- [ReStructuredText Primer](https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html)
- [Sphinx C++ Domain](https://www.sphinx-doc.org/en/master/usage/restructuredtext/domains.html#the-c-domain)
60 changes: 60 additions & 0 deletions docs/api/core_types.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
.. ******************************************************************************
Copyright (c) 2025 Contributors to the Eclipse Foundation

See the NOTICE file(s) distributed with this work for additional
information regarding copyright ownership.

This program and the accompanying materials are made available under the
terms of the Apache License Version 2.0 which is available at
https://www.apache.org/licenses/LICENSE-2.0

SPDX-License-Identifier: Apache-2.0
******************************************************************************

Core Types API Reference
========================

.. contents::
:local:
:depth: 2

Overview
--------

This module provides core types for the SCORE Time Synchronization system.


Namespace: ``score_time::ipc``
------------------------------


SyncLogEntry
~~~~~~~~~~~~

.. cpp:struct:: score_time::ipc::SyncLogEntry

Single entry in the synchronization event log Uses per-entry seqlock protocol for lock-free concurrent access between writer (tsyncd daemon) and readers (client applications). **Seqlock Protocol:** - seq is even (0, 2, 4, ...) when entry is readable - seq is odd (1, 3, 5, ...) when writer is updating the entry - Readers retry if seq is odd or changes during read All fields are atomic to prevent torn reads on architectures where 64-bit loads are not naturally atomic.

**Defined in:** :code:`shared_state.hpp`


SharedState
~~~~~~~~~~~

.. cpp:struct:: score_time::ipc::SharedState

Main shared memory structure for IPC between tsyncd daemon and clients This structure is mapped into shared memory (typically /dev/shm/score_time) and provides lock-free access to synchronized time information using seqlock protocol. **Memory Layout:** - Header fields (magic, version, size) for validation - Vehicle time data (gPTP/IEEE 802.1AS synchronized time) - Absolute time data (UTC/wall-clock time from GNSS/NTP) - Circular event logs for diagnostics **Concurrency:** - Single writer (tsyncd daemon) - Multiple readers (client applications) - Uses double-buffering seqlock for vehicle/absolute time - Uses per-entry seqlock for log entries **Version History:** - v1-v3: Original implementations - v4: Added per-entry seqlock to prevent torn reads in logs

**Defined in:** :code:`shared_state.hpp`

**Usage:** Shared memory structure for lock-free IPC.


Examples
--------

See the test files for usage examples:

- Unit tests: ``tests/cpp/``
- Integration tests: ``tests/integration/``

9 changes: 9 additions & 0 deletions docs/api/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
API Reference
=============

.. toctree::
:maxdepth: 2

core_types
ipc
utilities
Loading
Loading