Skip to content

Commit 87c83b0

Browse files
topolarityKristofferC
authored and
KristofferC
committed
Prevent pre-compilation package from triggering its own extensions (#56666)
It is possible for an extension `ExtAB` to be loadable by one of its triggers, e.g. if `A` loads `B`. However, this loading is not supposed to happen during pre-compilation of `A`. Getting this wrong means disagreeing with the scheduled pre-compile jobs (`A` is not scheduled to depend on or generate a cache file for `ExtAB` but accidentally attempts both) and leads to confusing errors about missing cache files. We used to cover up this bad behavior w/ an erroneous cycle warning (fixed by #55910), but now we need to be sure this works.
1 parent ace962e commit 87c83b0

File tree

8 files changed

+88
-1
lines changed

8 files changed

+88
-1
lines changed

base/loading.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1215,6 +1215,7 @@ function run_module_init(mod::Module, i::Int=1)
12151215
end
12161216

12171217
function run_package_callbacks(modkey::PkgId)
1218+
(modkey == precompilation_target) && return nothing
12181219
run_extension_callbacks(modkey)
12191220
assert_havelock(require_lock)
12201221
unlock(require_lock)
@@ -1338,7 +1339,7 @@ function _insert_extension_triggers(parent::PkgId, extensions::Dict{String, Any}
13381339
# TODO: Better error message if this lookup fails?
13391340
uuid_trigger = UUID(totaldeps[trigger]::String)
13401341
trigger_id = PkgId(uuid_trigger, trigger)
1341-
if !haskey(Base.loaded_modules, trigger_id) || haskey(package_locks, trigger_id)
1342+
if !haskey(Base.loaded_modules, trigger_id) || haskey(package_locks, trigger_id) || (trigger_id == precompilation_target)
13421343
trigger1 = get!(Vector{ExtensionId}, EXT_DORMITORY, trigger_id)
13431344
push!(trigger1, gid)
13441345
else
@@ -1350,6 +1351,7 @@ end
13501351

13511352
loading_extension::Bool = false
13521353
precompiling_extension::Bool = false
1354+
precompilation_target::Union{Nothing,PkgId} = nothing
13531355
function run_extension_callbacks(extid::ExtensionId)
13541356
assert_havelock(require_lock)
13551357
succeeded = try
@@ -2342,6 +2344,7 @@ function create_expr_cache(pkg::PkgId, input::String, output::String, output_o::
23422344
write(io.in, """
23432345
empty!(Base.EXT_DORMITORY) # If we have a custom sysimage with `EXT_DORMITORY` prepopulated
23442346
Base.precompiling_extension = $(loading_extension)
2347+
Base.precompilation_target = $(pkg_str(pkg))
23452348
Base.include_package_for_output($(pkg_str(pkg)), $(repr(abspath(input))), $(repr(depot_path)), $(repr(dl_load_path)),
23462349
$(repr(load_path)), $deps, $(repr(source_path(nothing))))
23472350
""")

test/loading.jl

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,6 +1101,41 @@ end
11011101
cmd_proj_ext = addenv(cmd_proj_ext, "JULIA_LOAD_PATH" => join([joinpath(proj, "HasExtensions.jl"), joinpath(proj, "EnvWithDeps")], sep))
11021102
run(cmd_proj_ext)
11031103
end
1104+
1105+
# Extensions for "parent" dependencies
1106+
# (i.e. an `ExtAB` where A depends on / loads B, but B provides the extension)
1107+
1108+
mktempdir() do depot # Parallel pre-compilation
1109+
code = """
1110+
Base.disable_parallel_precompile = false
1111+
using Parent
1112+
Base.get_extension(getfield(Parent, :DepWithParentExt), :ParentExt) isa Module || error("expected extension to load")
1113+
Parent.greet()
1114+
"""
1115+
proj = joinpath(@__DIR__, "project", "Extensions", "Parent.jl")
1116+
cmd = `$(Base.julia_cmd()) --startup-file=no -e $code`
1117+
cmd = addenv(cmd,
1118+
"JULIA_LOAD_PATH" => proj,
1119+
"JULIA_DEPOT_PATH" => depot * Base.Filesystem.pathsep(),
1120+
)
1121+
@test occursin("Hello parent!", String(read(cmd)))
1122+
end
1123+
mktempdir() do depot # Serial pre-compilation
1124+
code = """
1125+
Base.disable_parallel_precompile = true
1126+
using Parent
1127+
Base.get_extension(getfield(Parent, :DepWithParentExt), :ParentExt) isa Module || error("expected extension to load")
1128+
Parent.greet()
1129+
"""
1130+
proj = joinpath(@__DIR__, "project", "Extensions", "Parent.jl")
1131+
cmd = `$(Base.julia_cmd()) --startup-file=no -e $code`
1132+
cmd = addenv(cmd,
1133+
"JULIA_LOAD_PATH" => proj,
1134+
"JULIA_DEPOT_PATH" => depot * Base.Filesystem.pathsep(),
1135+
)
1136+
@test occursin("Hello parent!", String(read(cmd)))
1137+
end
1138+
11041139
finally
11051140
try
11061141
rm(depot_path, force=true, recursive=true)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
name = "DepWithParentExt"
2+
uuid = "8a35c396-5ffc-40d2-b7ec-e8ed2248da32"
3+
version = "0.1.0"
4+
5+
[weakdeps]
6+
Parent = "58cecb9c-f68a-426e-b92a-89d456ae7acc"
7+
8+
[extensions]
9+
ParentExt = "Parent"
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module ParentExt
2+
3+
using Parent
4+
using DepWithParentExt
5+
6+
end
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module DepWithParentExt
2+
3+
greet() = print("Hello dep w/ ext for parent dep!")
4+
5+
end # module DepWithParentExt
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# This file is machine-generated - editing it directly is not advised
2+
3+
julia_version = "1.10.6"
4+
manifest_format = "2.0"
5+
project_hash = "5d72c155f50f076d28b74de819d417878ffb0965"
6+
7+
[[deps.DepWithParentExt]]
8+
path = "../DepWithParentExt.jl"
9+
uuid = "8a35c396-5ffc-40d2-b7ec-e8ed2248da32"
10+
version = "0.1.0"
11+
12+
[deps.DepWithParentExt.extensions]
13+
ParentExt = "Parent"
14+
15+
[deps.DepWithParentExt.weakdeps]
16+
Parent = "58cecb9c-f68a-426e-b92a-89d456ae7acc"
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
name = "Parent"
2+
uuid = "58cecb9c-f68a-426e-b92a-89d456ae7acc"
3+
version = "0.1.0"
4+
5+
[deps]
6+
DepWithParentExt = "8a35c396-5ffc-40d2-b7ec-e8ed2248da32"
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module Parent
2+
3+
using DepWithParentExt
4+
5+
greet() = print("Hello parent!")
6+
7+
end # module Parent

0 commit comments

Comments
 (0)