Linux output viewer
The optional Linux Debug terminal module opens a separate native terminal for process stdout/stderr, including C stdio, C++ streams, native writes, logging and emergency reports. It works independently of a rendering context. Engine has no dependency on this module; root application/test composition chooses it.
Use selection/attachment to include the viewer, build/runtime policy to control when it opens, and output/lifetime to understand stream ownership. Test reporting explains saved records and headless/discovery behavior; checks separate automation from desktop QA.
Selection and attachment
module_debug_terminal_linux is an interface target, publicly named
Cheryl::DebugTerminal::Linux. The root also supplies Cheryl::DebugTerminal for
the selected implementation. Root selection is CHERYL_BUILD_DEBUG_TERMINAL_LINUX,
defaulting to ON for a single-configuration Linux build with GNU/Clang and
CMAKE_BUILD_TYPE=Debug, and OFF otherwise. Standalone module consumers set this
option explicitly. Other platforms have no implementation. A consuming application
selects the module by linking
its public target; the root demo and shared test-main composition do so automatically.
Build the consuming executable rather than naming the interface as a build target;
included consumers bring in the implementation and viewer dependencies.
Cheryl::DebugTerminal::Startup names the private static attachment support
owned by this module (cengine_debug_terminal_startup), located under
private/startup/. It produces no startup DLL. Its CE::Application::DebugTerminal::run(argc, argv, application, start) accepts an application entry point and a module-owned startup
callback. Without a callback it invokes the application with the original arguments
and performs no terminal work. The support owns argument policy only; it does not
discover modules, own native sessions or require Engine to call a platform backend.
The Linux implementation uses the GNU-compatible linker --wrap=main attachment,
supplying its callback before application startup. It owns session shutdown through
atexit. Hosts with another entry-point wrapper must resolve their composition
explicitly. This module is not included in the
development SDK exports;
its installed-package deployment and another platform implementation remain unimplemented.
Build and runtime policy
|
Linked configurations |
Display policy |
|---|---|---|
|
Every configuration |
Automatic in Debug; other configurations require |
|
None |
No attachment or argument consumption. |
The default applies when the option first enters the CMake cache. Changing
CMAKE_BUILD_TYPE later retains that cached value; set the option explicitly to
change inclusion. Multi-configuration generators default to OFF; explicit ON
includes the terminal in every configuration from that build directory.
These rules are independent of logging profile and severity. When the option is
OFF, consumers link neither the native implementation nor the viewer dependency.
Linking plain Engine does not select this module. CHERYL_DEBUG_TERMINAL_AVAILABLE
describes whether the interface includes its implementation.
When attached, --debug-terminal and --no-debug-terminal are consumed before the
application parser; the last occurrence wins. Arguments after -- pass through.
Help, GoogleTest listing and re-executed death-test discovery suppress display.
Headless execution without DISPLAY or WAYLAND_DISPLAY uses inherited output.
When the implementation is omitted, these options remain application arguments;
they cannot enable a facility that was not linked.
CHERYL_DEBUG_TERMINAL_EMULATOR accepts auto, konsole or xterm. Automatic
selection tries Konsole, then xterm when the launcher is unavailable. The viewer
is cheryl-debug-terminal-viewer, built as a dependency of included consumers;
launch failure, invalid handshake or unavailable support reports to inherited
stderr and preserves the application’s inherited output path.
Output and lifetime
An owned temporary directory contains an append-only capture file and a Unix control socket. stdout/stderr share the file, so their stream identity is not retained. A separately launched viewer drains it live; newline-free buffered output still follows producer flushing. The viewer inherits no runner output descriptors, so a retained crash viewer cannot hold CTest capture channels open. File logging and severity filters remain independent.
Normal exit flushes captured output, signals the viewer to drain/close and removes
the temporary capture. Loss of the control connection without normal shutdown
retains available output until manual viewer closure. This detects abnormal process
loss, not the semantic difference between a signal, _Exit or a specific crash.
Normal nonzero return and handled startup errors still use normal shutdown.
Manual viewer closure leaves the application running. Subsequent output continues in the capture file until shutdown, with a notice and its path on inherited stderr; file logs continue. There is no automatic reopening or mirroring to the launch terminal. File-backed capture avoids dependence on a live pipe reader, but is not a disk quota or infallible output-delivery guarantee.
Test reporting
Repository-owned GoogleTest uses generated build-tree routing copies. Framework reports, assertion progress, help/listing and diagnostics use separately saved inherited output channels; tested engine/module writes use terminal capture. The dependency source checkout is unchanged. Internal stdout/stderr capture and death-test output retain their framework semantics, and XML remains independent.
A supplied GoogleTest target without the routing capability causes terminal startup
to fall back to inherited output. Discovery creates no viewer. Each included test
process owns its own viewer; parallel processes do not share a window or producer
identity. Interactive Debug test launches therefore create separate viewers unless
disabled. Builds with the terminal option OFF keep their existing reporting/output
paths.
Checks and acceptance limits
The explicitly buildable targets tests-acceptance-engine-terminal and
tests-acceptance-engine-terminal-reports supply raw-output/lifetime and framework
probes. They are not ordinary standalone test runs: some scenarios deliberately
fail or terminate. The terminal.py driver selects
them, controls fake emulator launchers and checks output, rollback/reaping, crash
retention, manual closure, discovery, captures, death tests and XML.
Configuration matrix
The Linux configuration matrix uses Debug ON, Release OFF, Release ON and
Debug OFF. Included configurations cover C/C++/native/worker/logger
output, final draining, startup rollback, launcher reaping, manual closure, abnormal
process loss, help/discovery, framework reporting/diagnostics, captures, both death-test
styles and XML. Omitted configurations establish
omission and passthrough; their final links exclude the implementation archive,
entry wrapper and viewer dependency.
To repeat the matrix or prepare desktop probe binaries, use Linux GNU/Clang, Engine text dependencies, initialized pinned GoogleTest and Python 3 without optimization. The standalone composition needs no GLFW/OpenGL/UI selection. Reuse each matching source/toolchain/configuration independently:
(
set -e
cd "$(git rev-parse --show-toplevel)"
for selection in Debug:ON Release:OFF Release:ON Debug:OFF; do
terminal_configuration="${selection%%:*}"
terminal_inclusion="${selection#*:}"
terminal_build="build/testing-terminal-${terminal_configuration}-${terminal_inclusion}"
cmake -S projects/modules/platform/debug-terminal-linux -B "$terminal_build" -G Ninja \
-DCMAKE_BUILD_TYPE="$terminal_configuration" \
-DCMAKE_POLICY_VERSION_MINIMUM=3.5 -DCMAKE_CXX_SCAN_FOR_MODULES=OFF \
-DCHERYL_REPOSITORY_ROOT="$PWD" -DCHERYL_LOG_PROFILE=developer \
-DCHERYL_BUILD_TESTS=ON -DCHERYL_BUILD_ACCEPTANCE_TESTS=OFF \
-DCHERYL_BUILD_DEBUG_TERMINAL_LINUX="$terminal_inclusion" \
-DCHERYL_DEBUG_TERMINAL_EMULATOR=auto
cmake --build "$terminal_build" --parallel --target \
tests-acceptance-engine-terminal tests-acceptance-engine-terminal-reports
python3 projects/modules/platform/debug-terminal-linux/tests/acceptance/terminal.py \
"$terminal_build" --configuration "$terminal_configuration" \
--inclusion "$terminal_inclusion"
done
)
Controlled launcher checks do not establish actual Konsole/xterm window behavior, desktop/IDE launch or another operating system. The real-desktop request retains those observations and reuses matching probe binaries from this procedure.