Skip to content

fix Windows native build portability - #4

Open
terbin wants to merge 1 commit into
2b2tplace:mainfrom
terbin:windows-portability
Open

fix Windows native build portability#4
terbin wants to merge 1 commit into
2b2tplace:mainfrom
terbin:windows-portability

Conversation

@terbin

@terbin terbin commented Jul 13, 2026

Copy link
Copy Markdown

Summary

Two changes so the native (JNI) shared library builds on Windows, with no effect on the Linux build.

Changes

  • cpp/PlaceViewer/CMakeLists.txt: replace set(CMAKE_CXX_FLAGS "-fPIC") with set(CMAKE_POSITION_INDEPENDENT_CODE ON). A raw -fPIC is invalid on the windows-msvc target (and clang-scan-deps, used for C++20 module scanning, promotes it from a warning to a hard error). The POSITION_INDEPENDENT_CODE property is the portable, compiler-abstracted equivalent: CMake emits -fPIC for the static dependencies on Linux and nothing on Windows. Set before the FetchContent calls, so it propagates to the fetched static targets. It's also cleaner than the raw flag, which overwrote CMAKE_CXX_FLAGS and only covered C++ (not C) sources.
  • cpp/PlaceViewer/CMakeLists.txt: normalize the output library arch name to what the Java loader (PlaceViewerLibrary.java) expects. CMAKE_SYSTEM_PROCESSOR is AMD64 on Windows, which produced PlaceViewer-AMD64.dll, but the loader normalizes os.arch and looks up PlaceViewer-x86_64.dll (exact match), so the DLL built fine yet would fail to load at runtime. Map AMD64 to x86_64 (and ARM64 to aarch64) so the name matches on every platform.
  • cpp/PlaceViewer/src/viewer/jni/jni_native_region3d.cpp: malloc_trim is a glibc-only function. Guard it behind #if defined(__GLIBC__) so it stays active on glibc and compiles to a no-op on Windows/macOS/musl.

Verification

  • Windows: clang 22 + vcpkg produces PlaceViewer-x86_64.dll (now matches the Java loader's expected name; the DLL statically bundles Boost/zlib/OpenSSL, so at load time it needs only the MSVC runtime + Windows UCRT).
  • Linux: g++ 13.3 produces libPlaceViewer-x86_64.so. Confirmed via compile_commands.json that the fetched static dependencies still compile with -fPIC and link into the shared object (a successful static-into-shared link on x86-64 is itself proof of PIC). The malloc_trim symbol is present in the .so, confirming the glibc branch compiles in.
  • Runtime (Windows): bundled into the mod jar and run on a live Paper 1.21.4 + Ignite server: the DLL loads over JNI (PlaceViewer native libraries have been successfully loaded), registry initialization runs, and the server reaches ready and shuts down cleanly, with no UnsatisfiedLinkError, missing-DLL, or exception.

Runtime note (Windows)

The DLL links the MSVC C++ runtime dynamically, so it needs the process's msvcp140.dll to be ≥ 14.40 (VS 2022 17.10, where std::mutex's ABI changed). It still loads fine against an older one, but then null-derefs in std::mutex::lock on the first region load. A JVM that bundles an older msvcp140.dll in its bin/ is loaded ahead of the system one, which is how this bites. Launch with a JDK whose bundled runtime is ≥14.40, or, for a fully self-contained DLL, statically link the MSVC runtime (CMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded), which would require the vcpkg dependencies rebuilt with the x64-windows-static triplet. Left as a follow-up; not part of this PR.

Dependencies & merge order

This is the umbrella PR of a coordinated Windows/g++ portability set. Because PlaceViewer fetches pinned tags of zvcr and mc-cpp, a full Windows build needs, in order:

  1. 2b2tplace/zvcr, companion PR: fix builds under MSVC and g++ zvcr#6
  2. 2b2tplace/mc-cpp, companion PR: fix Windows/MSVC build portability mc-cpp#1
  3. tag/release zvcr and mc-cpp, then bump their pinned GIT_TAGs in cpp/PlaceViewer/CMakeLists.txt
  4. this PR

This change is safe and independent on its own and does not regress the Linux build; it simply isn't sufficient for a full Windows build until 1-3 are done.

- CMakeLists: use CMAKE_POSITION_INDEPENDENT_CODE instead of a raw
  -fPIC flag, which is unsupported on the windows-msvc target
- CMakeLists: normalize the output arch name so Windows produces
  PlaceViewer-x86_64.dll (CMAKE_SYSTEM_PROCESSOR is AMD64 there),
  matching what the Java loader looks for
- jni_native_region3d: guard glibc-only malloc_trim() behind
  __GLIBC__
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