Skip to content

Commit

Permalink
[LazyJLLWrappers] Make the new lazy JLLWrappers a separate package
Browse files Browse the repository at this point in the history
We can actually co-exist with JLLWrappers with a little bit of extra
work, adding an `eager_mode()` function [0].  This allows us to have
fully lazy semantics when the entire tree of dependencies is using
`LazyJLLWrappers`, but subtrees that have old `JLLWrappers` JLLs will
all be flipped into eager mode.

X-ref: JuliaPackaging/JLLWrappers.jl#61
  • Loading branch information
staticfloat committed Mar 27, 2024
1 parent c5d4efd commit a5e52fd
Show file tree
Hide file tree
Showing 15 changed files with 48 additions and 24 deletions.
2 changes: 1 addition & 1 deletion JLLGenerator.jl/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
This package provides the tools necessary to generate JLLs, the thin wrapper packages the Julia ecosystem uses to provide access to external binaries.
The main datastructure in this package is the `JLLInfo` object, which takes in a single lump, the entire description of the binary objects to be wrapped.

This package is tightly coupled with `JLLWrappers.jl`; the TOML files that this package generates are read in by `JLLWrappers.jl` to auto-generate the necessary bindings.
This package is tightly coupled with `JLLWrappers2.jl`; the TOML files that this package generates are read in by `JLLWrappers2.jl` to auto-generate the necessary bindings.
This package is also tightly coupled with `BinaryBuilderProducts.jl`, as the nature of the binary objects to be wrapped are described by those products.
2 changes: 1 addition & 1 deletion JLLGenerator.jl/contrib/jll_auto_upgrade_helper.jl
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ mktempdir() do dir
global deps = []
for (name, uuid) in project["deps"]
# Drop default dependencies `JLLWrappers`, `Artifacts` and `Libdl`, these are implicit.
if name ("JLLWrappers", "Artifacts", "Libdl", "Pkg")
if name ("JLLWrappers2", "JLLWrappers", "Artifacts", "Libdl", "Pkg")
continue
end
push!(deps, (
Expand Down
8 changes: 2 additions & 6 deletions JLLGenerator.jl/src/JLLGenerator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -612,16 +612,12 @@ function generate_jll(out_dir::String, info::JLLInfo; clear::Bool = true, build_
"version" => string(info.version),
# We'll add either `Pkg` or `Artifacts` to this list, depending on the `julia_compat`.
"deps" => Dict{String,Any}(
"JLLWrappers" => "692b3bcd-3c85-4b1f-b108-f13ce0eb3210",
"JLLWrappers2" => "21706172-204c-4d4f-5420-656854206f44",
"Libdl" => "8f399da3-3557-5675-b5ff-fb832c97cbdb",
),

# We require at least JLLWrappers 2.0+, as that's when we implemented
# this whole TOML loading business. Note that the user can still override
# this (likely to their detriment) by putting an explicit entry for
# `JLLWrappers` in their `deps` field.
"compat" => Dict{String,Any}(
"JLLWrappers" => "2.0.0",
"JLLWrappers2" => "1.0.0",
"julia" => info.julia_compat,
)
)
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "JLLWrappers"
uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210"
authors = ["Mosè Giordano", "Elliot Saba"]
version = "2.0.0"
name = "LazyJLLWrappers"
uuid = "21706172-204c-4d4f-5420-656854206f44"
authors = ["Elliot Saba"]
version = "1.0.0"

[deps]
Artifacts = "56f22d72-fd6d-98f1-02f0-08ddc0907c33"
Expand Down
4 changes: 2 additions & 2 deletions JLLWrappers.jl/README.md → LazyJLLWrappers.jl/README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# JLLWrappers.jl
# LazyJLLWrappers.jl

This package exports a macro, `@generate_jll_from_toml()` that generates a [JLL wrapper package](https://docs.binarybuilder.org/stable/jll/) from a TOML file generated by [`JLLGenerator.jl`](https://github.com/JuliaPackaging/BB2.jl/tree/main/JLLGenerator.jl).
Example:

```
module Foo_jll
using JLLWrappers
using LazyJLLWrappers
@generate_jll_from_toml()
end
```
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ function executable_product_definition(jb::JLLBlocks, artifact, product)
push!(jb.top_level_blocks, quote
function $(var_name)(; adjust_PATH::Bool = true, adjust_LIBPATH::Bool = true)
env = Base.invokelatest(
JLLWrappers.adjust_ENV!,
LazyJLLWrappers.adjust_ENV!,
copy(ENV),
PATH[],
LIBPATH[],
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,10 @@ end

function top_level_statements(jb::JLLBlocks, artifact, platform)
if VERSION >= v"1.6.0"
push!(jb.top_level_blocks, :(using Libdl, JLLWrappers, Artifacts))
push!(jb.top_level_blocks, :(using Libdl, LazyJLLWrappers, Artifacts))
elseif VERSION >= v"1.3.0-rc4"
# Use slower Pkg-based artifacts
push!(jb.top_level_blocks, :(using Libdl, JLLWrappers, Pkg.Artifacts))
push!(jb.top_level_blocks, :(using Libdl, LazyJLLWrappers, Pkg.Artifacts))
else
error("Unable to use $(src_name)_jll on Julia versions older than 1.3!")
end
Expand Down Expand Up @@ -119,6 +119,31 @@ function top_level_statements(jb::JLLBlocks, artifact, platform)
push!(jb.top_level_blocks, emit_typed_global(:platform, typeof(platform), platform; isconst=true))
end

"""
build_eager_mode(jb, deps, lib_products)
In order to be compatible with JLLWrappers (the old version) we need to
support a way to force all libraries to load eagerly so that downstream
JLLs are able to make use of our libraries. This method will define an
`eager_mode()` function that ensures that all libraries in this JLL are
dlopen()'ed and ready for use. Old JLLWrappers will then call
`eager_mode()` on all dependencies to ensure that they are available.
"""
function build_eager_mode(jb::JLLBlocks, lib_products)
statements = Expr[]
# For every library in `lib_products`, open it!
for lib in lib_products
_, path_var_name, _ = product_names(lib)
push!(statements, :(dlopen($(path_var_name))))
end

push!(jb.top_level_blocks, quote
function eager_mode()
$(statements...)
end
end)
end


function emit_typed_global(name, type, val; isconst::Bool = false)
# On Julia v1.9+ we can type-annotate global variables, which provides slightly
Expand Down Expand Up @@ -214,6 +239,6 @@ function init_footer(jb::JLLBlocks, artifact)
unique!(PATH_list)
unique!(LIBPATH_list)
PATH[] = join(PATH_list, $(pathsep))
LIBPATH[] = join(vcat(LIBPATH_list, Base.invokelatest(JLLWrappers.get_julia_libpaths))::Vector{String}, $(pathsep))
LIBPATH[] = join(vcat(LIBPATH_list, Base.invokelatest(LazyJLLWrappers.get_julia_libpaths))::Vector{String}, $(pathsep))
end)
end
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module JLLWrappers
module LazyJLLWrappers

@warn("TODO: Remove JLLGenerator from the deps, it should be a test-only dependency")

Expand Down Expand Up @@ -171,6 +171,11 @@ macro generate_jll_from_toml()
for product in lib_products
library_product_definition(jb, artifact, product)
end

# Also, create our `eager_mode()` function body which will open all of our
# libraries and tell all of our dependencies to open their libraries too.
# This allows these packages to co-exist with the old `JLLWrappers`
build_eager_mode(jb, artifact["deps"], lib_products)

# Next all the other products
for product in artifact["products"]
Expand All @@ -195,4 +200,4 @@ macro generate_jll_from_toml()
return synthesize(jb)
end

end # module JLLWrappers
end # module LazyJLLWrappers
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
# TODO: Create a testing JLL that has all our different kinds of products, uses init blocks, etc...
# Use that to test this package here.
using JLLWrappers, Pkg, Test, JLLGenerator, Preferences
using LazyJLLWrappers, Pkg, Test, JLLGenerator, Preferences

# For more debugging info, set `io = stdout`
function generate_and_load_jll(jllinfo, test_code::String;
Expand All @@ -12,7 +10,7 @@ function generate_and_load_jll(jllinfo, test_code::String;
JLLGenerator.generate_jll(dir, jllinfo)
Pkg.activate(dir) do
Preferences.set_preferences!("$(jllinfo.name)_jll", pairs(extra_preferences)...)
# Ensure we're using the current version of JLLWrappers.jl
# Ensure we're using the current version of LazyJLLWrappers.jl
Pkg.develop(;path=dirname(@__DIR__), io)
Pkg.instantiate(;io)
end
Expand Down

0 comments on commit a5e52fd

Please sign in to comment.