Skip to content

Add Linux (x64) support: presets and POSIX port#31

Open
LelandJin wants to merge 4 commits into
carbonengine:mainfrom
LelandJin:linux-support
Open

Add Linux (x64) support: presets and POSIX port#31
LelandJin wants to merge 4 commits into
carbonengine:mainfrom
LelandJin:linux-support

Conversation

@LelandJin

Copy link
Copy Markdown

Summary

Adds Linux (x64) support to carbon core. Configures, builds, and passes the full test suite (184/184, GCC 15 / Fedora 43) with the new presets.

Build system

  • CMakePresets.json: new hidden linux/x64-linux base presets (condition hostSystemName == Linux) and concrete x64-linux-{debug,internal,release,trinitydev} presets, mirroring the Windows/macOS structure. Toolchain and triplets come from the companion vcpkg-registry PR.
  • CMakeLists.txt: two file names fixed to their on-disk casing (CcpDefines.cpp, CcpMemoryTrackerMutex.h) — case-insensitive filesystems masked this; Linux fails to configure without it.

Platform port (the existing POSIX #else branches already cover most of Linux; these fill the gaps)

  • include/CcpThread.h / CcpThread.cpp: __linux__ uses the shared POSIX implementation with pthread_t ids/handles and CcpGetThreadTimes via getrusage(RUSAGE_THREAD) (same 100 ns units as other platforms).
  • CCPAssert.cpp: Linux CcpIsDebuggerPresent() reading TracerPid from /proc/self/status; include/CCPAssert.h now uses the same debugger-gated CCP_DEBUG_BREAK on Linux as on macOS.
  • CcpFileUtils.cpp: guard BSD-only O_EXLOCK/O_SHLOCK; CcpExecutablePath() via readlink("/proc/self/exe").
  • CCPMemory.cpp: CcpGetProcessMemoryInfo() from /proc/self/status + getrusage.
  • StringConversions.cpp: UTF-8 ⇄ wchar_t (UTF-32) conversions for non-Apple POSIX (on macOS these overloads live in StringConversions.mm); passes the existing round-trip tests.
  • Missing standard includes that MSVC/AppleClang provided transitively (<cstdint>, <climits>, <sys/time.h>, <cstring>, <atomic>, <cmath>).

Bug fixes surfaced by the port (latent on all platforms)

  • CCPCallstack.cpp: strchr result was dereferenced before the null check in Enumerate — glibc backtrace_symbols lines without + crashed; macOS lines always contain + so it never fired there.
  • CcpTelemetry.cpp: fiber-cleanup loop called queue::front() after popping the last element (UB; aborts under _GLIBCXX_ASSERTIONS).

No behavior changes on Windows or macOS — all platform branches are additive.

Validation

  • Fedora Linux 43 (WSL2), GCC 15.2.1, CMake 3.31, cmake --preset x64-linux-debug.
  • All 20 vcpkg dependencies (tracy, gtest, lz4, python3 host + transitive) build with the new triplets.
  • ctest: 184/184 tests pass (5 disabled upstream, unchanged).

Notes

  • Depends on the carbonengine/vcpkg-registry PR adding x64-linux triplets/toolchains; the vendored registry submodule needs a pointer bump once that merges.
  • Environment note: vcpkg's bundled patchelf 0.15.5 corrupts DT_INIT of shared libraries emitted by newer binutils during its RPATH fixup (loader crash in call_init — first seen when python3's _ctypes loads libffi). Using patchelf ≥ 0.18 resolves it; worth pinning when Linux CI is set up.

Add x64-linux CMake presets mirroring the Windows/macOS structure and port the platform-specific code to Linux: pthread-based thread ids and getrusage thread times, TracerPid-based debugger detection, /proc/self/exe executable path, O_EXLOCK/O_SHLOCK guards, /proc-based process memory info, UTF-8 <-> wchar_t conversions for non-Apple POSIX, and the standard includes MSVC/AppleClang provided transitively.

Also fixes issues surfaced by the port: two source file names with wrong casing in CMakeLists.txt, a strchr null-pointer dereference in CCPCallstack::Enumerate, and a queue::front() call on an empty queue in the telemetry fiber cleanup loop.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 04eed14812

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread CcpFileUtils.cpp
LelandJin added 2 commits July 15, 2026 10:58
BSD's O_EXLOCK/O_SHLOCK acquire a flock-style advisory lock atomically at open() time. On platforms without those flags (Linux, Android), apply the equivalent blocking flock() right after opening; if the lock cannot be acquired the descriptor is closed and -1 is returned, matching the failure behavior of the locked open.
sem_timedwait expects an absolute CLOCK_REALTIME timestamp; passing a relative value makes the wait return almost immediately instead of waiting for the requested timeout.

Spotted by Patric Stout (TrueBrain) in his Linux port of the Carbon components: https://github.com/TrueBrain/carbonengine-linux
@LelandJin

Copy link
Copy Markdown
Author

Ha, glad to hear it :) Your repo is a goldmine — thanks. I've already adopted your sem_timedwait absolute-time fix into this PR (credited, a795e00).

Returning the favor: I put five patches on top of your carbon-core series — two latent bugs I hit while porting independently (a strchr null deref in CcpCallstack::Enumerate that glibc's backtrace_symbols triggers, and a queue::front() on an empty queue in the telemetry fiber cleanup that aborts under _GLIBCXX_ASSERTIONS), flock()-based share-mode locking instead of the O_EXLOCK=0 shims, a debugger-gated CCP_DEBUG_BREAK that re-enables the two memory-guard tests (side note: the old guard tested WIN32, which MSVC doesn't define, so they were off on Windows too), and a codecvt-free UTF-8 conversion (codecvt_utf8 is gone in C++26).

Validated on top of your full series at 250df52 with your presets: 189/189 tests pass. GitHub won't let me open a PR against your repo (interaction limits?), so here's the branch, exported with your export-port-patches.sh: TrueBrain/carbonengine-linux@main...LelandJin:carbonengine-linux:core-fixes — feel free to pull it in however you prefer.

The option existed but the build was broken with it: CcpSemaphore/CcpMutex/CcpStatistics include tracy headers unconditionally (no include path without find_package(Tracy)), CCPMemory and CcpSemaphore relied on tracy's include chain to reach the CcpSecureCrt shims, and the test target always compiled the Tracy client tests and linked Tracy::TracyClient. Guard the tracy includes behind CCP_TELEMETRY_ENABLED, include CcpSecureCrt.h explicitly, and only build/link the telemetry tests when WITH_TELEMETRY is on.

The missing CcpSecureCrt.h include in CCPMemory.cpp was spotted by Patric Stout (TrueBrain) in his Linux port: https://github.com/TrueBrain/carbonengine-linux
@LelandJin

Copy link
Copy Markdown
Author

Two more verified additions to this PR:

  • a795e00sem_timedwait was being passed a relative timespec, but it expects an absolute CLOCK_REALTIME timestamp, so CcpSemaphore::TimedWait returned (almost) immediately instead of waiting. Fix spotted by @TrueBrain in his Linux port.
  • fe263b1WITH_TELEMETRY=OFF no longer breaks the build: tracy includes are now guarded by CCP_TELEMETRY_ENABLED, CCPMemory.cpp/CcpSemaphore.cpp include CcpSecureCrt.h explicitly instead of relying on tracy's include chain, and the Tracy client tests only build/link when telemetry is enabled.

Validated on the x64-linux-debug preset in both configurations: default 184/184 tests pass, WITH_TELEMETRY=OFF builds clean and passes 170/170 (the 14 telemetry tests are excluded by design in that configuration).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant