Skip to content

Commit

Permalink
add Base.isprecompiled(pkg::PkgId) (#50218)
Browse files Browse the repository at this point in the history
  • Loading branch information
IanButterworth authored Jun 29, 2023
1 parent 5db930e commit f6f3553
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 1 deletion.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ New library functions
* `fourthroot(x)` is now defined in `Base.Math` and can be used to compute the fourth root of `x`.
It can also be accessed using the unicode character ``, which can be typed by `\fourthroot<tab>` ([#48899]).
* `Libc.memmove`, `Libc.memset`, and `Libc.memcpy` are now defined, whose functionality matches that of their respective C calls.
* `Base.isprecompiled(pkg::PkgId)` to identify whether a package has already been precompiled ([#50218]).

New library features
--------------------
Expand Down
59 changes: 59 additions & 0 deletions base/loading.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1364,6 +1364,65 @@ end

# End extensions

# should sync with the types of arguments of `stale_cachefile`
const StaleCacheKey = Tuple{Base.PkgId, UInt128, String, String}

"""
Base.isprecompiled(pkg::PkgId; ignore_loaded::Bool=false)
Returns whether a given PkgId within the active project is precompiled.
By default this check observes the same approach that code loading takes
with respect to when different versions of dependencies are currently loaded
to that which is expected. To ignore loaded modules and answer as if in a
fresh julia session specify `ignore_loaded=true`.
!!! compat "Julia 1.10"
This function requires at least Julia 1.10.
"""
function isprecompiled(pkg::PkgId;
ignore_loaded::Bool=false,
stale_cache::Dict{StaleCacheKey,Bool}=Dict{StaleCacheKey, Bool}(),
cachepaths::Vector{String}=Base.find_all_in_cache_path(pkg),
sourcepath::Union{String,Nothing}=Base.locate_package(pkg)
)
isnothing(sourcepath) && error("Cannot locate source for $(repr(pkg))")
for path_to_try in cachepaths
staledeps = stale_cachefile(sourcepath, path_to_try, ignore_loaded = true)
if staledeps === true
continue
end
staledeps, _ = staledeps::Tuple{Vector{Any}, Union{Nothing, String}}
# finish checking staledeps module graph
for i in 1:length(staledeps)
dep = staledeps[i]
dep isa Module && continue
modpath, modkey, modbuild_id = dep::Tuple{String, PkgId, UInt128}
modpaths = find_all_in_cache_path(modkey)
for modpath_to_try in modpaths::Vector{String}
stale_cache_key = (modkey, modbuild_id, modpath, modpath_to_try)::StaleCacheKey
if get!(() -> stale_cachefile(stale_cache_key...; ignore_loaded) === true,
stale_cache, stale_cache_key)
continue
end
@goto check_next_dep
end
@goto check_next_path
@label check_next_dep
end
try
# update timestamp of precompilation file so that it is the first to be tried by code loading
touch(path_to_try)
catch ex
# file might be read-only and then we fail to update timestamp, which is fine
ex isa IOError || rethrow()
end
return true
@label check_next_path
end
return false
end

# loads a precompile cache file, after checking stale_cachefile tests
function _tryrequire_from_serialized(modkey::PkgId, build_id::UInt128)
assert_havelock(require_lock)
Expand Down
1 change: 1 addition & 0 deletions doc/src/base/base.md
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,7 @@ Base.identify_package
Base.locate_package
Base.require
Base.compilecache
Base.isprecompiled
```

## Internals
Expand Down
5 changes: 4 additions & 1 deletion test/precompile.jl
Original file line number Diff line number Diff line change
Expand Up @@ -655,7 +655,10 @@ precompile_test_harness("code caching") do dir
precompile(getelsize, (Vector{Int32},))
end
""")
Base.compilecache(Base.PkgId(string(Cache_module)))
pkgid = Base.PkgId(string(Cache_module))
@test !Base.isprecompiled(pkgid)
Base.compilecache(pkgid)
@test Base.isprecompiled(pkgid)
@eval using $Cache_module
M = getfield(@__MODULE__, Cache_module)
# Test that this cache file "owns" all the roots
Expand Down

0 comments on commit f6f3553

Please sign in to comment.