Skip to content

Switch from Cairo_jll to Cairo_NoGPL_jll#373

Open
jkrumbiegel wants to merge 1 commit intoJuliaGraphics:masterfrom
jkrumbiegel:jk/switch-to-cairo-nogpl
Open

Switch from Cairo_jll to Cairo_NoGPL_jll#373
jkrumbiegel wants to merge 1 commit intoJuliaGraphics:masterfrom
jkrumbiegel:jk/switch-to-cairo-nogpl

Conversation

@jkrumbiegel
Copy link
Copy Markdown

Summary

  • Replace Cairo_jll dependency with Cairo_NoGPL_jll to remove the transitive GPL dependency (LZO)
  • Bump version to 1.1.2

Rationale

Cairo.jl only ever calls into libcairo (the core rendering library), which is identical in both Cairo_jll and Cairo_NoGPL_jll. The only difference between the two JLL variants is that Cairo_jll links libcairo-script-interpreter against LZO (GPL-licensed), while Cairo_NoGPL_jll builds it without LZO.

Since Cairo.jl never calls into libcairo-script-interpreter, there is no user-observable impact from this switch. The only scenario affected would be someone accessing the libcairo_script_interpreter handle through the internal JLL reference — but that would be using undocumented internals, and even then the only loss is LZO compression support in CairoScript files (ZLIB still works as a fallback).

LZO itself has zero usage anywhere in libcairo's src/ — it is confined entirely to the separate script interpreter utility library.

How these changes were tested

  • Verified that Cairo_NoGPL_jll exports the same symbols (libcairo, libcairo_gobject, libcairo_script_interpreter)
  • Confirmed via source inspection that all ccalls in Cairo.jl target libcairo, never libcairo_script_interpreter
  • Confirmed that cairo_script_* functions used by Cairo.jl (script surface API) live in libcairo itself (src/cairo-script-surface.c), not in the script interpreter library
  • Verified zero LZO references in Cairo's src/ directory

Created with the help of Claude Code

Cairo.jl only uses libcairo (the core rendering library), which is
identical in both JLL variants. The only difference is that Cairo_jll
links libcairo-script-interpreter against LZO (GPL-licensed), while
Cairo_NoGPL_jll does not. Since Cairo.jl never calls into
libcairo-script-interpreter, there is no user-observable impact.

This avoids a transitive GPL dependency for all downstream packages.
@giordano
Copy link
Copy Markdown
Contributor

I don't think this is a good idea JuliaPackaging/Yggdrasil#13111 (comment)

@jkrumbiegel
Copy link
Copy Markdown
Author

Could you expand why not? The comment you linked to is not very specific either. My purpose here is just to make CairoMakie not pull in LZO but there might be other effects I've overlooked.

@giordano
Copy link
Copy Markdown
Contributor

You can have a single library loaded at a time, if in the same environment there are both Cairo_jll and Cairo_NoGPL_jll at the same time, the behaviour is unpredictable (which library will actually be loaded? who knows, the first one which happens to be loaded).

The whole premise of Cairo_NoGPL was not for doing what's being proposed here, so I'm now regretting having agreed with having that package in.

@andreasnoack
Copy link
Copy Markdown
Contributor

It sounds like LZO is not used downstream at all. There are not that many direct consumers of Cairo_jll, so would a better solution be to only build Cairo_jll but without LZO linking?

@giordano
Copy link
Copy Markdown
Contributor

There are not that many direct consumers of Cairo_jl

If you ignore the 775 indirect dependencies (including anything which has to do with plotting) which will be in chaos, sure, there aren't many dependencies

@jkrumbiegel
Copy link
Copy Markdown
Author

Why should they be in chaos if nothing uses the cairo-script util which is what LZO is used for exclusively as far as I know? libcairo is not affected by this.

@KristofferC
Copy link
Copy Markdown
Member

If you have two different versions of Cairo_jll and Cario_NoGPL_jll, both of those libraries can't be loaded, right? So one of the julia packages will get the wrong thing loaded for it. The point by having a single package is AFAIU to ensure that only a single version of the binary library is resolved and everyone agrees to use that. With two packages for the same library, the versions might get decoupled.

@andreasnoack
Copy link
Copy Markdown
Contributor

@giordano The top comment stated that

...The only scenario affected would be someone accessing the libcairo_script_interpreter handle through the internal JLL reference — but that would be using undocumented internals, and even then the only loss is LZO compression support in CairoScript files (ZLIB still works as a fallback).

LZO itself has zero usage anywhere in libcairo's src/ — it is confined entirely to the separate script interpreter utility library.

so the direct dependencies are relevant because "accessing the libcairo_script_interpreter handle" should only happen from a package that directly depends on the jll. Do you disagree with the assessment of the top comment? If so, it would be helpful if you could elaborate on where you see the chaos coming from.

@Keno
Copy link
Copy Markdown
Contributor

Keno commented Mar 24, 2026

Can we just not build the script interpreter in the base jll and do a separate jll for the script interpreter?

@jkrumbiegel
Copy link
Copy Markdown
Author

jkrumbiegel commented Mar 26, 2026

As far as I can tell, there's no .jl file on github that references libcairo_script_interpreter except forks of Yggdrasil etc.

https://github.com/search?q=%2F%5Cblibcairo_script_interpreter%5Cb%2F+path%3A*.jl&type=code

So given that nobody is using this, neither through Cairo nor Cairo_jll, I think what Keno suggests makes sense. We can make a script_interpreter jll for those who might need it in the future and we remove it from Cairo_jll. Then we tag a new version of Cairo_jll and switch Cairo.jl to it. This will remove LZO from all projects using Cairo while not resulting in any user-observable differences in behavior. A question is if it should be tagged breaking, it technically is of course even if nobody is using this. Not sure if any of the 23 _jll packages depending on Cairo_jll might use libcairo_script_interpreter internally which wouldn't be picked up by my search https://juliahub.com/ui/Packages/General/Cairo_jll#dependents

Another option is to remove LZO from Cairo_jll (what CairoNoGPL_jll is right now) given that the script interpreter can still be built on zlib. Technically that would also be breaking but in practice it might just not be, and we might care more about the practical notion of breaking here than one based on principle that doesn't match our current reality.

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.

5 participants