@@ -1678,25 +1678,13 @@ end
16781678# should sync with the types of arguments of `stale_cachefile`
16791679const StaleCacheKey = Tuple{Base. PkgId, UInt128, String, String}
16801680
1681- """
1682- Base.isprecompiled(pkg::PkgId; ignore_loaded::Bool=false)
1683-
1684- Returns whether a given PkgId within the active project is precompiled.
1685-
1686- By default this check observes the same approach that code loading takes
1687- with respect to when different versions of dependencies are currently loaded
1688- to that which is expected. To ignore loaded modules and answer as if in a
1689- fresh julia session specify `ignore_loaded=true`.
1690-
1691- !!! compat "Julia 1.10"
1692- This function requires at least Julia 1.10.
1693- """
1694- function isprecompiled (pkg:: PkgId ;
1681+ function compilecache_path (pkg:: PkgId ;
16951682 ignore_loaded:: Bool = false ,
16961683 stale_cache:: Dict{StaleCacheKey,Bool} = Dict {StaleCacheKey, Bool} (),
16971684 cachepaths:: Vector{String} = Base. find_all_in_cache_path (pkg),
16981685 sourcepath:: Union{String,Nothing} = Base. locate_package (pkg),
16991686 flags:: CacheFlags = CacheFlags ())
1687+ path = nothing
17001688 isnothing (sourcepath) && error (" Cannot locate source for $(repr (" text/plain" , pkg)) " )
17011689 for path_to_try in cachepaths
17021690 staledeps = stale_cachefile (sourcepath, path_to_try, ignore_loaded = true , requested_flags= flags)
@@ -1728,10 +1716,64 @@ function isprecompiled(pkg::PkgId;
17281716 # file might be read-only and then we fail to update timestamp, which is fine
17291717 ex isa IOError || rethrow ()
17301718 end
1731- return true
1719+ path = path_to_try
1720+ break
17321721 @label check_next_path
17331722 end
1734- return false
1723+ return path
1724+ end
1725+
1726+ """
1727+ Base.isprecompiled(pkg::PkgId; ignore_loaded::Bool=false)
1728+
1729+ Returns whether a given PkgId within the active project is precompiled.
1730+
1731+ By default this check observes the same approach that code loading takes
1732+ with respect to when different versions of dependencies are currently loaded
1733+ to that which is expected. To ignore loaded modules and answer as if in a
1734+ fresh julia session specify `ignore_loaded=true`.
1735+
1736+ !!! compat "Julia 1.10"
1737+ This function requires at least Julia 1.10.
1738+ """
1739+ function isprecompiled (pkg:: PkgId ;
1740+ ignore_loaded:: Bool = false ,
1741+ stale_cache:: Dict{StaleCacheKey,Bool} = Dict {StaleCacheKey, Bool} (),
1742+ cachepaths:: Vector{String} = Base. find_all_in_cache_path (pkg),
1743+ sourcepath:: Union{String,Nothing} = Base. locate_package (pkg),
1744+ flags:: CacheFlags = CacheFlags ())
1745+ path = compilecache_path (pkg; ignore_loaded, stale_cache, cachepaths, sourcepath, flags)
1746+ return ! isnothing (path)
1747+ end
1748+
1749+ """
1750+ Base.isrelocatable(pkg::PkgId)
1751+
1752+ Returns whether a given PkgId within the active project is precompiled and the
1753+ associated cache is relocatable.
1754+
1755+ !!! compat "Julia 1.11"
1756+ This function requires at least Julia 1.11.
1757+ """
1758+ function isrelocatable (pkg:: PkgId )
1759+ path = compilecache_path (pkg)
1760+ isnothing (path) && return false
1761+ io = open (path, " r" )
1762+ try
1763+ iszero (isvalid_cache_header (io)) && throw (ArgumentError (" Invalid header in cache file $cachefile ." ))
1764+ _, (includes, includes_srcfiles, _), _... = _parse_cache_header (io, path)
1765+ for inc in includes
1766+ ! startswith (inc. filename, " @depot" ) && return false
1767+ if inc ∉ includes_srcfiles
1768+ # its an include_dependency
1769+ track_content = inc. mtime == - 1.0
1770+ track_content || return false
1771+ end
1772+ end
1773+ finally
1774+ close (io)
1775+ end
1776+ return true
17351777end
17361778
17371779# search for a precompile cache file to load, after some various checks
@@ -3064,7 +3106,7 @@ function resolve_depot(inc::AbstractString)
30643106end
30653107
30663108
3067- function parse_cache_header (f:: IO , cachefile:: AbstractString )
3109+ function _parse_cache_header (f:: IO , cachefile:: AbstractString )
30683110 flags = read (f, UInt8)
30693111 modules = Vector {Pair{PkgId, UInt64}} ()
30703112 while true
@@ -3148,6 +3190,13 @@ function parse_cache_header(f::IO, cachefile::AbstractString)
31483190
31493191 srcfiles = srctext_files (f, srctextpos, includes)
31503192
3193+ return modules, (includes, srcfiles, requires), required_modules, srctextpos, prefs, prefs_hash, clone_targets, flags
3194+ end
3195+
3196+ function parse_cache_header (f:: IO , cachefile:: AbstractString )
3197+ modules, (includes, srcfiles, requires), required_modules,
3198+ srctextpos, prefs, prefs_hash, clone_targets, flags = _parse_cache_header (f, cachefile)
3199+
31513200 includes_srcfiles = CacheHeaderIncludes[]
31523201 includes_depfiles = CacheHeaderIncludes[]
31533202 for (i, inc) in enumerate (includes)
0 commit comments