Skip to content

Commit df51ae6

Browse files
committed
feat(juliacall): allow supplying libjulia path / bindir to skip discovery subprocess
init() starts a short-lived Julia process solely to print libjulia's path and Sys.BINDIR. In pre-built containers / system images these are static and known ahead of time; allow supplying them via the libpath / default_bindir options (PYTHON_JULIACALL_LIBPATH / PYTHON_JULIACALL_DEFAULT_BINDIR) to skip the extra process. Behaviour is unchanged unless both are set. Docs and CHANGELOG updated.
1 parent beec1ec commit df51ae6

3 files changed

Lines changed: 21 additions & 4 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## Unreleased
4+
* JuliaCall: added `libpath` / `default_bindir` options
5+
(`PYTHON_JULIACALL_LIBPATH` / `PYTHON_JULIACALL_DEFAULT_BINDIR`) to supply
6+
libjulia's path and `Sys.BINDIR` directly, skipping the discovery subprocess
7+
at startup. Behaviour is unchanged unless both are set.
8+
39
## 0.9.34 (2026-05-18)
410
* Bug fixes.
511

docs/src/juliacall.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ be configured in two ways:
142142
| `-X juliacall-heap-size-hint=<N>` | `PYTHON_JULIACALL_HEAP_SIZE_HINT=<N>` | Hint for initial heap size in bytes. |
143143
| `-X juliacall-exe=<file>` | `PYTHON_JULIACALL_EXE=<file>` | Path to Julia binary to use (overrides JuliaPkg). |
144144
| `-X juliacall-project=<dir>` | `PYTHON_JULIACALL_PROJECT=<dir>` | Path to the Julia project to use (overrides JuliaPkg). |
145+
| `-X juliacall-libpath=<file>` | `PYTHON_JULIACALL_LIBPATH=<file>` | Path to libjulia. If set together with `default-bindir`, skips the subprocess that discovers it. |
146+
| `-X juliacall-default-bindir=<dir>` | `PYTHON_JULIACALL_DEFAULT_BINDIR=<dir>` | Julia's `Sys.BINDIR`. If set together with `libpath`, skips the subprocess that discovers it. |
145147
| `-X juliacall-trace-compile=<stderr\|name>` | `PYTHON_JULIACALL_TRACE_COMPILE=<stderr\|name>` | Print precompile statements. |
146148
| `-X juliacall-trace-compile-timing` | `PYTHON_JULIACALL_TRACE_COMPILE_TIMING=<yes\|no>` | Include timings with precompile statements. |
147149

pysrc/juliacall/__init__.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -205,10 +205,19 @@ def args_from_config(config):
205205
exepath = CONFIG['exepath']
206206
project = CONFIG['project']
207207

208-
# Find the Julia library
209-
cmd = [exepath, '--project='+project, '--startup-file=no', '-O0', '--compile=min',
210-
'-e', 'import Libdl; print(abspath(Libdl.dlpath("libjulia")), "\\0", Sys.BINDIR)']
211-
libpath, default_bindir = subprocess.run(cmd, check=True, capture_output=True, encoding='utf8').stdout.split('\0')
208+
# Find the Julia library.
209+
#
210+
# This normally starts a short-lived Julia process just to print libjulia's
211+
# path and Sys.BINDIR. In deployment scenarios (e.g. a pre-built container
212+
# or system image) these are static and known ahead of time, so they may be
213+
# supplied directly via the `libpath` / `default_bindir` options to skip the
214+
# extra process. Behaviour is unchanged unless both are set.
215+
libpath = path_option('libpath', check_exists=True)[0]
216+
default_bindir = path_option('default_bindir', check_exists=True)[0]
217+
if libpath is None or default_bindir is None:
218+
cmd = [exepath, '--project='+project, '--startup-file=no', '-O0', '--compile=min',
219+
'-e', 'import Libdl; print(abspath(Libdl.dlpath("libjulia")), "\\0", Sys.BINDIR)']
220+
libpath, default_bindir = subprocess.run(cmd, check=True, capture_output=True, encoding='utf8').stdout.split('\0')
212221
assert os.path.exists(libpath)
213222
assert os.path.exists(default_bindir)
214223
CONFIG['libpath'] = libpath

0 commit comments

Comments
 (0)