@@ -404,11 +404,12 @@ function precompilepkgs(pkgs::Vector{String}=String[];
404
404
configs:: Union{Config,Vector{Config}} = (` ` => Base. CacheFlags ()),
405
405
io:: IO = stderr ,
406
406
# asking for timing disables fancy mode, as timing is shown in non-fancy mode
407
- fancyprint:: Bool = can_fancyprint (io) && ! timing)
407
+ fancyprint:: Bool = can_fancyprint (io) && ! timing,
408
+ ignore_loaded:: Bool = true )
408
409
# monomorphize this to avoid latency problems
409
410
_precompilepkgs (pkgs, internal_call, strict, warn_loaded, timing, _from_loading,
410
411
configs isa Vector{Config} ? configs : [configs],
411
- IOContext {IO} (io), fancyprint)
412
+ IOContext {IO} (io), fancyprint, ignore_loaded )
412
413
end
413
414
414
415
function _precompilepkgs (pkgs:: Vector{String} ,
@@ -419,7 +420,8 @@ function _precompilepkgs(pkgs::Vector{String},
419
420
_from_loading:: Bool ,
420
421
configs:: Vector{Config} ,
421
422
io:: IOContext{IO} ,
422
- fancyprint:: Bool )
423
+ fancyprint:: Bool ,
424
+ ignore_loaded:: Bool )
423
425
requested_pkgs = copy (pkgs) # for understanding user intent
424
426
425
427
time_start = time_ns ()
@@ -894,7 +896,7 @@ function _precompilepkgs(pkgs::Vector{String},
894
896
wait (was_processed[(dep,config)])
895
897
end
896
898
circular = pkg in circular_deps
897
- is_stale = ! Base. isprecompiled (pkg; ignore_loaded= true , stale_cache, cachepath_cache, cachepaths, sourcepath, flags= cacheflags)
899
+ is_stale = ! Base. isprecompiled (pkg; ignore_loaded, stale_cache, cachepath_cache, cachepaths, sourcepath, flags= cacheflags)
898
900
if ! circular && is_stale
899
901
Base. acquire (parallel_limiter)
900
902
is_direct_dep = pkg in direct_deps
@@ -920,10 +922,10 @@ function _precompilepkgs(pkgs::Vector{String},
920
922
try
921
923
# allows processes to wait if another process is precompiling a given package to
922
924
# a functionally identical package cache (except for preferences, which may differ)
923
- t = @elapsed ret = precompile_pkgs_maybe_cachefile_lock (io, print_lock, fancyprint, pkg_config, pkgspidlocked, hascolor) do
925
+ t = @elapsed ret = precompile_pkgs_maybe_cachefile_lock (io, print_lock, fancyprint, pkg_config, pkgspidlocked, hascolor, parallel_limiter, ignore_loaded ) do
924
926
Base. with_logger (Base. NullLogger ()) do
925
- # The false here means we ignore loaded modules, so precompile for a fresh session
926
- keep_loaded_modules = false
927
+ # whether to respect already loaded dependency versions
928
+ keep_loaded_modules = ! ignore_loaded
927
929
# for extensions, any extension in our direct dependencies is one we have a right to load
928
930
# for packages, we may load any extension (all possible triggers are accounted for above)
929
931
loadable_exts = haskey (exts, pkg) ? filter ((dep)-> haskey (exts, dep), depsmap[pkg]) : nothing
@@ -1008,9 +1010,11 @@ function _precompilepkgs(pkgs::Vector{String},
1008
1010
plural1 = length (configs) > 1 ? " dependency configurations" : n_loaded == 1 ? " dependency" : " dependencies"
1009
1011
plural2 = n_loaded == 1 ? " a different version is" : " different versions are"
1010
1012
plural3 = n_loaded == 1 ? " " : " s"
1013
+ plural4 = n_loaded == 1 ? " this package" : " these packages"
1011
1014
print (iostr, " \n " ,
1012
1015
color_string (string (n_loaded), Base. warn_color ()),
1013
- " $(plural1) precompiled but $(plural2) currently loaded. Restart julia to access the new version$(plural3) "
1016
+ " $(plural1) precompiled but $(plural2) currently loaded. Restart julia to access the new version$(plural3) . \
1017
+ Otherwise, loading dependents of $(plural4) may trigger further precompilation to work with the unexpected version$(plural3) ."
1014
1018
)
1015
1019
end
1016
1020
if ! isempty (precomperr_deps)
@@ -1069,7 +1073,7 @@ function _precompilepkgs(pkgs::Vector{String},
1069
1073
direct = strict ? " " : " direct "
1070
1074
err_msg = " The following $n_direct_errs $(direct) dependenc$(pluralde) failed to precompile:\n $(String (take! (err_str))) "
1071
1075
if internal_call # aka. auto-precompilation
1072
- if isinteractive () && ! get ( ENV , " CI " , false )
1076
+ if isinteractive ()
1073
1077
plural1 = length (failed_deps) == 1 ? " y" : " ies"
1074
1078
println (io, " " , color_string (" $(length (failed_deps)) " , Base. error_color ()), " dependenc$(plural1) errored." )
1075
1079
println (io, " For a report of the errors see `julia> err`. To retry use `pkg> precompile`" )
@@ -1101,7 +1105,7 @@ function _color_string(cstr::String, col::Union{Int64, Symbol}, hascolor)
1101
1105
end
1102
1106
1103
1107
# Can be merged with `maybe_cachefile_lock` in loading?
1104
- function precompile_pkgs_maybe_cachefile_lock (f, io:: IO , print_lock:: ReentrantLock , fancyprint:: Bool , pkg_config, pkgspidlocked, hascolor)
1108
+ function precompile_pkgs_maybe_cachefile_lock (f, io:: IO , print_lock:: ReentrantLock , fancyprint:: Bool , pkg_config, pkgspidlocked, hascolor, parallel_limiter :: Base.Semaphore , ignore_loaded :: Bool )
1105
1109
pkg, config = pkg_config
1106
1110
flags, cacheflags = config
1107
1111
FileWatching = Base. loaded_modules[Base. PkgId (Base. UUID (" 7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" ), " FileWatching" )]
@@ -1122,15 +1126,21 @@ function precompile_pkgs_maybe_cachefile_lock(f, io::IO, print_lock::ReentrantLo
1122
1126
! fancyprint && lock (print_lock) do
1123
1127
println (io, " " , pkg. name, _color_string (" Being precompiled by $(pkgspidlocked[pkg_config]) " , Base. info_color (), hascolor))
1124
1128
end
1125
- # wait until the lock is available
1126
- FileWatching. mkpidlock (pidfile; stale_age) do
1127
- # double-check in case the other process crashed or the lock expired
1128
- if Base. isprecompiled (pkg; ignore_loaded= true , flags= cacheflags) # don't use caches for this as the env state will have changed
1129
- return nothing # returning nothing indicates a process waited for another
1130
- else
1131
- delete! (pkgspidlocked, pkg_config)
1132
- return f () # precompile
1133
- end
1129
+ Base. release (parallel_limiter) # release so other work can be done while waiting
1130
+ try
1131
+ # wait until the lock is available
1132
+ @invokelatest Base. mkpidlock_hook (() -> begin
1133
+ # double-check in case the other process crashed or the lock expired
1134
+ if Base. isprecompiled (pkg; ignore_loaded, flags= cacheflags) # don't use caches for this as the env state will have changed
1135
+ return nothing # returning nothing indicates a process waited for another
1136
+ else
1137
+ delete! (pkgspidlocked, pkg_config)
1138
+ Base. acquire (f, parallel_limiter) # precompile
1139
+ end
1140
+ end ,
1141
+ pidfile; stale_age)
1142
+ finally
1143
+ Base. acquire (parallel_limiter) # re-acquire so the outer release is balanced
1134
1144
end
1135
1145
end
1136
1146
return cachefile
0 commit comments