@@ -1350,7 +1350,9 @@ function run_module_init(mod::Module, i::Int=1)
13501350end
13511351
13521352function run_package_callbacks (modkey:: PkgId )
1353- run_extension_callbacks (modkey)
1353+ if ! precompiling_extension
1354+ run_extension_callbacks (modkey)
1355+ end
13541356 assert_havelock (require_lock)
13551357 unlock (require_lock)
13561358 try
@@ -1405,13 +1407,12 @@ function insert_extension_triggers(env::String, pkg::PkgId)::Union{Nothing,Missi
14051407 proj_pkg = project_file_name_uuid (implicit_project_file, pkg. name)
14061408 if pkg == proj_pkg
14071409 d_proj = parsed_toml (implicit_project_file)
1408- weakdeps = get (d_proj, " weakdeps" , nothing ):: Union{Nothing, Vector{String}, Dict{String,Any}}
14091410 extensions = get (d_proj, " extensions" , nothing ):: Union{Nothing, Dict{String, Any}}
14101411 extensions === nothing && return
1411- weakdeps === nothing && return
1412- if weakdeps isa Dict{String, Any}
1413- return _insert_extension_triggers (pkg, extensions, weakdeps )
1414- end
1412+ weakdeps = get (Dict{String, Any}, d_proj, " weakdeps " ) :: Dict{String,Any}
1413+ deps = get ( Dict{String, Any}, d_proj, " deps " ) :: Dict{String, Any}
1414+ total_deps = merge (weakdeps, deps )
1415+ return _insert_extension_triggers (pkg, extensions, total_deps)
14151416 end
14161417
14171418 # Now look in manifest
@@ -1426,35 +1427,43 @@ function insert_extension_triggers(env::String, pkg::PkgId)::Union{Nothing,Missi
14261427 uuid = get (entry, " uuid" , nothing ):: Union{String, Nothing}
14271428 uuid === nothing && continue
14281429 if UUID (uuid) == pkg. uuid
1429- weakdeps = get (entry, " weakdeps" , nothing ):: Union{Nothing, Vector{String}, Dict{String,Any}}
14301430 extensions = get (entry, " extensions" , nothing ):: Union{Nothing, Dict{String, Any}}
14311431 extensions === nothing && return
1432- weakdeps === nothing && return
1433- if weakdeps isa Dict{String, Any}
1434- return _insert_extension_triggers (pkg, extensions, weakdeps)
1432+ weakdeps = get (Dict{String, Any}, entry, " weakdeps" ):: Union{Vector{String}, Dict{String,Any}}
1433+ deps = get (Dict{String, Any}, entry, " deps" ):: Union{Vector{String}, Dict{String,Any}}
1434+
1435+ function expand_deps_list (deps′:: Vector{String} )
1436+ deps′_expanded = Dict {String, Any} ()
1437+ for (dep_name, entries) in d
1438+ dep_name in deps′ || continue
1439+ entries:: Vector{Any}
1440+ if length (entries) != 1
1441+ error (" expected a single entry for $(repr (dep_name)) in $(repr (project_file)) " )
1442+ end
1443+ entry = first (entries):: Dict{String, Any}
1444+ uuid = entry[" uuid" ]:: String
1445+ deps′_expanded[dep_name] = uuid
1446+ end
1447+ return deps′_expanded
14351448 end
14361449
1437- d_weakdeps = Dict {String, Any} ()
1438- for (dep_name, entries) in d
1439- dep_name in weakdeps || continue
1440- entries:: Vector{Any}
1441- if length (entries) != 1
1442- error (" expected a single entry for $(repr (dep_name)) in $(repr (project_file)) " )
1443- end
1444- entry = first (entries):: Dict{String, Any}
1445- uuid = entry[" uuid" ]:: String
1446- d_weakdeps[dep_name] = uuid
1450+ if weakdeps isa Vector{String}
1451+ weakdeps = expand_deps_list (weakdeps)
1452+ end
1453+ if deps isa Vector{String}
1454+ deps = expand_deps_list (deps)
14471455 end
1448- @assert length (d_weakdeps) == length (weakdeps)
1449- return _insert_extension_triggers (pkg, extensions, d_weakdeps)
1456+
1457+ total_deps = merge (weakdeps, deps)
1458+ return _insert_extension_triggers (pkg, extensions, total_deps)
14501459 end
14511460 end
14521461 end
14531462 end
14541463 return nothing
14551464end
14561465
1457- function _insert_extension_triggers (parent:: PkgId , extensions:: Dict{String, Any} , weakdeps :: Dict{String, Any} )
1466+ function _insert_extension_triggers (parent:: PkgId , extensions:: Dict{String, Any} , totaldeps :: Dict{String, Any} )
14581467 for (ext, triggers) in extensions
14591468 triggers = triggers:: Union{String, Vector{String}}
14601469 triggers isa String && (triggers = [triggers])
@@ -1468,7 +1477,7 @@ function _insert_extension_triggers(parent::PkgId, extensions::Dict{String, Any}
14681477 push! (trigger1, gid)
14691478 for trigger in triggers
14701479 # TODO : Better error message if this lookup fails?
1471- uuid_trigger = UUID (weakdeps [trigger]:: String )
1480+ uuid_trigger = UUID (totaldeps [trigger]:: String )
14721481 trigger_id = PkgId (uuid_trigger, trigger)
14731482 if ! haskey (explicit_loaded_modules, trigger_id) || haskey (package_locks, trigger_id)
14741483 trigger1 = get! (Vector{ExtensionId}, EXT_DORMITORY, trigger_id)
@@ -1480,6 +1489,7 @@ function _insert_extension_triggers(parent::PkgId, extensions::Dict{String, Any}
14801489 end
14811490end
14821491
1492+ precompiling_package:: Bool = false
14831493loading_extension:: Bool = false
14841494precompiling_extension:: Bool = false
14851495function run_extension_callbacks (extid:: ExtensionId )
@@ -2172,6 +2182,11 @@ For more details regarding code loading, see the manual sections on [modules](@r
21722182[parallel computing](@ref code-availability).
21732183"""
21742184function require (into:: Module , mod:: Symbol )
2185+ if into === Base. __toplevel__ && precompiling_package
2186+ # this error type needs to match the error type compilecache throws for non-125 errors.
2187+ error (" `using/import $mod ` outside of a Module detected. Importing a package outside of a module \
2188+ is not allowed during package precompilation." )
2189+ end
21752190 if _require_world_age[] != typemax (UInt)
21762191 Base. invoke_in_world (_require_world_age[], __require, into, mod)
21772192 else
@@ -2750,41 +2765,10 @@ function load_path_setup_code(load_path::Bool=true)
27502765 return code
27512766end
27522767
2753- """
2754- check_src_module_wrap(srcpath::String)
2755-
2756- Checks that a package entry file `srcpath` has a module declaration, and that it is before any using/import statements.
2757- """
2758- function check_src_module_wrap (pkg:: PkgId , srcpath:: String )
2759- module_rgx = r" ^(|end |\"\"\" )\s *(?:@)*(?:bare)?module\s "
2760- load_rgx = r" \b (?:using|import)\s "
2761- load_seen = false
2762- inside_string = false
2763- for s in eachline (srcpath)
2764- if count (" \"\"\" " , s) == 1
2765- # ignore module docstrings
2766- inside_string = ! inside_string
2767- end
2768- inside_string && continue
2769- if contains (s, module_rgx)
2770- if load_seen
2771- throw (ErrorException (" Package $(repr (" text/plain" , pkg)) source file $srcpath has a using/import before a module declaration." ))
2772- end
2773- return true
2774- end
2775- if startswith (s, load_rgx)
2776- load_seen = true
2777- end
2778- end
2779- throw (ErrorException (" Package $(repr (" text/plain" , pkg)) source file $srcpath does not contain a module declaration." ))
2780- end
2781-
27822768# this is called in the external process that generates precompiled package files
27832769function include_package_for_output (pkg:: PkgId , input:: String , depot_path:: Vector{String} , dl_load_path:: Vector{String} , load_path:: Vector{String} ,
27842770 concrete_deps:: typeof (_concrete_dependencies), source:: Union{Nothing,String} )
27852771
2786- check_src_module_wrap (pkg, input)
2787-
27882772 append! (empty! (Base. DEPOT_PATH ), depot_path)
27892773 append! (empty! (Base. DL_LOAD_PATH), dl_load_path)
27902774 append! (empty! (Base. LOAD_PATH ), load_path)
@@ -2811,11 +2795,22 @@ function include_package_for_output(pkg::PkgId, input::String, depot_path::Vecto
28112795 finally
28122796 Core. Compiler. track_newly_inferred. x = false
28132797 end
2798+ # check that the package defined the expected module so we can give a nice error message if not
2799+ Base. check_package_module_loaded (pkg)
2800+ end
2801+
2802+ function check_package_module_loaded (pkg:: PkgId )
2803+ if ! haskey (Base. loaded_modules, pkg)
2804+ # match compilecache error type for non-125 errors
2805+ error (" $(repr (" text/plain" , pkg)) did not define the expected module `$(pkg. name) `, \
2806+ check for typos in package module name" )
2807+ end
2808+ return nothing
28142809end
28152810
28162811const PRECOMPILE_TRACE_COMPILE = Ref {String} ()
28172812function create_expr_cache (pkg:: PkgId , input:: String , output:: String , output_o:: Union{Nothing, String} ,
2818- concrete_deps:: typeof (_concrete_dependencies), flags:: Cmd = ` ` , internal_stderr:: IO = stderr , internal_stdout:: IO = stdout )
2813+ concrete_deps:: typeof (_concrete_dependencies), flags:: Cmd = ` ` , internal_stderr:: IO = stderr , internal_stdout:: IO = stdout , isext :: Bool = false )
28192814 @nospecialize internal_stderr internal_stdout
28202815 rm (output, force= true ) # Remove file if it exists
28212816 output_o === nothing || rm (output_o, force= true )
@@ -2884,7 +2879,8 @@ function create_expr_cache(pkg::PkgId, input::String, output::String, output_o::
28842879 write (io. in, """
28852880 empty!(Base.EXT_DORMITORY) # If we have a custom sysimage with `EXT_DORMITORY` prepopulated
28862881 Base.track_nested_precomp($precomp_stack )
2887- Base.precompiling_extension = $(loading_extension)
2882+ Base.precompiling_extension = $(loading_extension | isext)
2883+ Base.precompiling_package = true
28882884 Base.include_package_for_output($(pkg_str (pkg)) , $(repr (abspath (input))) , $(repr (depot_path)) , $(repr (dl_load_path)) ,
28892885 $(repr (load_path)) , $deps , $(repr (source_path (nothing ))) )
28902886 """ )
@@ -2941,18 +2937,18 @@ This can be used to reduce package load times. Cache files are stored in
29412937`DEPOT_PATH[1]/compiled`. See [Module initialization and precompilation](@ref)
29422938for important notes.
29432939"""
2944- function compilecache (pkg:: PkgId , internal_stderr:: IO = stderr , internal_stdout:: IO = stdout ; flags:: Cmd = ` ` , reasons:: Union{Dict{String,Int},Nothing} = Dict {String,Int} ())
2940+ function compilecache (pkg:: PkgId , internal_stderr:: IO = stderr , internal_stdout:: IO = stdout ; flags:: Cmd = ` ` , reasons:: Union{Dict{String,Int},Nothing} = Dict {String,Int} (), isext :: Bool = false )
29452941 @nospecialize internal_stderr internal_stdout
29462942 path = locate_package (pkg)
29472943 path === nothing && throw (ArgumentError (" $(repr (" text/plain" , pkg)) not found during precompilation" ))
2948- return compilecache (pkg, path, internal_stderr, internal_stdout; flags, reasons)
2944+ return compilecache (pkg, path, internal_stderr, internal_stdout; flags, reasons, isext )
29492945end
29502946
29512947const MAX_NUM_PRECOMPILE_FILES = Ref (10 )
29522948
29532949function compilecache (pkg:: PkgId , path:: String , internal_stderr:: IO = stderr , internal_stdout:: IO = stdout ,
29542950 keep_loaded_modules:: Bool = true ; flags:: Cmd = ` ` , cacheflags:: CacheFlags = CacheFlags (),
2955- reasons:: Union{Dict{String,Int},Nothing} = Dict {String,Int} ())
2951+ reasons:: Union{Dict{String,Int},Nothing} = Dict {String,Int} (), isext :: Bool = false )
29562952
29572953 @nospecialize internal_stderr internal_stdout
29582954 # decide where to put the resulting cache file
@@ -2992,7 +2988,7 @@ function compilecache(pkg::PkgId, path::String, internal_stderr::IO = stderr, in
29922988 close (tmpio_o)
29932989 close (tmpio_so)
29942990 end
2995- p = create_expr_cache (pkg, path, tmppath, tmppath_o, concrete_deps, flags, internal_stderr, internal_stdout)
2991+ p = create_expr_cache (pkg, path, tmppath, tmppath_o, concrete_deps, flags, internal_stderr, internal_stdout, isext )
29962992
29972993 if success (p)
29982994 if cache_objects
@@ -3778,10 +3774,17 @@ end
37783774
37793775 # now check if this file's content hash has changed relative to its source files
37803776 if stalecheck
3781- if ! samefile (includes[1 ]. filename, modpath) && ! samefile (fixup_stdlib_path (includes[1 ]. filename), modpath)
3782- @debug " Rejecting cache file $cachefile because it is for file $(includes[1 ]. filename) not file $modpath "
3783- record_reason (reasons, " wrong source" )
3784- return true # cache file was compiled from a different path
3777+ if ! samefile (includes[1 ]. filename, modpath)
3778+ # In certain cases the path rewritten by `fixup_stdlib_path` may
3779+ # point to an unreadable directory, make sure we can `stat` the
3780+ # file before comparing it with `modpath`.
3781+ stdlib_path = fixup_stdlib_path (includes[1 ]. filename)
3782+ if ! (isreadable (stdlib_path) && samefile (stdlib_path, modpath))
3783+ ! samefile (fixup_stdlib_path (includes[1 ]. filename), modpath)
3784+ @debug " Rejecting cache file $cachefile because it is for file $(includes[1 ]. filename) not file $modpath "
3785+ record_reason (reasons, " wrong source" )
3786+ return true # cache file was compiled from a different path
3787+ end
37853788 end
37863789 for (modkey, req_modkey) in requires
37873790 # verify that `require(modkey, name(req_modkey))` ==> `req_modkey`
0 commit comments