@@ -1036,14 +1036,22 @@ function create_distribution(project_dir::String,
10361036 try_rm_dir (dist_dir; force)
10371037 ensure_default_depot_paths (dist_dir)
10381038
1039- stdlibs = gather_stdlibs_project (ctx)
1040- stdlibs = unique ( vcat (stdlibs, map (pkg -> pkg . name, stdlibs_in_default_sysimage ())) )
1041- bundle_julia_libraries (dist_dir, stdlibs )
1039+ # For distributions, we need to bundle libraries for ALL stdlibs from the running Julia
1040+ all_stdlibs = readdir (Sys . STDLIB )
1041+ bundle_julia_libraries (dist_dir, all_stdlibs )
10421042
10431043 manifest_pkg_entries = gather_dependency_entries (ctx)
10441044 bundle_default_stdlibs (dist_dir)
10451045 bundle_custom_stdlibs (ctx, dist_dir, manifest_pkg_entries, copy_globs)
10461046 bundle_julia_test_files (dist_dir)
1047+ bundle_julia_base_files (dist_dir)
1048+ bundle_julia_compiler_files (dist_dir)
1049+ bundle_julia_support_files (dist_dir)
1050+
1051+ # Get stdlibs that will be in the sysimage (as deps of custom packages)
1052+ stdlib_deps_in_sysimage = gather_dependency_entries (ctx; include_stdlibs= true )
1053+ stdlib_deps_names = [pkg. name for pkg in stdlib_deps_in_sysimage]
1054+ bundle_stdlib_project (dist_dir, stdlib_deps_names)
10471055
10481056 bundle_julia_libexec (ctx, dist_dir)
10491057 bundle_julia_executable (dist_dir)
@@ -1064,6 +1072,8 @@ function create_distribution(project_dir::String,
10641072 script,
10651073 import_into_main= false )
10661074
1075+ precompile_stdlibs (dist_dir, sysimage_path, cpu_target)
1076+
10671077 return nothing
10681078end
10691079
@@ -1403,6 +1413,137 @@ function bundle_julia_test_files(dest_dir)
14031413 end
14041414end
14051415
1416+ function bundle_julia_base_files (dest_dir)
1417+ src_base = abspath (Sys. BINDIR, " .." , " share" , " julia" , " base" )
1418+ if isdir (src_base)
1419+ dest_base = joinpath (dest_dir, " share" , " julia" , " base" )
1420+ if isdir (dest_base)
1421+ rm (dest_base; recursive= true , force= true )
1422+ end
1423+ cp (src_base, dest_base; force= true )
1424+ end
1425+ end
1426+
1427+ function bundle_julia_compiler_files (dest_dir)
1428+ src_compiler = abspath (Sys. BINDIR, " .." , " share" , " julia" , " Compiler" )
1429+ if isdir (src_compiler)
1430+ dest_compiler = joinpath (dest_dir, " share" , " julia" , " Compiler" )
1431+ if isdir (dest_compiler)
1432+ rm (dest_compiler; recursive= true , force= true )
1433+ end
1434+ cp (src_compiler, dest_compiler; force= true )
1435+ end
1436+ end
1437+
1438+ function bundle_julia_support_files (dest_dir)
1439+ src_share = abspath (Sys. BINDIR, " .." , " share" , " julia" )
1440+ dest_share = joinpath (dest_dir, " share" , " julia" )
1441+
1442+ # Bundle individual files and directories
1443+ for item in [" julia-config.jl" , " juliac" , " terminfo" ]
1444+ src_item = joinpath (src_share, item)
1445+ dest_item = joinpath (dest_share, item)
1446+ if isfile (src_item)
1447+ cp (src_item, dest_item; force= true )
1448+ elseif isdir (src_item)
1449+ if isdir (dest_item)
1450+ rm (dest_item; recursive= true , force= true )
1451+ end
1452+ cp (src_item, dest_item; force= true )
1453+ end
1454+ end
1455+ end
1456+
1457+ function bundle_stdlib_project (dest_dir, packages_in_sysimage:: Vector{String} )
1458+ # Dynamically generate stdlib Project.toml and Manifest.toml from running Julia's stdlibs
1459+ # Include all stdlibs in manifest for dependency resolution, but only list non-sysimage ones in Project.toml
1460+ dest_stdlib = joinpath (dest_dir, " share" , " julia" , " stdlib" )
1461+ mkpath (dest_stdlib)
1462+
1463+ # Get list of packages in the sysimage
1464+ sysimage_pkgs = Set (map (pkg -> pkg. name, stdlibs_in_default_sysimage ()))
1465+ union! (sysimage_pkgs, packages_in_sysimage)
1466+
1467+ # Collect stdlib packages for Project.toml (only non-sysimage)
1468+ stdlib_deps = Dict {String, String} ()
1469+ # Collect ALL stdlib packages for Manifest.toml (needed for dependency resolution)
1470+ all_stdlib_deps = Dict {String, String} ()
1471+ for pkg_name in readdir (Sys. STDLIB)
1472+ pkg_project = joinpath (Sys. STDLIB, pkg_name, " Project.toml" )
1473+ if isfile (pkg_project)
1474+ proj = TOML. parsefile (pkg_project)
1475+ if haskey (proj, " uuid" )
1476+ all_stdlib_deps[pkg_name] = proj[" uuid" ]
1477+ # Only add to Project.toml if not in sysimage
1478+ if ! (pkg_name in sysimage_pkgs)
1479+ stdlib_deps[pkg_name] = proj[" uuid" ]
1480+ end
1481+ end
1482+ end
1483+ end
1484+
1485+ # Generate Project.toml
1486+ project = Dict (" deps" => stdlib_deps)
1487+ open (joinpath (dest_stdlib, " Project.toml" ), " w" ) do io
1488+ TOML. print (io, project)
1489+ end
1490+
1491+ # Generate Manifest.toml
1492+ manifest = Dict {String, Any} ()
1493+ manifest[" julia_version" ] = string (VERSION )
1494+ manifest[" manifest_format" ] = " 2.0"
1495+ manifest[" deps" ] = Dict {String, Any} ()
1496+
1497+ # Add each stdlib as a manifest entry (use all_stdlib_deps for complete dependency resolution)
1498+ for (name, uuid) in all_stdlib_deps
1499+ pkg_proj = TOML. parsefile (joinpath (Sys. STDLIB, name, " Project.toml" ))
1500+ entry = Dict {String, Any} (" uuid" => uuid)
1501+ if haskey (pkg_proj, " version" )
1502+ entry[" version" ] = pkg_proj[" version" ]
1503+ end
1504+ if haskey (pkg_proj, " deps" )
1505+ entry[" deps" ] = collect (keys (pkg_proj[" deps" ]))
1506+ end
1507+ manifest[" deps" ][name] = [entry]
1508+ end
1509+
1510+ open (joinpath (dest_stdlib, " Manifest.toml" ), " w" ) do io
1511+ TOML. print (io, manifest)
1512+ end
1513+ end
1514+
1515+ function precompile_stdlibs (dist_dir, sysimage_path, cpu_target)
1516+ julia_exe = joinpath (dist_dir, " bin" , " julia" )
1517+ depot_path = joinpath (dist_dir, " share" , " julia" )
1518+ stdlib_dir = joinpath (depot_path, " stdlib" )
1519+ compiled_dir = joinpath (depot_path, " compiled" )
1520+ mkpath (compiled_dir)
1521+
1522+ # Precompile all packages in the stdlib that aren't in the sysimage
1523+ precompile_code = """
1524+ println("Active project: ", Base.active_project())
1525+ println("DEPOT_PATH: ", Base.DEPOT_PATH)
1526+ Base.Precompilation.precompilepkgs(configs=[
1527+ `` => Base.CacheFlags(debug_level=2, opt_level=3),
1528+ `` => Base.CacheFlags(check_bounds=1, debug_level=2, opt_level=3)
1529+ ]; io=stdout)
1530+ """
1531+
1532+ # Set JULIA_PROJECT to the stdlib directory so precompilepkgs knows what to precompile
1533+ # Set JULIA_LOAD_PATH to @stdlib like Julia's makefile does
1534+ env = Dict (
1535+ " JULIA_DEPOT_PATH" => depot_path,
1536+ " JULIA_LOAD_PATH" => " @stdlib" ,
1537+ " JULIA_CPU_TARGET" => cpu_target,
1538+ " JULIA_PROJECT" => stdlib_dir
1539+ )
1540+
1541+ cmd = setenv (` $julia_exe --sysimage=$sysimage_path --startup-file=no -e $precompile_code ` , env)
1542+
1543+ @info " Precompiling stdlibs for the distribution..."
1544+ run (cmd)
1545+ end
1546+
14061547function bundle_default_stdlibs (dest_dir)
14071548 src_stdlib = abspath (Sys. BINDIR, " .." , " share" , " julia" , " stdlib" )
14081549 dest_stdlib = joinpath (dest_dir, " share" , " julia" , " stdlib" )
0 commit comments