eclipse-score / eclipse-score/score

Decision Record for name collision in include paths & file names

Open Beginner friendly
#3,234 0 comments 0 reactions 0 assignees View on GitHub
community:architecture
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.