Guard the add_test shadow on being top-level again
CMake chains command overrides one level deep: a second override rebinds
_add_test to the first and the builtin becomes unreachable to everyone. So two
projects in one tree cannot both shadow add_test, and akbasic has to shadow it
first for libakerror and libakstdlib -- which left its own registrations
recursing to CMake's depth limit.
The unconditional shadow arrived with the vendored-dependency fix in 18399f2.
That half stays; only the guard comes back.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
35
TODO.md
35
TODO.md
@@ -1278,6 +1278,41 @@ Every size below is measured, not estimated.
|
||||
`amdgpu_dri.so`; running it headless produces none, and headless is what the
|
||||
suites are written for anyway.
|
||||
|
||||
### Found while embedding libakgl in a consumer
|
||||
|
||||
40. ~~**Shadowing `add_test()` unconditionally broke every embedding consumer.**~~ **Fixed in
|
||||
the same release it was introduced in**, and worth keeping because the CMake behaviour
|
||||
behind it is not obvious and will catch the next person.
|
||||
|
||||
18399f2 moved the vendored-dependency block out from behind
|
||||
`if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)` — which was the point of that
|
||||
commit — and took the `add_test()`/`set_tests_properties()` override out with it. The
|
||||
override's own comment claimed "an embedding consumer's `add_test()` still reaches CTest".
|
||||
It does not, and cannot.
|
||||
|
||||
**CMake chains command overrides exactly one level deep.** Overriding `add_test` makes the
|
||||
builtin available as `_add_test`; overriding it a *second* time rebinds `_add_test` to the
|
||||
*first* override and the builtin becomes unreachable to everybody, permanently — there is
|
||||
no `__add_test`. Verified directly rather than inferred from the documentation:
|
||||
|
||||
```cmake
|
||||
function(add_test) _add_test(${ARGV}) endfunction() # _add_test -> builtin
|
||||
function(add_test) _add_test(${ARGV}) endfunction() # _add_test -> the first override
|
||||
if(COMMAND __add_test) ... endif() # absent
|
||||
```
|
||||
|
||||
So two projects in one tree cannot both shadow it. `akbasic` shadows it first — it has to,
|
||||
for `libakerror` and `libakstdlib`, which register their tests unconditionally — and its own
|
||||
registrations then recursed until CMake stopped at "Maximum recursion depth of 1000
|
||||
exceeded". A consumer had no way to work around it: once the builtin is gone it is gone for
|
||||
that project too.
|
||||
|
||||
**Fix:** the override is guarded on being top-level again, exactly as it was before 18399f2
|
||||
and exactly as `libakstdlib` guards its own. The vendored-dependency block stays
|
||||
unconditional, which is what that commit was actually for. An embedded `libakgl` leaves
|
||||
`add_test` alone and lets its consumer suppress what it does not want — machinery the
|
||||
consumer has to have anyway.
|
||||
|
||||
## Build notes
|
||||
|
||||
The vendored SDL satellite libraries are built into per-project subdirectories
|
||||
|
||||
Reference in New Issue
Block a user