Skip to content

Commit c626955

Browse files
timholyKeno
authored andcommitted
Make __precompile__(false) non-fatal to cachecompile
And make it equivalent to `exit(125)` Fixes #28384
1 parent b0bf91e commit c626955

File tree

2 files changed

+43
-30
lines changed

2 files changed

+43
-30
lines changed

base/loading.jl

+37-22
Original file line numberDiff line numberDiff line change
@@ -918,7 +918,6 @@ function _require(pkg::PkgId)
918918
try
919919
toplevel_load[] = false
920920
# perform the search operation to select the module file require intends to load
921-
name = pkg.name
922921
path = locate_package(pkg)
923922
if path === nothing
924923
throw(ArgumentError("""
@@ -939,8 +938,8 @@ function _require(pkg::PkgId)
939938
# but it was not handled by the precompile loader, complain
940939
for (concrete_pkg, concrete_build_id) in _concrete_dependencies
941940
if pkg == concrete_pkg
942-
@warn """Module $name with build ID $concrete_build_id is missing from the cache.
943-
This may mean module $name does not support precompilation but is imported by a module that does."""
941+
@warn """Module $(pkg.name) with build ID $concrete_build_id is missing from the cache.
942+
This may mean $pkg does not support precompilation but is imported by a module that does."""
944943
if JLOptions().incremental != 0
945944
# during incremental precompilation, this should be fail-fast
946945
throw(PrecompilableError())
@@ -952,14 +951,19 @@ function _require(pkg::PkgId)
952951
if (0 == ccall(:jl_generating_output, Cint, ())) || (JLOptions().incremental != 0)
953952
# spawn off a new incremental pre-compile task for recursive `require` calls
954953
# or if the require search declared it was pre-compiled before (and therefore is expected to still be pre-compilable)
955-
cachefile = compilecache(pkg)
956-
m = _require_from_serialized(cachefile)
957-
if isa(m, Exception)
958-
if !precompilableerror(m)
959-
@warn "The call to compilecache failed to create a usable precompiled cache file for module $name" exception=m
954+
cachefile = compilecache(pkg, path)
955+
if isa(cachefile, Exception)
956+
if !precompilableerror(cachefile)
957+
@warn "The call to compilecache failed to create a usable precompiled cache file for $pkg" exception=m
960958
end
959+
# fall-through to loading the file locally
961960
else
962-
return
961+
m = _require_from_serialized(cachefile)
962+
if isa(m, Exception)
963+
@warn "The call to compilecache failed to create a usable precompiled cache file for $pkg" exception=m
964+
else
965+
return
966+
end
963967
end
964968
end
965969
end
@@ -1108,18 +1112,18 @@ function create_expr_cache(input::String, output::String, concrete_deps::typeof(
11081112
in = io.in
11091113
try
11101114
write(in, """
1111-
begin
1112-
$(Base.load_path_setup_code())
1113-
Base._track_dependencies[] = true
1114-
empty!(Base._concrete_dependencies)
1115-
""")
1115+
begin
1116+
$(Base.load_path_setup_code())
1117+
Base._track_dependencies[] = true
1118+
Base.empty!(Base._concrete_dependencies)
1119+
""")
11161120
for (pkg, build_id) in concrete_deps
11171121
pkg_str = if pkg.uuid === nothing
11181122
"Base.PkgId($(repr(pkg.name)))"
11191123
else
11201124
"Base.PkgId(Base.UUID(\"$(pkg.uuid)\"), $(repr(pkg.name)))"
11211125
end
1122-
write(in, "push!(Base._concrete_dependencies, $pkg_str => $(repr(build_id)))\n")
1126+
write(in, "Base.push!(Base._concrete_dependencies, $pkg_str => $(repr(build_id)))\n")
11231127
end
11241128
write(io, "end\0")
11251129
uuid_tuple = uuid === nothing ? (0, 0) : convert(NTuple{2, UInt64}, uuid)
@@ -1128,7 +1132,14 @@ function create_expr_cache(input::String, output::String, concrete_deps::typeof(
11281132
if source !== nothing
11291133
write(in, "task_local_storage()[:SOURCE_PATH] = $(repr(source))\0")
11301134
end
1131-
write(in, "Base.include(Base.__toplevel__, $(repr(abspath(input))))\0")
1135+
write(in, """
1136+
try
1137+
Base.include(Base.__toplevel__, $(repr(abspath(input))))
1138+
catch ex
1139+
Base.precompilableerror(ex) || Base.rethrow(ex)
1140+
Base.@debug "Aborting `createexprcache'" exception=(Base.ErrorException("Declaration of __precompile__(false) not allowed"), Base.catch_backtrace())
1141+
Base.exit(125) # we define status = 125 means PrecompileableError
1142+
end\0""")
11321143
# TODO: cleanup is probably unnecessary here
11331144
if source !== nothing
11341145
write(in, "delete!(task_local_storage(), :SOURCE_PATH)\0")
@@ -1152,10 +1163,11 @@ This can be used to reduce package load times. Cache files are stored in
11521163
for important notes.
11531164
"""
11541165
function compilecache(pkg::PkgId)
1155-
# decide where to get the source file from
1156-
name = pkg.name
11571166
path = locate_package(pkg)
11581167
path === nothing && throw(ArgumentError("$pkg not found during precompilation"))
1168+
return compilecache(pkg, path)
1169+
end
1170+
function compilecache(pkg::PkgId, path::String)
11591171
# decide where to put the resulting cache file
11601172
cachefile = abspath(DEPOT_PATH[1], cache_file_entry(pkg))
11611173
cachepath = dirname(cachefile)
@@ -1170,17 +1182,20 @@ function compilecache(pkg::PkgId)
11701182
# run the expression and cache the result
11711183
verbosity = isinteractive() ? CoreLogging.Info : CoreLogging.Debug
11721184
if isfile(cachefile)
1173-
@logmsg verbosity "Recompiling stale cache file $cachefile for module $name"
1185+
@logmsg verbosity "Recompiling stale cache file $cachefile for $pkg"
11741186
else
1175-
@logmsg verbosity "Precompiling module $name"
1187+
@logmsg verbosity "Precompiling $pkg"
11761188
end
1177-
if success(create_expr_cache(path, cachefile, concrete_deps, pkg.uuid))
1189+
p = create_expr_cache(path, cachefile, concrete_deps, pkg.uuid)
1190+
if success(p)
11781191
# append checksum to the end of the .ji file:
11791192
open(cachefile, "a+") do f
11801193
write(f, _crc32c(seekstart(f)))
11811194
end
1195+
elseif p.exitcode == 125
1196+
return PrecompilableError()
11821197
else
1183-
error("Failed to precompile $name to $cachefile.")
1198+
error("Failed to precompile $pkg to $cachefile.")
11841199
end
11851200
return cachefile
11861201
end

test/precompile.jl

+6-8
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ try
2424

2525
write(FooBase_file,
2626
"""
27+
false && __precompile__(false)
2728
module $FooBase_module
2829
import Base: hash, >
2930
struct fmpz end
@@ -279,18 +280,15 @@ try
279280
Baz_file = joinpath(dir, "Baz.jl")
280281
write(Baz_file,
281282
"""
282-
__precompile__(false)
283+
true && __precompile__(false)
283284
module Baz
285+
baz() = 1
284286
end
285287
""")
286288

287-
@test_warn "ERROR: LoadError: Declaring __precompile__(false) is not allowed in files that are being precompiled.\nStacktrace:\n [1] __precompile__" try
288-
Base.compilecache(Base.PkgId("Baz")) # from __precompile__(false)
289-
error("__precompile__ disabled test failed")
290-
catch exc
291-
isa(exc, ErrorException) || rethrow(exc)
292-
occursin("__precompile__(false)", exc.msg) && rethrow(exc)
293-
end
289+
@test Base.compilecache(Base.PkgId("Baz")) == Base.PrecompilableError() # due to __precompile__(false)
290+
@eval using Baz
291+
@test Base.invokelatest(Baz.baz) == 1
294292

295293
# Issue #12720
296294
FooBar1_file = joinpath(dir, "FooBar1.jl")

0 commit comments

Comments
 (0)