@@ -9,16 +9,14 @@ const sysimage_binaries = (
99 " sys.o" , " sys.$(Libdl. dlext) " , " sys.ji" , " inference.o" , " inference.ji"
1010)
1111
12- function snoop (path, compilationfile, csv, reuse )
12+ function snoop (path, compilationfile, csv)
1313 cd (@__DIR__ )
1414 # Snoop compiler can't handle the path as a variable, so we just create a file
15- if ! reuse
16- open (joinpath (" snoopy.jl" ), " w" ) do io
17- println (io, " include(\" $(escape_string (path)) \" )" )
18- end
19- SnoopCompile. @snoop csv begin
20- include (" snoopy.jl" )
21- end
15+ open (joinpath (" snoopy.jl" ), " w" ) do io
16+ println (io, " include(\" $(escape_string (path)) \" )" )
17+ end
18+ SnoopCompile. @snoop csv begin
19+ include (" snoopy.jl" )
2220 end
2321 data = SnoopCompile. read (csv)
2422 pc = SnoopCompile. parcel (reverse! (data[2 ]))
@@ -40,12 +38,15 @@ function snoop(path, compilationfile, csv, reuse)
4038 # replace `_` for free parameters, which print out a warning otherwise
4139 ln = replace (ln, delims, s "\1 XXX\2 " )
4240 # only print out valid lines
43- # TODO figure out why some precompile statements have undefined free variables in there
41+ # TODO figure out the actual problems and why snoop compile emits invalid code
4442 try
45- eval (tmp_mod, parse (ln))
46- println (io, ln)
43+ parse (ln) # parse to make sure expression is parsing without error
44+ # wrap in try catch to catch problematic code emitted by SnoopCompile
45+ # without interupting the whole precompilation
46+ # (usually, SnoopCompile emits 1% erroring statements)
47+ println (io, " try\n " , ln, " \n end" )
4748 catch e
48- warn (" Not emitted: " , ln)
49+ warn (" Not emitted because code couldn't parse : " , ln)
4950 end
5051 end
5152 end
@@ -95,40 +96,84 @@ function get_root_dir(path)
9596 end
9697end
9798
99+ function snoop_package (package:: String , rel_snoop_file, sysimg_tmp, reuse)
100+ precompile_file = joinpath (sysimg_tmp, " precompile.jl" )
101+
102+ end
103+
104+ function sysimg_folder (files... )
105+ base_path = normpath (abspath (joinpath (@__DIR__ , " .." , " sysimg" )))
106+ isdir (base_path) || mkpath (base_path)
107+ normpath (abspath (joinpath (base_path, files... )))
108+ end
98109
99- function compile_package (package, force = false , reuse = false ; debug = false )
100- realpath = if ispath (package)
101- normpath (abspath (package))
102- else
103- Pkg. dir (package)
110+ function sysimgbackup_folder (files... )
111+ backup = sysimg_folder (" backup" )
112+ isdir (backup) || mkpath (backup)
113+ sysimg_folder (" backup" , files... )
114+ end
115+
116+
117+ function package_folder (package... )
118+ packages = normpath (abspath (joinpath (@__DIR__ , " .." , " packages" )))
119+ isdir (packages) || mkpath (packages)
120+ normpath (abspath (joinpath (packages, package... )))
121+ end
122+
123+
124+ function compile_package (packages... ; kw_args... )
125+ args = map (packages) do package
126+ # If no explicit path to a seperate precompile file, use runtests
127+ isa (package, String) && return (package, " test/runtests.jl" )
128+ isa (package, Tuple{String, String}) && return package
129+ error (" Unrecognized package. Use `packagename::String`, or (packagename::String, rel_path_to_testfile::String). Found: $package " )
104130 end
105- testroot = joinpath (realpath, " test" )
106- sysimg_tmp = normpath (joinpath (@__DIR__ , " .." , " sysimg_tmp" , get_root_dir (realpath)))
107- sysimg_backup = joinpath (@__DIR__ , " .." , " sysimg_backup" )
108- isdir (sysimg_backup) || mkpath (sysimg_tmp)
109- isdir (sysimg_tmp) || mkpath (sysimg_tmp)
110- precompile_file = joinpath (sysimg_tmp, " precompile.jl" )
111- snoop (
112- joinpath (testroot, " runtests.jl" ),
113- precompile_file,
114- joinpath (sysimg_tmp, " snooped.csv" ),
115- reuse
116- )
117- build_sysimg (joinpath (sysimg_tmp, " sys" ), " native" , precompile_file)
131+ compile_package (args... ; kw_args... )
132+ end
133+
134+ function snoop_userimg (userimg, packages:: Tuple{String, String} ...)
135+ snooped_precompiles = map (packages) do package_snoopfile
136+ package, snoopfile = package_snoopfile
137+ abs_package_path = if ispath (package)
138+ normpath (abspath (package))
139+ else
140+ Pkg. dir (package)
141+ end
142+ file2snoop = normpath (abspath (joinpath (abs_package_path, snoopfile)))
143+ package = package_folder (get_root_dir (abs_package_path))
144+ isdir (package) || mkpath (package)
145+ precompile_file = joinpath (package, " precompile.jl" )
146+ snoop (
147+ file2snoop,
148+ precompile_file,
149+ joinpath (package, " snooped.csv" )
150+ )
151+ precompile_file
152+ end
153+ open (userimg, " w" ) do io
154+ for path in snooped_precompiles
155+ write (io, open (read, path))
156+ println (io)
157+ end
158+ end
159+ userimg
160+ end
161+
162+ function compile_package (packages:: Tuple{String, String} ...; force = false , reuse = false , debug = false )
163+ userimg = sysimg_folder (" precompile.jl" )
164+ if ! reuse
165+ snoop_userimg (userimg, packages... )
166+ end
167+ ! isfile (userimg) && reuse && error (" Nothing to reuse. Please run `compile_package(reuse = true)`" )
168+ image_path = sysimg_folder (" sys" )
169+ build_sysimg (image_path, " native" , userimg)
118170 if force
119171 try
120- syspath = default_sysimg_path (debug)
121- for file in sysimage_binaries
122- # backup
123- bfile = joinpath (sysimg_backup, file)
124- sfile = joinpath (dirname (syspath), file)
125- if ! isfile (bfile) # use the one that is already there
126- mv (sfile, bfile, remove_destination = true )
127- else
128- mv (sfile, sfile* " .old" , remove_destination = true ) # remove so we don't overwrite (seems to be problematic on windows)
129- end
130- mv (joinpath (sysimg_tmp, file), sfile, remove_destination = false )
131- end
172+ replace_jl_sysimg (debug)
173+ info (
174+ " Replaced system image successfully. Next start of julia will load the newly compiled system image.
175+ If you encounter any errors with the new julia image, try `PackageCompiler.revert([debug = false])`"
176+ )
132177 catch e
133178 warn (" An error has occured while replacing sysimg files:" )
134179 warn (e)
@@ -138,9 +183,26 @@ function compile_package(package, force = false, reuse = false; debug = false)
138183 else
139184 info ("""
140185 Not replacing system image.
141- You can start julia with julia -J $(joinpath (sysimg_tmp, " sys " ) ) to load the compiled files.
186+ You can start julia with julia -J $(image_path ) to load the compiled files.
142187 """ )
143188 end
144189end
145190
191+
192+ function replace_jl_sysimg (debug = false )
193+ syspath = default_sysimg_path (debug)
194+ for file in sysimage_binaries
195+ # backup
196+ bfile = sysimgbackup_folder (file)
197+ sfile = joinpath (dirname (syspath), file)
198+ if ! isfile (bfile) # use the one that is already there
199+ mv (sfile, bfile, remove_destination = true )
200+ else
201+ mv (sfile, sfile* " .old" , remove_destination = true ) # remove so we don't overwrite (seems to be problematic on windows)
202+ end
203+ mv (joinpath (sysimg_tmp, file), sfile, remove_destination = false )
204+ end
205+ end
206+
207+
146208end # module
0 commit comments