diff --git a/base/initdefs.jl b/base/initdefs.jl index 002984b83dd978..aa95cc758a76f1 100644 --- a/base/initdefs.jl +++ b/base/initdefs.jl @@ -113,6 +113,47 @@ function init_depot_path() end end +# replace leading dirname with `@depot, @stdlib` if `path` is located withiin any of +# DEPOT_PATH/compiled or Sys.STDLIB +# return normalized path otherwise +function replace_depot_path(_path::AbstractString) + path = normpath(_path) + if startswith(path, Sys.STDLIB) + length(path) == 1+length(Sys.STDLIB) && return joinpath("@stdlib", "") + return joinpath("@stdlib", path[2+length(Sys.STDLIB):end]) + end + for depot in DEPOT_PATH + if startswith(path, joinpath(depot, "compiled")) + return joinpath("@depot", path[2+length(depot):end]) + end + end + return path +end + +# resolve leading `@depot, @stdlib` alias from `_path` to point to a valid path in any +# of DEPOT_PATH/compiled or Sys.STDLIb +# if `_path` has no leading alias, we return a normalized path +function resolve_depot_path(_path::AbstractString) + path = normpath(_path) + if startswith(path, "@stdlib") + length(path) == 1+length("@stdlib") && return joinpath(Sys.STDLIB, "") + fullpath = joinpath(Sys.STDLIB, path[2+length("@stdlib"):end]) + ispath(fullpath) && return fullpath + throw(ErrorException("Failed to resolve `$path` to a stdlib path in `$(Sys.STDLIB)`.")) + elseif startswith(path, joinpath("@depot", "compiled")) + dir = path[2+length("@depot"):end] + for depot in DEPOT_PATH + fullpath = joinpath(depot, dir) + ispath(fullpath) && return fullpath + end + io = IOBuffer() + print(io, "Failed to resolve `$path` to a valid path for any depot in `DEPOT_PATH = ", + DEPOT_PATH, "`.") + throw(ErrorException(String(take!(io)))) + end + return path +end + ## LOAD_PATH & ACTIVE_PROJECT ## # JULIA_LOAD_PATH: split on `:` (or `;` on Windows) diff --git a/base/loading.jl b/base/loading.jl index a7d05e5940ef39..90f2d8aeb1fd2b 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -1605,7 +1605,8 @@ function _include_dependency(mod::Module, _path::AbstractString) end if _track_dependencies[] @lock require_lock begin - push!(_require_dependencies, (mod, path, mtime(path))) + push!(_require_dependencies, (mod, path, mtime(path), + path[1] == '\0' ? path : replace_depot_path(path))) end end return path, prev @@ -1710,7 +1711,9 @@ function require(into::Module, mod::Symbol) end uuidkey, env = uuidkey_env if _track_dependencies[] - push!(_require_dependencies, (into, binpack(uuidkey), 0.0)) + path = binpack(uuidkey) + push!(_require_dependencies, (into, path, 0.0, + path[1] == '\0' ? path : replace_depot_path(path))) end return _require_prelocked(uuidkey, env) finally @@ -2456,6 +2459,8 @@ function parse_cache_header(f::IO) end if depname[1] == '\0' push!(requires, modkey => binunpack(depname)) + elseif depname[1] == '@' + push!(includes, CacheHeaderIncludes(modkey, resolve_depot_path(depname), mtime, modpath)) else push!(includes, CacheHeaderIncludes(modkey, depname, mtime, modpath)) end diff --git a/src/precompile.c b/src/precompile.c index 4aac28ff9a7908..411afd64bb12d2 100644 --- a/src/precompile.c +++ b/src/precompile.c @@ -30,8 +30,8 @@ void write_srctext(ios_t *f, jl_array_t *udeps, int64_t srctextpos) { write_uint64(f, posfile); ios_seek_end(f); // Each source-text file is written as - // int32: length of abspath - // char*: abspath + // int32: length of depot alias + // char*: depot alias // uint64: length of src text // char*: src text // At the end we write int32(0) as a terminal sentinel. @@ -50,12 +50,13 @@ void write_srctext(ios_t *f, jl_array_t *udeps, int64_t srctextpos) { ios_t *srctp = ios_file(&srctext, depstr, 1, 0, 0, 0); if (!srctp) { jl_printf(JL_STDERR, "WARNING: could not cache source text for \"%s\".\n", - jl_string_data(dep)); + depstr); continue; } - size_t slen = jl_string_len(dep); + jl_value_t *depalias = jl_fieldref(deptuple, 3); // file @depot alias + size_t slen = jl_string_len(depalias); write_int32(f, slen); - ios_write(f, depstr, slen); + ios_write(f, jl_string_data(depalias), slen); posfile = ios_pos(f); write_uint64(f, 0); // placeholder for length of this file in bytes uint64_t filelen = (uint64_t) ios_copyall(f, &srctext); diff --git a/src/staticdata_utils.c b/src/staticdata_utils.c index bf1a830b608de2..46002021a785be 100644 --- a/src/staticdata_utils.c +++ b/src/staticdata_utils.c @@ -715,10 +715,10 @@ static int64_t write_dependency_list(ios_t *s, jl_array_t* worklist, jl_array_t size_t i, l = udeps ? jl_array_len(udeps) : 0; for (i = 0; i < l; i++) { jl_value_t *deptuple = jl_array_ptr_ref(udeps, i); - jl_value_t *dep = jl_fieldref(deptuple, 1); // file abspath - size_t slen = jl_string_len(dep); + jl_value_t *depalias = jl_fieldref(deptuple, 3); // file @depot alias + size_t slen = jl_string_len(depalias); write_int32(s, slen); - ios_write(s, jl_string_data(dep), slen); + ios_write(s, jl_string_data(depalias), slen); write_float64(s, jl_unbox_float64(jl_fieldref(deptuple, 2))); // mtime jl_module_t *depmod = (jl_module_t*)jl_fieldref(deptuple, 0); // evaluating module jl_module_t *depmod_top = depmod;