Skip to content

Commit 78351b5

Browse files
Use Base parallel precompilation to build stdlibs (#53598)
Follow-on from #53403 This extends `Base.Precompilation.precompilepkgs` to take a list of configurations to precompile each package with, while parallelizing across all packages and configurations, and uses it to build the stdlib pkgimages. It simplifies the stdlib pkgimage build process but is (currently) dependent on having an accurately resolved Manifest.toml (Project.toml included to make the manifest easier to make). Any new/removed stdlibs or changes their dependencies will require updating the Manifest.toml. It's a bit chicken and egg, but should be manageable with manual editing of the Manifest.toml. In terms of speed improvement: MacOS aarch64 CI runner 6m19s before, 5m19 with this Note that CI builds will show the basic print with timing of each package, whereas local build will be the tidier fancy print without timings. Co-authored-by: Valentin Churavy <[email protected]>
1 parent a998082 commit 78351b5

9 files changed

+589
-291
lines changed

Makefile

+2-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ julia-debug julia-release : julia-% : julia-sysimg-% julia-src-% julia-symlink j
112112
julia-libccalllazyfoo julia-libccalllazybar julia-libllvmcalltest julia-base-cache
113113

114114
stdlibs-cache-release stdlibs-cache-debug : stdlibs-cache-% : julia-%
115-
@$(MAKE) $(QUIET_MAKE) -C $(BUILDROOT) -f pkgimage.mk all-$*
115+
@$(MAKE) $(QUIET_MAKE) -C $(BUILDROOT) -f pkgimage.mk $*
116116

117117
debug release : % : julia-% stdlibs-cache-%
118118

@@ -588,6 +588,7 @@ clean: | $(CLEAN_TARGETS)
588588
@-$(MAKE) -C $(BUILDROOT)/cli clean
589589
@-$(MAKE) -C $(BUILDROOT)/test clean
590590
@-$(MAKE) -C $(BUILDROOT)/stdlib clean
591+
@-$(MAKE) -C $(BUILDROOT) -f pkgimage.mk clean
591592
-rm -f $(BUILDROOT)/julia
592593
-rm -f $(BUILDROOT)/*.tar.gz
593594
-rm -f $(build_depsbindir)/stringreplace \

base/loading.jl

+26-7
Original file line numberDiff line numberDiff line change
@@ -1524,7 +1524,21 @@ function CacheFlags(f::UInt8)
15241524
CacheFlags(use_pkgimages, debug_level, check_bounds, inline, opt_level)
15251525
end
15261526
CacheFlags(f::Int) = CacheFlags(UInt8(f))
1527-
CacheFlags() = CacheFlags(ccall(:jl_cache_flags, UInt8, ()))
1527+
function CacheFlags(cf::CacheFlags=CacheFlags(ccall(:jl_cache_flags, UInt8, ()));
1528+
use_pkgimages::Union{Nothing,Bool}=nothing,
1529+
debug_level::Union{Nothing,Int}=nothing,
1530+
check_bounds::Union{Nothing,Int}=nothing,
1531+
inline::Union{Nothing,Bool}=nothing,
1532+
opt_level::Union{Nothing,Int}=nothing
1533+
)
1534+
return CacheFlags(
1535+
use_pkgimages === nothing ? cf.use_pkgimages : use_pkgimages,
1536+
debug_level === nothing ? cf.debug_level : debug_level,
1537+
check_bounds === nothing ? cf.check_bounds : check_bounds,
1538+
inline === nothing ? cf.inline : inline,
1539+
opt_level === nothing ? cf.opt_level : opt_level
1540+
)
1541+
end
15281542

15291543
function _cacheflag_to_uint8(cf::CacheFlags)::UInt8
15301544
f = UInt8(0)
@@ -2768,7 +2782,7 @@ function compilecache_dir(pkg::PkgId)
27682782
return joinpath(DEPOT_PATH[1], entrypath)
27692783
end
27702784

2771-
function compilecache_path(pkg::PkgId, prefs_hash::UInt64; project::String=something(Base.active_project(), ""))::String
2785+
function compilecache_path(pkg::PkgId, prefs_hash::UInt64; flags::CacheFlags=CacheFlags(), project::String=something(Base.active_project(), ""))::String
27722786
entrypath, entryfile = cache_file_entry(pkg)
27732787
cachepath = joinpath(DEPOT_PATH[1], entrypath)
27742788
isdir(cachepath) || mkpath(cachepath)
@@ -2778,7 +2792,7 @@ function compilecache_path(pkg::PkgId, prefs_hash::UInt64; project::String=somet
27782792
crc = _crc32c(project)
27792793
crc = _crc32c(unsafe_string(JLOptions().image_file), crc)
27802794
crc = _crc32c(unsafe_string(JLOptions().julia_bin), crc)
2781-
crc = _crc32c(ccall(:jl_cache_flags, UInt8, ()), crc)
2795+
crc = _crc32c(_cacheflag_to_uint8(flags), crc)
27822796

27832797
cpu_target = get(ENV, "JULIA_CPU_TARGET", nothing)
27842798
if cpu_target === nothing
@@ -2810,7 +2824,8 @@ end
28102824
const MAX_NUM_PRECOMPILE_FILES = Ref(10)
28112825

28122826
function compilecache(pkg::PkgId, path::String, internal_stderr::IO = stderr, internal_stdout::IO = stdout,
2813-
keep_loaded_modules::Bool = true; flags::Cmd=``, reasons::Union{Dict{String,Int},Nothing}=Dict{String,Int}())
2827+
keep_loaded_modules::Bool = true; flags::Cmd=``, cacheflags::CacheFlags=CacheFlags(),
2828+
reasons::Union{Dict{String,Int},Nothing}=Dict{String,Int}())
28142829

28152830
@nospecialize internal_stderr internal_stdout
28162831
# decide where to put the resulting cache file
@@ -2859,7 +2874,7 @@ function compilecache(pkg::PkgId, path::String, internal_stderr::IO = stderr, in
28592874
# Read preferences hash back from .ji file (we can't precompute because
28602875
# we don't actually know what the list of compile-time preferences are without compiling)
28612876
prefs_hash = preferences_hash(tmppath)
2862-
cachefile = compilecache_path(pkg, prefs_hash)
2877+
cachefile = compilecache_path(pkg, prefs_hash; flags=cacheflags)
28632878
ocachefile = cache_objects ? ocachefile_from_cachefile(cachefile) : nothing
28642879

28652880
# append checksum for so to the end of the .ji file:
@@ -3408,7 +3423,7 @@ global parse_pidfile_hook
34083423
# The preferences hash is only known after precompilation so just assume no preferences.
34093424
# Also ignore the active project, which means that if all other conditions are equal,
34103425
# the same package cannot be precompiled from different projects and/or different preferences at the same time.
3411-
compilecache_pidfile_path(pkg::PkgId) = compilecache_path(pkg, UInt64(0); project="") * ".pidfile"
3426+
compilecache_pidfile_path(pkg::PkgId; flags::CacheFlags=CacheFlags()) = compilecache_path(pkg, UInt64(0); project="", flags) * ".pidfile"
34123427

34133428
const compilecache_pidlock_stale_age = 10
34143429

@@ -3536,12 +3551,16 @@ end
35363551
M = root_module(req_key)
35373552
if PkgId(M) == req_key && module_build_id(M) === req_build_id
35383553
depmods[i] = M
3554+
elseif M == Core
3555+
@debug "Rejecting cache file $cachefile because it was made with a different julia version"
3556+
record_reason(reasons, "wrong julia version")
3557+
return true # Won't be able to fulfill dependency
35393558
elseif ignore_loaded || !stalecheck
35403559
# Used by Pkg.precompile given that there it's ok to precompile different versions of loaded packages
35413560
@goto locate_branch
35423561
else
35433562
@debug "Rejecting cache file $cachefile because module $req_key is already loaded and incompatible."
3544-
record_reason(reasons, req_key == PkgId(Core) ? "wrong julia version" : "wrong dep version loaded")
3563+
record_reason(reasons, "wrong dep version loaded")
35453564
return true # Won't be able to fulfill dependency
35463565
end
35473566
else

0 commit comments

Comments
 (0)