@@ -1643,25 +1643,13 @@ end
16431643# should sync with the types of arguments of `stale_cachefile`
16441644const StaleCacheKey = Tuple{Base. PkgId, UInt128, String, String}
16451645
1646- """
1647- Base.isprecompiled(pkg::PkgId; ignore_loaded::Bool=false)
1648-
1649- Returns whether a given PkgId within the active project is precompiled.
1650-
1651- By default this check observes the same approach that code loading takes
1652- with respect to when different versions of dependencies are currently loaded
1653- to that which is expected. To ignore loaded modules and answer as if in a
1654- fresh julia session specify `ignore_loaded=true`.
1655-
1656- !!! compat "Julia 1.10"
1657- This function requires at least Julia 1.10.
1658- """
1659- function isprecompiled (pkg:: PkgId ;
1646+ function compilecache_path (pkg:: PkgId ;
16601647 ignore_loaded:: Bool = false ,
16611648 stale_cache:: Dict{StaleCacheKey,Bool} = Dict {StaleCacheKey, Bool} (),
16621649 cachepaths:: Vector{String} = Base. find_all_in_cache_path (pkg),
16631650 sourcepath:: Union{String,Nothing} = Base. locate_package (pkg),
16641651 flags:: CacheFlags = CacheFlags ())
1652+ path = nothing
16651653 isnothing (sourcepath) && error (" Cannot locate source for $(repr (" text/plain" , pkg)) " )
16661654 for path_to_try in cachepaths
16671655 staledeps = stale_cachefile (sourcepath, path_to_try, ignore_loaded = true , requested_flags= flags)
@@ -1693,10 +1681,64 @@ function isprecompiled(pkg::PkgId;
16931681 # file might be read-only and then we fail to update timestamp, which is fine
16941682 ex isa IOError || rethrow ()
16951683 end
1696- return true
1684+ path = path_to_try
1685+ break
16971686 @label check_next_path
16981687 end
1699- return false
1688+ return path
1689+ end
1690+
1691+ """
1692+ Base.isprecompiled(pkg::PkgId; ignore_loaded::Bool=false)
1693+
1694+ Returns whether a given PkgId within the active project is precompiled.
1695+
1696+ By default this check observes the same approach that code loading takes
1697+ with respect to when different versions of dependencies are currently loaded
1698+ to that which is expected. To ignore loaded modules and answer as if in a
1699+ fresh julia session specify `ignore_loaded=true`.
1700+
1701+ !!! compat "Julia 1.10"
1702+ This function requires at least Julia 1.10.
1703+ """
1704+ function isprecompiled (pkg:: PkgId ;
1705+ ignore_loaded:: Bool = false ,
1706+ stale_cache:: Dict{StaleCacheKey,Bool} = Dict {StaleCacheKey, Bool} (),
1707+ cachepaths:: Vector{String} = Base. find_all_in_cache_path (pkg),
1708+ sourcepath:: Union{String,Nothing} = Base. locate_package (pkg),
1709+ flags:: CacheFlags = CacheFlags ())
1710+ path = compilecache_path (pkg; ignore_loaded, stale_cache, cachepaths, sourcepath, flags)
1711+ return ! isnothing (path)
1712+ end
1713+
1714+ """
1715+ Base.isrelocatable(pkg::PkgId)
1716+
1717+ Returns whether a given PkgId within the active project is precompiled and the
1718+ associated cache is relocatable.
1719+
1720+ !!! compat "Julia 1.11"
1721+ This function requires at least Julia 1.11.
1722+ """
1723+ function isrelocatable (pkg:: PkgId )
1724+ path = compilecache_path (pkg)
1725+ isnothing (path) && return false
1726+ io = open (path, " r" )
1727+ try
1728+ iszero (isvalid_cache_header (io)) && throw (ArgumentError (" Invalid header in cache file $cachefile ." ))
1729+ _, (includes, includes_srcfiles, _), _... = _parse_cache_header (io, path)
1730+ for inc in includes
1731+ ! startswith (inc. filename, " @depot" ) && return false
1732+ if inc ∉ includes_srcfiles
1733+ # its an include_dependency
1734+ track_content = inc. mtime == - 1.0
1735+ track_content || return false
1736+ end
1737+ end
1738+ finally
1739+ close (io)
1740+ end
1741+ return true
17001742end
17011743
17021744# search for a precompile cache file to load, after some various checks
@@ -3025,7 +3067,7 @@ function resolve_depot(inc::AbstractString)
30253067end
30263068
30273069
3028- function parse_cache_header (f:: IO , cachefile:: AbstractString )
3070+ function _parse_cache_header (f:: IO , cachefile:: AbstractString )
30293071 flags = read (f, UInt8)
30303072 modules = Vector {Pair{PkgId, UInt64}} ()
30313073 while true
@@ -3109,6 +3151,13 @@ function parse_cache_header(f::IO, cachefile::AbstractString)
31093151
31103152 srcfiles = srctext_files (f, srctextpos, includes)
31113153
3154+ return modules, (includes, srcfiles, requires), required_modules, srctextpos, prefs, prefs_hash, clone_targets, flags
3155+ end
3156+
3157+ function parse_cache_header (f:: IO , cachefile:: AbstractString )
3158+ modules, (includes, srcfiles, requires), required_modules,
3159+ srctextpos, prefs, prefs_hash, clone_targets, flags = _parse_cache_header (f, cachefile)
3160+
31123161 includes_srcfiles = CacheHeaderIncludes[]
31133162 includes_depfiles = CacheHeaderIncludes[]
31143163 for (i, inc) in enumerate (includes)
0 commit comments