r-lib / processx

Execute and Control Subprocesses from R
https://processx.r-lib.org/
Other
232 stars 43 forks source link

R setting LD_LIBRARY_PATH causes problems in Julia #382

Closed karldw closed 8 months ago

karldw commented 8 months ago

TL;DR: Setting env = c("current", LD_LIBRARY_PATH = "") can help.

Description

R sometimes sets the LD_LIBRARY_PATH environment variable, which is then inherited by subprocesses. This can cause issues for some Julia packages when Julia is called from R. Here I'm demonstrating Plots.jl, but it happens with others too. (Plots.jl is not installed by default. Julia will prompt you to install if it's not available.)

Sys.getenv("LD_LIBRARY_PATH")
#> [1] "/usr/lib/R/lib:/usr/lib/x86_64-linux-gnu:/usr/lib/jvm/default-java/lib/server"
Sys.getenv("R_LD_LIBRARY_PATH")
#> [1] ""

processx::run("julia", c("--project=.", "-E", "using Plots"))
#> Error in `processx::run("julia", c("--project=.", "-E", "using Plots"))`:
#> ! System command 'julia' failed
#> ---
#> Exit status: -11
#> Stderr:
#> ERROR: InitError:
#> ---

processx::run("julia", c("--project=.", "-E", "using Plots"), env=c("current", LD_LIBRARY_PATH=""))
#> $status
#> [1] 0

system2

base::system2() has the same issues as processx, though with system2, setting LD_LIBRARY_PATH="" doesn't seem to solve things. (I have not dug into this.)

system2 equivalent ```r system2("julia", c("--project=.", "-E", '"using Plots"')) #> ERROR: InitError: could not load library "~/.julia/artifacts/466e859891e85a1f8a887e712f17b1645ec9c803/lib/libQt6Concurrent.so" #> /usr/lib/x86_64-linux-gnu/libQt6Core.so.6: version `Qt_6.5' not found (required by ~/.julia/artifacts/466e859891e85a1f8a887e712f17b1645ec9c803/lib/libQt6Concurrent.so) #> Stacktrace: #> [1] dlopen(s::String, flags::UInt32; throw_error::Bool) #> @ Base.Libc.Libdl ./libdl.jl:117 #> [2] dlopen(s::String, flags::UInt32) #> @ Base.Libc.Libdl ./libdl.jl:116`` #> [3] macro expansion #> @ ~/.julia/packages/JLLWrappers/pG9bm/src/products/library_generators.jl:63 [inlined] #> [4] __init__() #> @ Qt6Base_jll ~/.julia/packages/Qt6Base_jll/fqleI/src/wrappers/x86_64-linux-gnu-cxx11.jl:36 #> [5] register_restored_modules(sv::Core.SimpleVector, pkg::Base.PkgId, path::String) #> @ Base ./loading.jl:1115 #> [6] _include_from_serialized(pkg::Base.PkgId, path::String, ocachepath::String, depmods::Vector{Any}) #> @ Base ./loading.jl:1061 #> [7] _tryrequire_from_serialized(modkey::Base.PkgId, path::String, ocachepath::String, sourcepath::String, depmods::Vector{Any}) #> @ Base ./loading.jl:1391 #> [8] _require_search_from_serialized(pkg::Base.PkgId, sourcepath::String, build_id::UInt128) #> @ Base ./loading.jl:1494 #> [9] _require(pkg::Base.PkgId, env::String) #> @ Base ./loading.jl:1783 #> [10] _require_prelocked(uuidkey::Base.PkgId, env::String) #> @ Base ./loading.jl:1660 #> [11] macro expansion #> @ ./loading.jl:1648 [inlined] #> [12] macro expansion #> @ ./lock.jl:267 [inlined] #> [13] require(into::Module, mod::Symbol) #> @ Base ./loading.jl:1611 #> during initialization of module Qt6Base_jll ```

Platform:

I don't have any of the LD_LIBRARY_PATHs set outside of R:

echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH"
#> LD_LIBRARY_PATH=
echo "R_LD_LIBRARY_PATH=$R_LD_LIBRARY_PATH"
#> R_LD_LIBRARY_PATH=
echo "R_JAVA_LD_LIBRARY_PATH=$R_JAVA_LD_LIBRARY_PATH"
#> R_JAVA_LD_LIBRARY_PATH=

Impact

This is not actually a problem with processx, but I thought I should document it here, in case it saves someone else some time. The only change processx could make is to remove LD_LIBRARY_PATH by default, but that's not worth the risk of breaking other things.

Related issues

Environment variables generally:

Julia-specific:

karldw commented 8 months ago

One more thing: Julia can set environment variables at startup, by editing ~/.julia/config/startup.jl.

ENV["LD_LIBRARY_PATH"] = ""

Unfortunately, that does not seem to solve the problem here.