Skip to content

Commit 1e76111

Browse files
authored
use a function in pkg precompile instead of writing code to stdin (#36028)
1 parent f890d86 commit 1e76111

File tree

1 file changed

+55
-48
lines changed

1 file changed

+55
-48
lines changed

base/loading.jl

Lines changed: 55 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,66 +1200,73 @@ function load_path_setup_code(load_path::Bool=true)
12001200
return code
12011201
end
12021202

1203+
# this is called in the external process that generates precompiled package files
1204+
function include_package_for_output(input::String, depot_path::Vector{String}, dl_load_path::Vector{String}, load_path::Vector{String}, concrete_deps::typeof(_concrete_dependencies), uuid_tuple::NTuple{2,UInt64}, source::Union{Nothing,String})
1205+
append!(empty!(Base.DEPOT_PATH), depot_path)
1206+
append!(empty!(Base.DL_LOAD_PATH), dl_load_path)
1207+
append!(empty!(Base.LOAD_PATH), load_path)
1208+
ENV["JULIA_LOAD_PATH"] = join(load_path, Sys.iswindows() ? ';' : ':')
1209+
Base.HOME_PROJECT[] = Base.ACTIVE_PROJECT[] = nothing
1210+
Base._track_dependencies[] = true
1211+
append!(empty!(Base._concrete_dependencies), concrete_deps)
1212+
1213+
ccall(:jl_set_module_uuid, Cvoid, (Any, NTuple{2, UInt64}), Base.__toplevel__, uuid_tuple)
1214+
if source !== nothing
1215+
task_local_storage()[:SOURCE_PATH] = source
1216+
end
1217+
1218+
try
1219+
Base.include(Base.__toplevel__, input)
1220+
catch ex
1221+
precompilableerror(ex) || rethrow()
1222+
@debug "Aborting `create_expr_cache'" exception=(ErrorException("Declaration of __precompile__(false) not allowed"), catch_backtrace())
1223+
exit(125) # we define status = 125 means PrecompileableError
1224+
end
1225+
end
1226+
1227+
@assert precompile(include_package_for_output, (String,Vector{String},Vector{String},Vector{String},typeof(_concrete_dependencies),NTuple{2,UInt64},Nothing))
1228+
@assert precompile(include_package_for_output, (String,Vector{String},Vector{String},Vector{String},typeof(_concrete_dependencies),NTuple{2,UInt64},String))
1229+
12031230
function create_expr_cache(input::String, output::String, concrete_deps::typeof(_concrete_dependencies), uuid::Union{Nothing,UUID})
12041231
rm(output, force=true) # Remove file if it exists
1205-
code_object = """
1206-
while !eof(stdin)
1207-
code = readuntil(stdin, '\\0')
1208-
eval(Meta.parse(code))
1232+
depot_path = map(abspath, DEPOT_PATH)
1233+
dl_load_path = map(abspath, DL_LOAD_PATH)
1234+
load_path = map(abspath, Base.load_path())
1235+
path_sep = Sys.iswindows() ? ';' : ':'
1236+
any(path -> path_sep in path, load_path) &&
1237+
error("LOAD_PATH entries cannot contain $(repr(path_sep))")
1238+
1239+
deps_strs = String[]
1240+
for (pkg, build_id) in concrete_deps
1241+
pkg_str = if pkg.uuid === nothing
1242+
"Base.PkgId($(repr(pkg.name)))"
1243+
else
1244+
"Base.PkgId(Base.UUID(\"$(pkg.uuid)\"), $(repr(pkg.name)))"
12091245
end
1210-
"""
1246+
push!(deps_strs, "$pkg_str => $(repr(build_id))")
1247+
end
1248+
deps = repr(eltype(concrete_deps)) * "[" * join(deps_strs, ",") * "]"
1249+
1250+
uuid_tuple = uuid === nothing ? (UInt64(0), UInt64(0)) : convert(NTuple{2, UInt64}, uuid)
12111251

12121252
io = open(pipeline(`$(julia_cmd()) -O0
12131253
--output-ji $output --output-incremental=yes
12141254
--startup-file=no --history-file=no --warn-overwrite=yes
12151255
--color=$(have_color === nothing ? "auto" : have_color ? "yes" : "no")
1216-
--eval $code_object`, stderr=stderr),
1256+
--eval 'eval(Meta.parse(read(stdin,String)))'`, stderr=stderr),
12171257
"w", stdout)
1218-
in = io.in
1219-
try
1220-
write(in, """
1221-
begin
1222-
$(Base.load_path_setup_code())
1223-
Base._track_dependencies[] = true
1224-
Base.empty!(Base._concrete_dependencies)
1225-
""")
1226-
for (pkg, build_id) in concrete_deps
1227-
pkg_str = if pkg.uuid === nothing
1228-
"Base.PkgId($(repr(pkg.name)))"
1229-
else
1230-
"Base.PkgId(Base.UUID(\"$(pkg.uuid)\"), $(repr(pkg.name)))"
1231-
end
1232-
write(in, "Base.push!(Base._concrete_dependencies, $pkg_str => $(repr(build_id)))\n")
1233-
end
1234-
write(io, "end\0")
1235-
uuid_tuple = uuid === nothing ? (0, 0) : convert(NTuple{2, UInt64}, uuid)
1236-
write(in, "ccall(:jl_set_module_uuid, Cvoid, (Any, NTuple{2, UInt64}), Base.__toplevel__, $uuid_tuple)\0")
1237-
source = source_path(nothing)
1238-
if source !== nothing
1239-
write(in, "task_local_storage()[:SOURCE_PATH] = $(repr(source))\0")
1240-
end
1241-
write(in, """
1242-
try
1243-
Base.include(Base.__toplevel__, $(repr(abspath(input))))
1244-
catch ex
1245-
Base.precompilableerror(ex) || Base.rethrow()
1246-
Base.@debug "Aborting `createexprcache'" exception=(Base.ErrorException("Declaration of __precompile__(false) not allowed"), Base.catch_backtrace())
1247-
Base.exit(125) # we define status = 125 means PrecompileableError
1248-
end\0""")
1249-
# TODO: cleanup is probably unnecessary here
1250-
if source !== nothing
1251-
write(in, "delete!(task_local_storage(), :SOURCE_PATH)\0")
1252-
end
1253-
write(in, "ccall(:jl_set_module_uuid, Cvoid, (Any, NTuple{2, UInt64}), Base.__toplevel__, (0, 0))\0")
1254-
close(in)
1255-
catch
1256-
close(in)
1257-
process_running(io) && Timer(t -> kill(io), 5.0) # wait a short time before killing the process to give it a chance to clean up on its own first
1258-
rethrow()
1259-
end
1258+
# write data over stdin to avoid the (unlikely) case of exceeding max command line size
1259+
write(io.in, """
1260+
Base.include_package_for_output($(repr(abspath(input))), $(repr(depot_path)), $(repr(dl_load_path)),
1261+
$(repr(load_path)), $deps, $(repr(uuid_tuple)), $(repr(source_path(nothing))))
1262+
""")
1263+
close(io.in)
12601264
return io
12611265
end
12621266

1267+
@assert precompile(create_expr_cache, (String, String, typeof(_concrete_dependencies), Nothing))
1268+
@assert precompile(create_expr_cache, (String, String, typeof(_concrete_dependencies), UUID))
1269+
12631270
function compilecache_path(pkg::PkgId)::String
12641271
entrypath, entryfile = cache_file_entry(pkg)
12651272
cachepath = joinpath(DEPOT_PATH[1], entrypath)

0 commit comments

Comments
 (0)