Skip to content

fix(sconstruct): correct Java libjvm discovery and Python linking#12

Open
quinnjr wants to merge 1 commit intoFIUBioRG:masterfrom
quinnjr:bugfix/sconstruct-java-python-detection
Open

fix(sconstruct): correct Java libjvm discovery and Python linking#12
quinnjr wants to merge 1 commit intoFIUBioRG:masterfrom
quinnjr:bugfix/sconstruct-java-python-detection

Conversation

@quinnjr
Copy link
Copy Markdown
Contributor

@quinnjr quinnjr commented Apr 15, 2026

Summary

The SConstruct build fails on two common real-world toolchains: a non-/usr/bin Python (pyenv, conda, system updates) and OpenJDK 8 on RHEL-derived distros. This PR fixes both without changing the build's default behavior on systems where it already works.

Problem

Python detection

  • python3-config was invoked as /usr/bin/python3-config, so its flags did not match the Python interpreter build_support had actually selected via $PATH. Result: compile-time includes and link-time flags for two different interpreters.
  • On Python 3.8+, python3-config --ldflags no longer emits -lpython3.x unless --embed is passed, so linking the embedded interpreter silently dropped the library.

Java / libjvm discovery

  • The previous logic only probed $JAVA_HOME/lib/server and $JAVA_HOME/lib. JDK 8 on Linux (java-1.8.0-openjdk-*) keeps libjvm.so under jre/lib/<arch>/server, so detection failed on any RHEL/CentOS/Rocky host with the default OpenJDK 8 package.
  • A stale, hardcoded LIBPATH pointing at /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.472.b08-1.el8_10.x86_64/jre/lib/amd64/server/ leaked into the environment of anyone who happened to have a matching libjvm.so at the computed lib_dir — a reviewer-hostile landmine that bound the build to one specific RPM version.
  • $LIBJVM was read but never used to actually resolve the library directory.
  • The resolved libjvm directory was not added to the binary's RPATH, so running pluma required the user to set LD_LIBRARY_PATH at runtime.

Changes

SConstruct:

  • Invoke python3-config via $PATH (matches the interpreter build_support selected). Append --embed when running on CPython >= 3.8 so -lpython3.x is emitted.
  • Replace the two-entry probe with an ordered candidate list covering both modern (lib/server) and JDK 8 (jre/lib/<arch>/server) layouts. <arch> is derived from platform.machine() with the standard x86_64 -> amd64, aarch64, i686 -> i386 mapping.
  • Honor $LIBJVM as an explicit override: if it points at an existing file, its directory becomes the resolved LIBPATH.
  • Drop the hardcoded RHEL JDK path. Append the resolved directory to RPATH via SCons so the built pluma binary finds libjvm.so at runtime without LD_LIBRARY_PATH.
  • Import platform as _platform to avoid the shadowing from build_config.py that already exists in this file.
  • When detection fails, the warning now lists the directories that were searched, which is what you want when debugging someone else's build log.

No default behavior changes on a system where the old code already worked: the first two candidates in the probe list are the same paths the old code checked, in the same order.

Test plan

  • scons on RHEL 8 / Rocky 9 with java-1.8.0-openjdk-devel installed and $JAVA_HOME pointing at the JDK 8 root — verify libjvm.so is found under jre/lib/amd64/server and the resulting pluma runs without LD_LIBRARY_PATH.
  • scons on a system with a modern JDK (17/21) — verify lib/server is still picked first and the build is unchanged.
  • scons with $LIBJVM=/path/to/libjvm.so — verify the override wins over the candidate probe.
  • scons under a pyenv or conda Python 3.10+ that is first on $PATH — verify python3-config is resolved from $PATH and that -lpython3.x appears in the link command (i.e. --embed is in effect).
  • scons under a Python 3.7 interpreter — verify --embed is omitted.
  • readelf -d build/pluma | grep RPATH — confirm the resolved JVM directory is embedded.

- python3-config: use $PATH binary instead of hardcoded /usr/bin one, so
  the flags match the interpreter picked up by build_support. Add --embed
  on Python 3.8+ so ldflags emits -lpython3.x.
- libjvm discovery: probe jre/lib/<arch>/server (JDK 8 layout) in addition
  to lib/server; honor $LIBJVM; drop the stale hardcoded 1.8.0.472 path.
- Embed an rpath to the resolved JVM dir via SCons RPATH so pluma runs
  without LD_LIBRARY_PATH.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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