@@ -1200,66 +1200,73 @@ function load_path_setup_code(load_path::Bool=true)
1200
1200
return code
1201
1201
end
1202
1202
1203
+ # this is called in the external process that generates precompiled package files
1204
+ function include_package_for_output (input:: String , depot_path:: Vector{String} , dl_load_path:: Vector{String} , load_path:: Vector{String} , concrete_deps:: typeof (_concrete_dependencies), uuid_tuple:: NTuple{2,UInt64} , source:: Union{Nothing,String} )
1205
+ append! (empty! (Base. DEPOT_PATH ), depot_path)
1206
+ append! (empty! (Base. DL_LOAD_PATH), dl_load_path)
1207
+ append! (empty! (Base. LOAD_PATH ), load_path)
1208
+ ENV [" JULIA_LOAD_PATH" ] = join (load_path, Sys. iswindows () ? ' ;' : ' :' )
1209
+ Base. HOME_PROJECT[] = Base. ACTIVE_PROJECT[] = nothing
1210
+ Base. _track_dependencies[] = true
1211
+ append! (empty! (Base. _concrete_dependencies), concrete_deps)
1212
+
1213
+ ccall (:jl_set_module_uuid , Cvoid, (Any, NTuple{2 , UInt64}), Base. __toplevel__, uuid_tuple)
1214
+ if source != = nothing
1215
+ task_local_storage ()[:SOURCE_PATH ] = source
1216
+ end
1217
+
1218
+ try
1219
+ Base. include (Base. __toplevel__, input)
1220
+ catch ex
1221
+ precompilableerror (ex) || rethrow ()
1222
+ @debug " Aborting `create_expr_cache'" exception= (ErrorException (" Declaration of __precompile__(false) not allowed" ), catch_backtrace ())
1223
+ exit (125 ) # we define status = 125 means PrecompileableError
1224
+ end
1225
+ end
1226
+
1227
+ @assert precompile (include_package_for_output, (String,Vector{String},Vector{String},Vector{String},typeof (_concrete_dependencies),NTuple{2 ,UInt64},Nothing))
1228
+ @assert precompile (include_package_for_output, (String,Vector{String},Vector{String},Vector{String},typeof (_concrete_dependencies),NTuple{2 ,UInt64},String))
1229
+
1203
1230
function create_expr_cache (input:: String , output:: String , concrete_deps:: typeof (_concrete_dependencies), uuid:: Union{Nothing,UUID} )
1204
1231
rm (output, force= true ) # Remove file if it exists
1205
- code_object = """
1206
- while !eof(stdin)
1207
- code = readuntil(stdin, '\\ 0')
1208
- eval(Meta.parse(code))
1232
+ depot_path = map (abspath, DEPOT_PATH )
1233
+ dl_load_path = map (abspath, DL_LOAD_PATH)
1234
+ load_path = map (abspath, Base. load_path ())
1235
+ path_sep = Sys. iswindows () ? ' ;' : ' :'
1236
+ any (path -> path_sep in path, load_path) &&
1237
+ error (" LOAD_PATH entries cannot contain $(repr (path_sep)) " )
1238
+
1239
+ deps_strs = String[]
1240
+ for (pkg, build_id) in concrete_deps
1241
+ pkg_str = if pkg. uuid === nothing
1242
+ " Base.PkgId($(repr (pkg. name)) )"
1243
+ else
1244
+ " Base.PkgId(Base.UUID(\" $(pkg. uuid) \" ), $(repr (pkg. name)) )"
1209
1245
end
1210
- """
1246
+ push! (deps_strs, " $pkg_str => $(repr (build_id)) " )
1247
+ end
1248
+ deps = repr (eltype (concrete_deps)) * " [" * join (deps_strs, " ," ) * " ]"
1249
+
1250
+ uuid_tuple = uuid === nothing ? (UInt64 (0 ), UInt64 (0 )) : convert (NTuple{2 , UInt64}, uuid)
1211
1251
1212
1252
io = open (pipeline (` $(julia_cmd ()) -O0
1213
1253
--output-ji $output --output-incremental=yes
1214
1254
--startup-file=no --history-file=no --warn-overwrite=yes
1215
1255
--color=$(have_color === nothing ? " auto" : have_color ? " yes" : " no" )
1216
- --eval $code_object ` , stderr = stderr ),
1256
+ --eval 'eval(Meta.parse(read(stdin,String)))' ` , stderr = stderr ),
1217
1257
" w" , stdout )
1218
- in = io. in
1219
- try
1220
- write (in, """
1221
- begin
1222
- $(Base. load_path_setup_code ())
1223
- Base._track_dependencies[] = true
1224
- Base.empty!(Base._concrete_dependencies)
1225
- """ )
1226
- for (pkg, build_id) in concrete_deps
1227
- pkg_str = if pkg. uuid === nothing
1228
- " Base.PkgId($(repr (pkg. name)) )"
1229
- else
1230
- " Base.PkgId(Base.UUID(\" $(pkg. uuid) \" ), $(repr (pkg. name)) )"
1231
- end
1232
- write (in, " Base.push!(Base._concrete_dependencies, $pkg_str => $(repr (build_id)) )\n " )
1233
- end
1234
- write (io, " end\0 " )
1235
- uuid_tuple = uuid === nothing ? (0 , 0 ) : convert (NTuple{2 , UInt64}, uuid)
1236
- write (in, " ccall(:jl_set_module_uuid, Cvoid, (Any, NTuple{2, UInt64}), Base.__toplevel__, $uuid_tuple )\0 " )
1237
- source = source_path (nothing )
1238
- if source != = nothing
1239
- write (in, " task_local_storage()[:SOURCE_PATH] = $(repr (source)) \0 " )
1240
- end
1241
- write (in, """
1242
- try
1243
- Base.include(Base.__toplevel__, $(repr (abspath (input))) )
1244
- catch ex
1245
- Base.precompilableerror(ex) || Base.rethrow()
1246
- Base.@debug "Aborting `createexprcache'" exception=(Base.ErrorException("Declaration of __precompile__(false) not allowed"), Base.catch_backtrace())
1247
- Base.exit(125) # we define status = 125 means PrecompileableError
1248
- end\0 """ )
1249
- # TODO : cleanup is probably unnecessary here
1250
- if source != = nothing
1251
- write (in, " delete!(task_local_storage(), :SOURCE_PATH)\0 " )
1252
- end
1253
- write (in, " ccall(:jl_set_module_uuid, Cvoid, (Any, NTuple{2, UInt64}), Base.__toplevel__, (0, 0))\0 " )
1254
- close (in)
1255
- catch
1256
- close (in)
1257
- process_running (io) && Timer (t -> kill (io), 5.0 ) # wait a short time before killing the process to give it a chance to clean up on its own first
1258
- rethrow ()
1259
- end
1258
+ # write data over stdin to avoid the (unlikely) case of exceeding max command line size
1259
+ write (io. in, """
1260
+ Base.include_package_for_output($(repr (abspath (input))) , $(repr (depot_path)) , $(repr (dl_load_path)) ,
1261
+ $(repr (load_path)) , $deps , $(repr (uuid_tuple)) , $(repr (source_path (nothing ))) )
1262
+ """ )
1263
+ close (io. in)
1260
1264
return io
1261
1265
end
1262
1266
1267
+ @assert precompile (create_expr_cache, (String, String, typeof (_concrete_dependencies), Nothing))
1268
+ @assert precompile (create_expr_cache, (String, String, typeof (_concrete_dependencies), UUID))
1269
+
1263
1270
function compilecache_path (pkg:: PkgId ):: String
1264
1271
entrypath, entryfile = cache_file_entry (pkg)
1265
1272
cachepath = joinpath (DEPOT_PATH [1 ], entrypath)
0 commit comments