Skip to content

Commit de49c5a

Browse files
committed
In Julia 1.12+, use the BuildSettings mechanism to pass the list of sysimages to include in the fresh (non-incremental) base sysimage
1 parent 951dc0f commit de49c5a

File tree

1 file changed

+44
-16
lines changed

1 file changed

+44
-16
lines changed

src/PackageCompiler.jl

+44-16
Original file line numberDiff line numberDiff line change
@@ -210,14 +210,22 @@ function get_julia_cmd()
210210
end
211211
end
212212

213+
function generate_sysimg_jl_contents()
214+
original_sysimg_source_path = Base.find_source_file("sysimg.jl")
215+
original_sysimg_content = read(sysimg_source_path, String)
216+
if VERSION >= v"1.12-"
217+
# In Julia 1.12+, we use BuildSettings, and thus we don't need to rewrite sysimg.jl
218+
# to change the list of stdlibs.
219+
new_sysimage_content = original_sysimg_content
220+
else
221+
# Julia 1.11 and earlier do not support BuildSettings.
222+
# So we need to rewrite sysimg.jl to change the list of stdlibs.
213223

214-
function rewrite_sysimg_jl_only_needed_stdlibs(stdlibs::Vector{String})
215-
sysimg_source_path = Base.find_source_file("sysimg.jl")
216-
sysimg_content = read(sysimg_source_path, String)
217-
# replaces the hardcoded list of stdlibs in sysimg.jl with
218-
# the stdlibs that is given as argument
219-
return replace(sysimg_content,
220-
r"stdlibs = \[(.*?)\]"s => string("stdlibs = [", join(":" .* stdlibs, ",\n"), "]"))
224+
# Replaces the hardcoded list of stdlibs in sysimg.jl with
225+
# the stdlibs that is given as argument
226+
new_sysimg_content = replace(sysimg_content, r"stdlibs = \[(.*?)\]"s => string("stdlibs = [", join(":" .* stdlibs, ",\n"), "]"))
227+
end
228+
return new_sysimg_content
221229
end
222230

223231
function create_fresh_base_sysimage(stdlibs::Vector{String}; cpu_target::String, sysimage_build_args::Cmd)
@@ -237,7 +245,7 @@ function create_fresh_base_sysimage(stdlibs::Vector{String}; cpu_target::String,
237245
# we can't strip the IR from the base sysimg, so we filter out this flag
238246
# also presumably `--compile=all` and maybe a few others we missed here...
239247
sysimage_build_args_strs = map(p -> "$(p...)", values(sysimage_build_args))
240-
filter!(p -> !contains(p, "--compile") && p ̸ ("--strip-ir",), sysimage_build_args_strs)
248+
filter!(p -> !contains(p, "--compile") && p ("--strip-ir",), sysimage_build_args_strs)
241249
sysimage_build_args = Cmd(sysimage_build_args_strs)
242250

243251
cd(base_dir) do
@@ -254,21 +262,41 @@ function create_fresh_base_sysimage(stdlibs::Vector{String}; cpu_target::String,
254262

255263
spinner = TerminalSpinners.Spinner(msg = "PackageCompiler: compiling fresh sysimage (incremental=false)")
256264
TerminalSpinners.@spin spinner begin
257-
# Use that to create sys.ji
258-
new_sysimage_content = rewrite_sysimg_jl_only_needed_stdlibs(stdlibs)
265+
new_sysimage_content = generate_sysimg_jl_contents(stdlibs)
259266
new_sysimage_content *= "\nempty!(Base.atexit_hooks)\n"
260267
new_sysimage_source_path = joinpath(tmp, "sysimage_packagecompiler_$(uuid1()).jl")
261268
write(new_sysimage_source_path, new_sysimage_content)
262-
try
263-
# The final positional argument of "" is to pass BUILDROOT="" to Base.jl.
264-
# In Julia 1.11 and earlier, this positional argument will be ignored.
265-
# In Julia 1.12 and later, this positional argument will be picked up by Base.jl,
266-
# and Base.jl will set Base.BUILDROOT to "".
269+
270+
if VERSION >= v"1.12-"
271+
build_settings_source_path = joinpath(tmp, "buildsettings_packagecompiler_$(uuid1()).jl")
272+
open(build_settings_source_path, "w") do io
273+
stdlibs_string =
274+
println(io, "INCLUDE_STDLIBS = \"FileWatching,Libdl,Artifacts,SHA,Sockets,LinearAlgebra,Random\")"
275+
end
276+
277+
# The second positional argument `""` is to pass BUILDROOT="" to Base.jl.
278+
# If we don't have the "", then Base.jl will assume that one of our other
279+
# arguments is the BUILDROOT, which obviously is incorrect.
267280
# https://github.com/JuliaLang/PackageCompiler.jl/issues/989
281+
#
282+
# The --build-settings argument is to pass our BuildSettings file.
283+
# BuildSettings is only available in Julia 1.12+
284+
# https://github.com/JuliaLang/julia/pull/54387
285+
buildsettings_args = `$new_sysimage_source_path "" --build-settings $(build_settings_source_path)`
286+
else
287+
# Julia 1.11 and earlier do not support BuildSettings.
288+
#
289+
# Julia 1.11 and earlier do not require us to pass BUILDROOT as a positional
290+
# argument.
291+
buildsettings_args = `$new_sysimage_source_path`
292+
end
293+
294+
try
295+
# Use the previously-created corecompiler.ji to create sys.ji
268296
cmd = addenv(`$(get_julia_cmd()) --cpu-target $cpu_target
269297
--sysimage=$tmp_corecompiler_ji
270298
$sysimage_build_args --output-o=$tmp_sys_o
271-
$new_sysimage_source_path ""`,
299+
$buildsettings_args`,
272300
"JULIA_LOAD_PATH" => "@stdlib")
273301
@debug "running $cmd"
274302

0 commit comments

Comments
 (0)