Skip to content

Jolt linker errors on Linux: undefined JPH symbols #44

@proggeramlug

Description

@proggeramlug

Summary

cargo test --release against bloom-shared on Ubuntu 22.04 fails to link the test binary even though the cmake build of bloom_jolt + libJolt succeeds. macOS builds and runs the same tests cleanly.

Repro

Ubuntu 22.04 (or act / a Linux VM) with the runner-image deps:

sudo apt-get install -y cmake build-essential pkg-config
cd native/shared
cargo test --release

Symptoms

error: linking with `cc` failed: exit status: 1
  rust-lld: error: undefined symbol: JPH::Free
  rust-lld: error: undefined symbol: JPH::BodyManager::UnlockWrite(unsigned long) const
  rust-lld: error: undefined symbol: JPH::BodyManager::LockWrite(unsigned long) const
  rust-lld: error: undefined symbol: JPH::BodyManager::UnlockRead(unsigned long) const
  rust-lld: error: undefined symbol: JPH::BodyManager::LockRead(unsigned long) const
  rust-lld: error: undefined symbol: JPH::BodyManager::GetMutexMask(JPH::BodyID const*, int) const
  rust-lld: error: undefined symbol: JPH::Trace
  rust-lld: error: undefined symbol: JPH::ProfileThread::sInstance
  rust-lld: error: undefined symbol: JPH::ProfileMeasurement::sOutOfSamplesReported
  rust-lld: error: undefined symbol: vtable for JPH::CharacterBase
  ...

Link line shows -Wl,-Bstatic" "-lbloom_jolt" "-lJolt" "-Wl,-Bdynamic" "-lstdc++" — both static archives are present on the link line.

Hypothesis

Likely a preprocessor-define mismatch between how libJolt.a was compiled vs what bloom_jolt.a expects:

  • JPH::Trace, JPH::ProfileThread::sInstance, JPH::ProfileMeasurement::sOutOfSamplesReported are profile/debug symbols that exist only when JPH_PROFILE_ENABLED is defined.
  • The bloom_jolt shim's translation unit may be picking up the inline header definitions that call those symbols, while libJolt.a was compiled with profile turned off and so didn't emit them.

Our native/third_party/bloom_jolt/CMakeLists.txt already sets:

set(USE_ASSERTS                         OFF CACHE BOOL "" FORCE)
set(PROFILE_ENABLED                     OFF CACHE BOOL "" FORCE)
set(GENERATE_DEBUG_SYMBOLS              OFF CACHE BOOL "" FORCE)

…but those flags need to also be propagated as compile definitions on the bloom_jolt target itself so the shim's inline-included Jolt headers don't reference the disabled-out symbols. Check whether Jolt 5.5.0's CMakeLists.txt exports those defines via target_compile_definitions(Jolt PUBLIC ...) or whether we need to mirror them on our own target.

Why macOS works

macOS host build (cargo test --release on macos-14 runner and locally) links cleanly. The cmake/Apple-clang combo may be more permissive about weak/unresolved profile symbols, or it strips them via -Wl,-dead_strip before they trip the linker.

Acceptance criteria

  • cargo test --release in native/shared/ passes on Ubuntu 22.04 with the same Jolt feature set as macOS
  • All 13+ jolt_sys integration tests run end-to-end on Linux
  • CI's shared-tests (ubuntu-22.04) job goes green

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions