eclipse-score / eclipse-score/score
Decision Record for name collision in include paths & file names
- Dominant language
- Starlark
- Stars
- 109
- Forks
- 105
- Avg merge
- 1d 9h
- Merged PRs (30d)
- 21
Description
### What
in relation to
- https://eclipse-score.github.io/score/pr-3196/design_decisions/DR-003-arch.html
- https://github.com/eclipse-score/score/pull/3196
## Header Name Collisions Across Modules
A common worry is what happens when several modules expose an identically named
header — for example `error.h`. The important point is that collisions are decided by
the **include-path string**, not the file name. Two `error.h` files coexist without
issue as long as their include paths differ:
```cpp
#include "score/filesystem/error.h" // baselibs
#include "score/concurrency/future/error.h" // baselibs
```
Both exist side by side in `baselibs` today with no conflict, because the package
prefix makes them unique. A problem only arises when the path is shortened to the bare
file name and two dependencies provide it:
```cpp
#include "error.h" // provided by module A AND module B → ambiguous
```
If a target depends on both libraries, `-I`/`-isystem` ordering decides which file
wins — the wrong header may be included, silently violating the One Definition Rule.
The **Bazel module name does not protect against this**: `@module_a` / `@module_b` do
not appear in the C++ include path by default; the path is determined solely by the
package location and by `strip_include_prefix` / `include_prefix` / `includes`.
**Rule:** Uniqueness must be guaranteed by the include-path **prefix** (the project or
component name). A bare `include/` without a
component-named subdirectory does **not** solve the problem.
## Consequences
### Positive
- The public API of every C++ component is visible, isolated, and self-documenting.
- Bazel `hdrs`/`srcs` boundaries align with the physical layout, reducing accidental
API leakage.
- Consumers get stable, collision-free include paths regardless of how the dependency
is resolved (in-repo, override, or registry module).
- Public SDK packaging for non-Bazel consumers is a folder copy.
- The layout is consistent with widely used community conventions (PFL, P1204).
### Negative / Costs
- A modest, one-time increase in Bazel boilerplate (`strip_include_prefix`) and the
`include//` nesting.
- Minor day-to-day navigation overhead from the `include/` ↔ `src/` split.
- Existing flat components must be migrated to gain the benefits (can be incremental).
### Follow-Up Actions
- Provide a component template / scaffolding (directory skeleton + `BUILD.bazel`) that
encodes the `include//` + `src/` layout and `strip_include_prefix`.
- Document the convention in the S-CORE contribution guidelines and C++ coding
guidelines, including the private-vs-public include-path rules.
- Define a migration path for existing flat components (opportunistic, per module).
- Consider a lightweight CI/lint check that flags private headers appearing in `hdrs`
or public headers being included via non-canonical paths.
### Acceptance Criteria (DoD)
DR is merged
### How
_No response_
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by reading the linked DR-003 architecture decision and PR-3196, then find the repository's existing decision-record location and conventions. Check the referenced contribution and C++ coding guidelines to place the include-path rule and follow-up actions consistently. Done means the decision record is added and merged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- build-system, documentation
- Issue type
- Documentation
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100