@@ -9,6 +9,7 @@ using LazyArtifacts
9
9
using UUIDs: UUID, uuid1
10
10
using RelocatableFolders
11
11
using TOML
12
+ using Glob
12
13
13
14
export create_sysimage, create_app, create_library
14
15
@@ -93,10 +94,12 @@ sysimage_modules() = map(x->x.name, Base._sysimage_modules)
93
94
stdlibs_in_sysimage () = intersect (_STDLIBS, sysimage_modules ())
94
95
95
96
# TODO : Also check UUIDs for stdlibs, not only names
96
- function gather_stdlibs_project (ctx)
97
+ function gather_stdlibs_project (ctx; only_in_sysimage :: Bool = true )
97
98
@assert ctx. env. manifest != = nothing
98
- sysimage_stdlibs = stdlibs_in_sysimage ()
99
- return String[pkg. name for (_, pkg) in ctx. env. manifest if pkg. name in sysimage_stdlibs]
99
+ stdlibs = only_in_sysimage ? stdlibs_in_sysimage () : _STDLIBS
100
+ stdlib_names = String[pkg. name for (_, pkg) in ctx. env. manifest]
101
+ filter! (pkg -> pkg in stdlibs, stdlib_names)
102
+ return stdlib_names
100
103
end
101
104
102
105
function check_packages_in_project (ctx, packages)
@@ -700,12 +703,15 @@ function create_app(package_dir::String,
700
703
executables = [ctx. env. pkg. name => " julia_main" ]
701
704
end
702
705
try_rm_dir (app_dir; force)
703
- bundle_artifacts (ctx, app_dir; include_lazy_artifacts)
704
- bundle_julia_libraries (app_dir)
706
+
707
+ stdlibs = filter_stdlibs ? gather_stdlibs_project (ctx; only_in_sysimage= false ) : _STDLIBS
708
+ bundle_julia_libraries (app_dir, stdlibs)
705
709
bundle_julia_executable (app_dir)
706
710
bundle_project (ctx, app_dir)
707
711
bundle_cert (app_dir)
708
712
713
+ bundle_artifacts (ctx, app_dir; include_lazy_artifacts)
714
+
709
715
sysimage_path = joinpath (app_dir, " lib" , " julia" , " sys." * Libdl. dlext)
710
716
711
717
package_name = ctx. env. pkg. name
@@ -885,10 +891,11 @@ function create_library(package_dir::String,
885
891
lib_name = something (lib_name, ctx. env. pkg. name)
886
892
try_rm_dir (dest_dir; force)
887
893
mkpath (dest_dir)
888
- bundle_julia_libraries (dest_dir)
889
- bundle_artifacts (ctx, dest_dir; include_lazy_artifacts )
894
+ stdlibs = filter_stdlibs ? gather_stdlibs_project (ctx; only_in_sysimage = false ) : _STDLIBS
895
+ bundle_julia_libraries (dest_dir, stdlibs )
890
896
bundle_headers (dest_dir, header_files)
891
897
bundle_cert (dest_dir)
898
+ bundle_artifacts (ctx, dest_dir; include_lazy_artifacts)
892
899
893
900
lib_dir = Sys. iswindows () ? joinpath (dest_dir, " bin" ) : joinpath (dest_dir, " lib" )
894
901
@@ -1018,20 +1025,275 @@ function bundle_julia_executable(dir::String)
1018
1025
cp (joinpath (Sys. BINDIR:: String , name), joinpath (bindir, name); force= true )
1019
1026
end
1020
1027
1021
- function bundle_julia_libraries (dest_dir)
1022
- app_libdir = joinpath (dest_dir, Sys. isunix () ? " lib" : " bin" )
1023
- mkpath (app_libdir)
1024
- cp (julia_libdir (), app_libdir; force= true )
1025
- # We do not want to bundle the sysimg
1026
- default_sysimg_name = " sys." * Libdl. dlext
1027
- rm (joinpath (app_libdir, " julia" , default_sysimg_name); force= true )
1028
- # Remove debug symbol libraries
1029
- if Sys. isapple ()
1030
- v = string (VERSION . major, " ." , VERSION . minor)
1031
- rm (joinpath (app_libdir, " libjulia.$v .dylib.dSYM" ); force= true , recursive= true )
1032
- rm (joinpath (app_libdir, " julia" , " sys.dylib.dSYM" ); force= true , recursive= true )
1028
+
1029
+
1030
+ # Goes into `lib/julia`
1031
+ const libjulia_list =
1032
+ if Sys. islinux ()
1033
+ [
1034
+ " libLLVM-*jl.so*"
1035
+ " libatomic.so*"
1036
+ " libgcc_s.so*"
1037
+ " libgmp.so*" # I guess the xx version is not needed?
1038
+ " libjulia-codegen.so*"
1039
+ " libjulia-internal.so*"
1040
+ " libmpfr.so*"
1041
+ " libopenlibm.so*"
1042
+ " libpcre2-8.so*"
1043
+ " libssp.so*"
1044
+ " libstdc++.so*"
1045
+ " libunwind.so*"
1046
+ " libuv.so*"
1047
+ " libz.so*"
1048
+ ]
1049
+ elseif Sys. isapple ()
1050
+ [
1051
+ " libLLVM*.dylib" # why no 13jl prefix here like for the others?
1052
+ " libatomic*.dylib"
1053
+ " libgcc_s*.dylib"
1054
+ " libgmp*.dylib"
1055
+ " libjulia-codegen*.dylib"
1056
+ " libjulia-internal*.dylib"
1057
+ " libmpfr*.dylib"
1058
+ " libopenlibm*.dylib"
1059
+ " libpcre2-8*.dylib"
1060
+ " libssp*.dylib"
1061
+ " libstdc++*.dylib"
1062
+ " libunwind*.dylib"
1063
+ " libuv*.dylib"
1064
+ " libz*.dylib"
1065
+ ]
1066
+ elseif Sys. iswindows ()
1067
+ [
1068
+ " libLLVM-*jl.dll"
1069
+ " libLTO.dll"
1070
+ " libatomic*.dll"
1071
+ " libgcc_s_seh*.dll"
1072
+ " libgmp*.dll"
1073
+ " libjulia-codegen.dll"
1074
+ " libjulia-internal.dll"
1075
+ " libjulia.dll"
1076
+
1077
+ # Why are these needed?
1078
+ " libRemarks.dll"
1079
+ " libmlir_async_runtime.dll"
1080
+ " libmlir_c_runner_utils.dll"
1081
+ " libmlir_runner_utils.dll"
1082
+
1083
+ " libmpfr*.dll"
1084
+ " libopenlibm.dll"
1085
+ " libpcre2*.dll"
1086
+ " libssp*.dll"
1087
+ " libuv-2.dll"
1088
+ " libwinpthread*.dll"
1089
+ " libz.dll"
1090
+ ]
1091
+ else
1092
+ error (" unknown os" )
1093
+ end
1094
+
1095
+
1096
+ # Goes into `lib`
1097
+ const lib_list = String[
1098
+ if Sys. islinux ()
1099
+ " libjulia.so*"
1100
+ elseif Sys. isapple ()
1101
+ " libjulia*.dylib"
1102
+ elseif Sys. iswindows ()
1103
+ end
1104
+ ]
1105
+
1106
+ if Base. USE_BLAS64
1107
+ const libsuffix = " 64_"
1108
+ else
1109
+ const libsuffix = " "
1110
+ end
1111
+
1112
+
1113
+ const jll_libs = Dict {String, Vector{String}} (
1114
+ " CompilerSupportLibraries_jll" =>
1115
+ [
1116
+ " libgomp"
1117
+ " libquadmath"
1118
+ " libgfortran"
1119
+ ],
1120
+ " dSFMT_jll" =>
1121
+ [
1122
+ " libdSFMT"
1123
+ ],
1124
+ " GMP_jll" =>
1125
+ [
1126
+ " libgmp"
1127
+ " libgmpxx"
1128
+ ],
1129
+ " libblastrampoline_jll" =>
1130
+ [
1131
+ " libblastrampoline"
1132
+ ],
1133
+ " LibCURL_jll" =>
1134
+ [
1135
+ " libcurl"
1136
+ ],
1137
+ " LibGit2_jll" =>
1138
+ [
1139
+ " libgit2"
1140
+ ],
1141
+ " libLLVM_jll" =>
1142
+ [
1143
+ " libLLVM"
1144
+ ],
1145
+ " LibSSH2_jll" =>
1146
+ [
1147
+ " libssh2"
1148
+ ],
1149
+ # Only on Linux?
1150
+ " LibUnwind_jll" =>
1151
+ [
1152
+ " libunwind"
1153
+ ],
1154
+ " LibUV_jll" =>
1155
+ [
1156
+ " libuv"
1157
+ ],
1158
+ # Only on Mac?
1159
+ " LLVMLibUnwind_jll" =>
1160
+ [
1161
+ " libunwind"
1162
+ ],
1163
+ " MbedTLS_jll" =>
1164
+ [
1165
+ " libmbedcrypto"
1166
+ " libmbedtls"
1167
+ " libmbedx509"
1168
+ ],
1169
+ " MPFR_jll:" =>
1170
+ [
1171
+ " libmpfr"
1172
+ ],
1173
+ " nghttp2_jll:" =>
1174
+ [
1175
+ " libnghttp2"
1176
+ ],
1177
+ " OpenBLAS_jll:" =>
1178
+ [
1179
+ " libopenblas$(libsuffix) "
1180
+ ],
1181
+ " OpenLibm_jll:" =>
1182
+ [
1183
+ " libopenlibm"
1184
+ ],
1185
+ " PCRE2_jll" =>
1186
+ [
1187
+ " libpcre2-8"
1188
+ ],
1189
+ " SuiteSparse_jll" =>
1190
+ [" libamd"
1191
+ " libbtf"
1192
+ " libcamd"
1193
+ " libccolamd"
1194
+ " libcholmod"
1195
+ " libcolamd"
1196
+ " libklu"
1197
+ " libldl"
1198
+ " librbio"
1199
+ " libspqr"
1200
+ " libsuitesparseconfig"
1201
+ " libumfpack"
1202
+ ],
1203
+ " Zlib_jll" =>
1204
+ [
1205
+ " libz"
1206
+ ],
1207
+ )
1208
+
1209
+ function glob_pattern_lib (lib)
1210
+ Sys. iswindows () ? lib * " .dll" :
1211
+ Sys. isapple () ? lib * " *.dylib" :
1212
+ Sys. islinux () ? lib* " .so*" :
1213
+ error (" unknown os" )
1214
+ end
1215
+
1216
+
1217
+
1218
+ # TODO : Detangle printing from business logic
1219
+ function bundle_julia_libraries (dest_dir, stdlibs)
1220
+ app_lib_dir = joinpath (dest_dir, Sys. isunix () ? " lib" : " bin" )
1221
+ app_libjulia_dir = Sys. isunix () ? joinpath (app_lib_dir, " julia" ) : app_lib_dir
1222
+ lib_dir = julia_libdir ()
1223
+ libjulia_dir = Sys. isunix () ? joinpath (lib_dir, " julia" ) : lib_dir
1224
+
1225
+ mkpath (app_lib_dir)
1226
+ Sys. isunix () && mkpath (app_libjulia_dir)
1227
+
1228
+ libs = Pair{String, String}
1229
+
1230
+ tot_libsize = 0
1231
+ printstyled (" PackageCompiler: bundled libraries:\n " )
1232
+
1233
+ println (" ├── Base:" )
1234
+ first = true
1235
+ for lib in libjulia_list
1236
+ matches = glob (lib, libjulia_dir)
1237
+ for match in matches
1238
+ mark = " ├──"
1239
+
1240
+ cp (match, joinpath (app_libjulia_dir, basename (match)))
1241
+ libsize = lstat (match). size
1242
+ tot_libsize += libsize
1243
+ if libsize > 1024
1244
+ println (" │ $mark " , basename (match), " - " , pretty_byte_str (libsize))
1245
+ first = false
1246
+ end
1247
+ end
1248
+ end
1249
+
1250
+ for lib in lib_list
1251
+ mark = " ├──"
1252
+ matches = glob (lib, lib_dir)
1253
+ for match in matches
1254
+ libsize = lstat (match). size
1255
+ tot_libsize += libsize
1256
+ if libsize > 1024
1257
+ println (" │ $mark " , basename (match), " - " , pretty_byte_str (libsize))
1258
+ end
1259
+ cp (match, joinpath (app_lib_dir, basename (match)))
1260
+ end
1033
1261
end
1262
+
1263
+ println (" ├── Stdlibs:" )
1264
+ for stdlib in stdlibs
1265
+ printed_stdlib = false
1266
+ libs = get (Vector{String}, jll_libs, stdlib)
1267
+ first_lib = true
1268
+ for lib in libs
1269
+ lib = glob_pattern_lib (lib)
1270
+ matches = glob (lib, libjulia_dir)
1271
+ for match in matches
1272
+ destpath = joinpath (app_libjulia_dir, basename (match))
1273
+ if ! isfile (destpath)
1274
+ if ! printed_stdlib && ! isempty (match)
1275
+ mark = " ├──"
1276
+ printed_stdlib = true
1277
+ println (" │ $mark " , stdlib)
1278
+ end
1279
+
1280
+ libsize = lstat (match). size
1281
+ mark = " ├──"
1282
+ if libsize > 1024
1283
+ println (" │ │ $mark " , basename (match), " - " , pretty_byte_str (libsize))
1284
+ first_lib = false
1285
+ end
1286
+ cp (match, destpath)
1287
+ tot_libsize += libsize
1288
+ end
1289
+ end
1290
+ end
1291
+ end
1292
+
1293
+ println (" Total library file size: " , pretty_byte_str (tot_libsize))
1294
+
1034
1295
return
1296
+
1035
1297
end
1036
1298
1037
1299
function recursive_dir_size (path)
@@ -1200,4 +1462,8 @@ function bundle_cert(dest_dir)
1200
1462
cp (cert_path, joinpath (share_path, " cert.pem" ))
1201
1463
end
1202
1464
1465
+ function bundle_libraries (src_dir, dest_dir)
1466
+
1467
+ end
1468
+
1203
1469
end # module
0 commit comments