Compose.jl
Compose.jl copied to clipboard
Revise + Requires + Cairo + Fontconfig + Compose produces a pango error
Hi -- has anyone seen this before...
The error below does not occur when just doing:
julia> using Cairo, Fontconfig
julia> using Compose
However, there seems to be some difficulty when using Revise (a VSCode default) with Compose + Cairo + Fontconfig:
_
_ _ _(_)_ | Documentation: https://docs.julialang.org
(_) | (_) (_) |
_ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 1.5.0 (2020-08-01)
_/ |\__'_|_|_|\__'_| | Official https://julialang.org/ release
|__/ |
julia> using Revise
julia> using Cairo, Fontconfig
julia> using Compose
julia> ┌ Error: evaluation error starting at /home/dehann/.julia/dev/Compose/src/pango.jl:30
│ mod = Compose
│ ex =
│ quote
│ #= /home/dehann/.julia/dev/Compose/src/pango.jl:28 =#
│ let available_font_families = Set{AbstractString}()
│ #= /home/dehann/.julia/dev/Compose/src/pango.jl:29 =#
│ for font_pattern = Fontconfig.list()
│ #= /home/dehann/.julia/dev/Compose/src/pango.jl:30 =#
│ push!(available_font_families, lowercase(Fontconfig.format(font_pattern, "%{family}")))
│ end
│ #= /home/dehann/.julia/dev/Compose/src/pango.jl:33 =#
│ meta_families = Set(["serif", "sans", "sans-serif", "monospace", "cursive", "fantasy"])
│ #= /home/dehann/.julia/dev/Compose/src/pango.jl:35 =#
│ global match_font
│ #= /home/dehann/.julia/dev/Compose/src/pango.jl:36 =#
│ function match_font(families::AbstractString, size::Float64)
│ #= /home/dehann/.julia/dev/Compose/src/pango.jl:36 =#
│ #= /home/dehann/.julia/dev/Compose/src/pango.jl:37 =#
│ matched_family = "sans-serif"
│ #= /home/dehann/.julia/dev/Compose/src/pango.jl:38 =#
│ for family = [lowercase(strip(family, [' ', '"', '\''])) for family = split(families, ',')]
│ #= /home/dehann/.julia/dev/Compose/src/pango.jl:39 =#
│ if family in available_font_families || family in meta_families
│ #= /home/dehann/.julia/dev/Compose/src/pango.jl:40 =#
│ matched_family = family
│ #= /home/dehann/.julia/dev/Compose/src/pango.jl:41 =#
│ break
│ end
│ end
│ #= /home/dehann/.julia/dev/Compose/src/pango.jl:44 =#
│ family = Fontconfig.format(match(Fontconfig.Pattern(family = matched_family)), "%{family}")
│ #= /home/dehann/.julia/dev/Compose/src/pango.jl:45 =#
│ desc = #= /home/dehann/.julia/dev/Compose/src/pango.jl:45 =# @sprintf("%s %fpx", family, size)
│ #= /home/dehann/.julia/dev/Compose/src/pango.jl:46 =#
│ fd = ccall((:pango_font_description_from_string, libpango), Ptr{Cvoid}, (Ptr{UInt8},), desc)
│ #= /home/dehann/.julia/dev/Compose/src/pango.jl:47 =#
│ return fd
│ end
│ end
│ end
│ exception =
│ UndefRefError: access to undefined reference
│ Stacktrace:
│ [1] getindex at ./array.jl:809 [inlined]
│ [2] lookup_var at /home/dehann/.julia/packages/JuliaInterpreter/RmxVj/src/interpret.jl:4 [inlined]
│ [3] collect_args(::JuliaInterpreter.Frame, ::Expr; isfc::Bool) at /home/dehann/.julia/packages/JuliaInterpreter/RmxVj/src/interpret.jl:60
└ @ Revise ~/.julia/packages/Revise/BqeJF/src/lowered.jl:106
WARNING: redefinition of constant pango_attrs. This may fail, cause incorrect answers, or produce other errors.
Attempt to Fix
I had similar-ish problems elsewhere when Requires.jl inputs use a begin end
block -- i.e. this is "bad":
function __init__()
@require SomePkg="abc123..." begin
@info "Doing stuff"
include("MoreUtils.jl")
end
end
but not when doing include directly:
function __init__()
@require SomePkg="abc123..." include("MoreUtils.jl")
end
So I have been changing to this all over (e.g. IncrementalInference.jl 845)
cc @timholy (Hi) since this might relate to timholy/Revise.jl#520
Different Error with Compose
I have been attempting to fix locally by doing the same pattern, but then ccall
starts having issues. The current @require
code looks like this
https://github.com/GiovineItalia/Compose.jl/blob/121510649e9c195545881a824916d6a81580ddc1/src/Compose.jl#L156-L180
But when I change to this:
function link_fontconfig()
@debug "Loading Fontconfig backend into Compose.jl"
include(joinpath(@__DIR__, "pango.jl")) # THIS IS THE ATTEMPT 2/2
pango_cairo_ctx[] = C_NULL
ccall((:g_type_init, libgobject), Cvoid, ())
pango_cairo_fm[] = ccall((:pango_cairo_font_map_new, libpangocairo),
Ptr{Cvoid}, ())
pango_cairo_ctx[] = ccall((:pango_font_map_create_context, libpango),
Ptr{Cvoid}, (Ptr{Cvoid},), pango_cairo_fm[])
pangolayout[] = PangoLayout()
end
function link_cairo()
@debug "Loading Cairo backend into Compose.jl"
include(joinpath(@__DIR__,"cairo_backends.jl"))
include(joinpath(@__DIR__,"immerse_backend.jl"))
end
function __init__()
@require Cairo="159f3aea-2a34-519c-b102-8c37f9878175" link_cairo()
# THIS IS THE ATTEMPT 1/2
@require Fontconfig="186bb1d3-e1f7-5a2c-a377-96d770f13627" link_fontconfig()
end
But then this happens (WITHOUT using Revise):
julia> using Cairo, Fontconfig
julia> using Compose
[ Info: Precompiling Compose [a81c6b42-2e10-5240-aca2-a61377ecd94b]
┌ Warning: Error requiring Fontconfig from Compose:
│ TypeError: in ccall: first argument not a pointer or valid constant expression, expected Ptr, got a value of type Tuple{Symbol,String}
│ Stacktrace:
│ [1] link_fontconfig() at /home/dehann/.julia/dev/Compose/src/Compose.jl:162
│ [2] top-level scope at none:1
│ [3] eval at ./boot.jl:331 [inlined]
│ [4] eval at /home/dehann/.julia/dev/Compose/src/Compose.jl:1 [inlined]
│ [5] (::Compose.var"#119#125")() at /home/dehann/.julia/packages/Requires/qy6zC/src/require.jl:85
│ [6] err(::Any, ::Module, ::String) at /home/dehann/.julia/packages/Requires/qy6zC/src/require.jl:42
│ [7] (::Compose.var"#118#124")() at /home/dehann/.julia/packages/Requires/qy6zC/src/require.jl:84
│ [8] withpath(::Any, ::String) at /home/dehann/.julia/packages/Requires/qy6zC/src/require.jl:32
│ [9] (::Compose.var"#117#123")() at /home/dehann/.julia/packages/Requires/qy6zC/src/require.jl:83
│ [10] listenpkg(::Any, ::Base.PkgId) at /home/dehann/.julia/packages/Requires/qy6zC/src/require.jl:15
│ [11] macro expansion at /home/dehann/.julia/packages/Requires/qy6zC/src/require.jl:81 [inlined]
│ [12] __init__() at /home/dehann/.julia/dev/Compose/src/Compose.jl:178
│ [13] _include_from_serialized(::String, ::Array{Any,1}) at ./loading.jl:697
│ [14] _require_from_serialized(::String) at ./loading.jl:749
│ [15] _require(::Base.PkgId) at ./loading.jl:1040
│ [16] require(::Base.PkgId) at ./loading.jl:928
│ [17] require(::Module, ::Symbol) at ./loading.jl:923
│ [18] eval(::Module, ::Any) at ./boot.jl:331
│ [19] eval_user_input(::Any, ::REPL.REPLBackend) at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.5/REPL/src/REPL.jl:134
│ [20] repl_backend_loop(::REPL.REPLBackend) at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.5/REPL/src/REPL.jl:195
│ [21] start_repl_backend(::REPL.REPLBackend, ::Any) at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.5/REPL/src/REPL.jl:180
│ [22] run_repl(::REPL.AbstractREPL, ::Any; backend_on_current_task::Bool) at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.5/REPL/src/REPL.jl:292
│ [23] run_repl(::REPL.AbstractREPL, ::Any) at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.5/REPL/src/REPL.jl:288
│ [24] (::Base.var"#806#808"{Bool,Bool,Bool,Bool})(::Module) at ./client.jl:399
│ [25] #invokelatest#1 at ./essentials.jl:710 [inlined]
│ [26] invokelatest at ./essentials.jl:709 [inlined]
│ [27] run_main_repl(::Bool, ::Bool, ::Bool, ::Bool, ::Bool) at ./client.jl:383
│ [28] exec_options(::Base.JLOptions) at ./client.jl:313
│ [29] _start() at ./client.jl:506
└ @ Requires ~/.julia/packages/Requires/qy6zC/src/require.jl:44
For Reference
Pretty sure I'm on the latest packages, and
julia> versioninfo()
Julia Version 1.5.0
Commit 96786e22cc (2020-08-01 23:44 UTC)
Platform Info:
OS: Linux (x86_64-pc-linux-gnu)
CPU: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-9.0.1 (ORCJIT, skylake)
Environment:
JULIA_NUM_THREADS = 6
Thanks for the detailed investigation! I'm sorry for this annoying warning. I don't think it's hurting anything serious, but I really do need to get to it sometime soon.