GR.jl
GR.jl copied to clipboard
GKS: svgplugin.dll: can't load library, error 126 (0x7e)
After https://github.com/JuliaPackaging/Yggdrasil/pull/5784, I am encountering this issue on Windows with GR_jll v0.69.1+1:
GKS: svgplugin.dll: can't load library, error 126 (0x7e)
ERROR: SystemError: opening file "...\\jl_ViZ8T6pmd8.svg": No such file or directory
I can resolve by one of the following.
- Downgrading GR_jll to v0.69.1+0
] add GR_jll#fc933dae4a54c49707193e2dcc7df1e5ef201cab
using GR_JLL
Libdl.dlopen(joinpath(dirname(GR.GRPreferences.GR_jll.libGR_path), "svgplugin"))
I'm adding the later to #483
Resolved in https://github.com/jheinen/GR.jl/pull/483/commits/ea529f5534d6cdffa4ffbbc1615b6263cd1f22a8 . With dont_dlopen
in GR_jll, we need to build GR_jll.LIBPATH
ourselves.
Does this fix https://github.com/JuliaPackaging/Yggdrasil/pull/5784#issuecomment-1301183099 ?
Maybe we can remove PATH
on windows
since LIBPATH
is adjusted...
@jheinen, for the next release of GR.jl
, it'd be cautious to bump to 0.70.0
, since the recent changes might break Plots
.
This would allow us to test Plots
ci before accepting the potentially breaking GR
changes.
Due to illness I am currently in the home office and do not have the possibility to test Windows systems. Hopefully, I can check it on Monday ...
Does this fix https://github.com/JuliaPackaging/Yggdrasil/pull/5784#issuecomment-1301183099 ? Maybe we can remove
PATH
onwindows
sinceLIBPATH
is adjusted...
I suspect that we can. Do you know what the original issue was?
Do you know what the original issue was
From what I recall, this occurred when saving figures, and this involved svgplugin.dll
for sure.
Ha, that might be related to vscode
, https://github.com/JuliaPlots/Plots.jl/issues/4375#issuecomment-1260086074, it'll be great to confirm that GR#master
(and also without PATH
set) works on vscode
on windows
.
Afaik, we can't test vscode
in ci
(especially the embedded display mechanism of Plots
in it), and this caused a lot end users troubles in Plots 1.35
.
Let me recapitulate from the top where the issue is with the yanked GR_jll and what the solution is. I believe there was also a defect on the system binary side.
Yanked GR_jll, v0.69.1+1
issue
GKS loads plugins dynamically. For example, here is where the svgplugin is loaded. https://github.com/sciapp/gr/blob/9aa4f55f75101b76ba8e4406b78601e410642cc6/lib/gks/plugin.c#L247-L248
Thus we need to supply a library path.
The change to Yggdrasil's build_tarballs.jl for GR_jll passed the keyword dont_dlopen
. This results in https://github.com/JuliaBinaryWrappers/GR_jll.jl/commit/acb9ac81324fd1e7c82dccf00815f9ca97ae026f (GR_jll v0.69.1+1) where nothing
is passed as the third argument to JLLWrappers.@init_library_product
.
Examining JLLWrappers.@init_library_product
, setting the third argument dlopen_flags
to nothing
disables two statements: 1) dlopen
and 2) push!(LIBPATH_list, dirname($(path_name)))
.
https://github.com/JuliaPackaging/JLLWrappers.jl/blob/f6f6abe972085c08072f5d61df1cf7e4746da84b/src/products/library_generators.jl#L62-L65
Disabling the push!
call results in the problem. That in turn interferes with the proper construction of GR_jll.LIBPATH
:
https://cs.github.com/JuliaPackaging/JLLWrappers.jl/blob/f6f6abe972085c08072f5d61df1cf7e4746da84b/src/wrapper_generators.jl?q=generate_init_footer#L51
GR_jll.LIBPATH[]
will not contain the artifact path for libGR
.
This propagates through to GRPreferences.libpath[]
:
https://github.com/jheinen/GR.jl/blob/38cb1c8d4d71e01f99293d479d1776363fd09633/src/preferences.jl#L58
That in turn prevents the proper library path from being pushed into the PATH
, DYLD_FALLBACK_LIBRARY_PATH
, and GKS_QT
environment variables.
https://cs.github.com/jheinen/GR.jl/blob/8b18b19a29e1a8fd0977e8000daa135939680f2e/src/GR.jl#L325
https://github.com/jheinen/GR.jl/blob/8b18b19a29e1a8fd0977e8000daa135939680f2e/src/funcptrs.jl#L36-L43
Solution for GR_jll, v0.69.1+1
To compensate for the loss of LIBPATH
building by the JLLWappers resulting from dont_dlopen
, we need to build the LIBPATH
ourselves on GRPreferences.__init__
:
This was implemented in https://github.com/jheinen/GR.jl/commit/ea529f5534d6cdffa4ffbbc1615b6263cd1f22a8#diff-2f56fb4df7441bc075aeb66f5ba5dab42395cfe73bb618c97d3b894cc280cf8eR59-R65
https://github.com/jheinen/GR.jl/blob/ea529f5534d6cdffa4ffbbc1615b6263cd1f22a8/src/preferences.jl#L59-L65
System binary issue
When binary == "system"
, there was a second issue. GRPreferences.libpath[]
was set to joinpath(grdir[], "lib")
. While this is correct on non-Windows systems, it should be joinpath(grdir[], "bin")
on Windows.
https://github.com/jheinen/GR.jl/blob/6fc46ea21a179dcbfc2db916b4e3162de2b124ba/src/preferences.jl#L66
Solution for System binary issue
The switch between lib
and bin
is already implemented in the GRPreferences.lib_path
:
https://github.com/jheinen/GR.jl/blob/ea529f5534d6cdffa4ffbbc1615b6263cd1f22a8/src/preferences.jl#L25-L30
The fix was implemented in https://github.com/jheinen/GR.jl/commit/38cb1c8d4d71e01f99293d479d1776363fd09633 by reusing the lib_path
function.
https://github.com/jheinen/GR.jl/blob/38cb1c8d4d71e01f99293d479d1776363fd09633/src/preferences.jl#L66
Mocking ijulia, atom, pluto, and vscode for testing
The detection mechanisms for determine if we are using an IDE or notebook is located in the following functions. https://github.com/jheinen/GR.jl/blob/7286144090d740c9d1fa1465e68e8146ac7257b5/src/GR.jl#L250-L253
Thus, we can mock these environments by creating fake modules with certain symbols in them.
That will engage the embedded environment clause in GR.init()
.
https://github.com/jheinen/GR.jl/blob/7286144090d740c9d1fa1465e68e8146ac7257b5/src/GR.jl#L316-L321