11__precompile__ ()
22module PackageCompiler
33
4+
5+ # TODO : remove once Julia v0.7 is released
6+ const julia_v07 = VERSION > v " 0.7-"
7+
8+
49using SnoopCompile
10+ using ArgParse
11+ julia_v07 && using Libdl
512
13+
14+ include (" juliac.jl" )
615include (" build_sysimg.jl" )
16+ include (" snooping.jl" )
717
818const sysimage_binaries = (
919 " sys.o" , " sys.$(Libdl. dlext) " , " sys.ji" , " inference.o" , " inference.ji"
1020)
1121
12- function snoop (path, compilationfile, csv)
13- cd (@__DIR__ )
14- # Snoop compiler can't handle the path as a variable, so we just create a file
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" )
20- end
21- data = SnoopCompile. read (csv)
22- pc = SnoopCompile. parcel (reverse! (data[2 ]))
23- delims = r" ([\{\} \n\(\) ,])_([\{\} \n\(\) ,])"
24- tmp_mod = eval (:(module $ (gensym ()) end ))
25- open (compilationfile, " w" ) do io
26- for (k, v) in pc
27- k == :unknown && continue
28- try
29- eval (tmp_mod, :(using $ k))
30- println (io, " using $k " )
31- info (" using $k " )
32- catch e
33- println (" Module not found: $k " )
34- end
35- end
36- for (k, v) in pc
37- for ln in v
38- # replace `_` for free parameters, which print out a warning otherwise
39- ln = replace (ln, delims, s "\1 XXX\2 " )
40- # only print out valid lines
41- # TODO figure out the actual problems and why snoop compile emits invalid code
42- try
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" )
48- catch e
49- warn (" Not emitted because code couldn't parse: " , ln)
50- end
51- end
52- end
53- end
54- end
5522
5623function copy_system_image (src, dest, ignore_missing = false )
5724 for file in sysimage_binaries
@@ -67,6 +34,19 @@ function copy_system_image(src, dest, ignore_missing = false)
6734 end
6835end
6936
37+ """
38+ Replaces the julia system image forcefully with a system image located at `image_path`
39+ """
40+ function replace_jl_sysimg (image_path, debug = false )
41+ syspath = default_sysimg_path (debug)
42+ backup = sysimgbackup_folder ()
43+ # create a backup
44+ # if syspath has missing files, ignore, since it will get replaced anyways
45+ copy_system_image (syspath, backup, true )
46+ info (" Overwriting system image!" )
47+ copy_system_image (image_path, syspath)
48+ end
49+
7050
7151"""
7252Builds a clean system image, similar to a fresh Julia install.
@@ -140,38 +120,7 @@ function compile_package(packages...; kw_args...)
140120 compile_package (args... ; kw_args... )
141121end
142122
143- """
144- snoop_userimg(userimg, packages::Tuple{String, String}...)
145123
146- Traces all function calls in packages and writes out `precompile` statements into the file `userimg`
147- """
148- function snoop_userimg (userimg, packages:: Tuple{String, String} ...)
149- snooped_precompiles = map (packages) do package_snoopfile
150- package, snoopfile = package_snoopfile
151- abs_package_path = if ispath (package)
152- normpath (abspath (package))
153- else
154- Pkg. dir (package)
155- end
156- file2snoop = normpath (abspath (joinpath (abs_package_path, snoopfile)))
157- package = package_folder (get_root_dir (abs_package_path))
158- isdir (package) || mkpath (package)
159- precompile_file = joinpath (package, " precompile.jl" )
160- snoop (
161- file2snoop,
162- precompile_file,
163- joinpath (package, " snooped.csv" )
164- )
165- precompile_file
166- end
167- open (userimg, " w" ) do io
168- for path in snooped_precompiles
169- write (io, open (read, path))
170- println (io)
171- end
172- end
173- userimg
174- end
175124
176125
177126"""
@@ -187,11 +136,12 @@ function compile_package(packages::Tuple{String, String}...; force = false, reus
187136 snoop_userimg (userimg, packages... )
188137 end
189138 ! isfile (userimg) && reuse && error (" Nothing to reuse. Please run `compile_package(reuse = true)`" )
190- image_path = sysimg_folder (" sys " )
139+ image_path = sysimg_folder ()
191140 build_sysimg (image_path, " native" , userimg)
141+ imgfile = joinpath (image_path, " sys.$(Libdl. dlext) " )
192142 if force
193143 try
194- replace_jl_sysimg (sysimg_folder () , debug)
144+ replace_jl_sysimg (image_path , debug)
195145 info (
196146 " Replaced system image successfully. Next start of julia will load the newly compiled system image.
197147 If you encounter any errors with the new julia image, try `PackageCompiler.revert([debug = false])`"
@@ -213,28 +163,15 @@ function compile_package(packages::Tuple{String, String}...; force = false, reus
213163 else
214164 info ("""
215165 Not replacing system image.
216- You can start julia with julia -J $(image_path ) to load the compiled files.
166+ You can start julia with julia -J $(imgfile ) to load the compiled files.
217167 """ )
218168 end
169+ imgfile
219170end
220171
221- """
222- Replaces the julia system image forcefully with a system image located at `image_path`
223- """
224- function replace_jl_sysimg (image_path, debug = false )
225- syspath = default_sysimg_path (debug)
226- backup = sysimgbackup_folder ()
227- # create a backup
228- # if syspath has missing files, ignore, since it will get replaced anyways
229- copy_system_image (syspath, backup, true )
230- info (" Overwriting system image!" )
231- copy_system_image (image_path, syspath)
232- end
233172
234173
235174export compile_package, revert, build_clean_image
236175
237176
238177end # module
239-
240-
0 commit comments