Skip to content

Commit fe53c05

Browse files
authored
Merge pull request #4 from SimonDanisch/sd/cleanup
fixes, multiple packages, more modularity
2 parents 85df43b + 6684a65 commit fe53c05

File tree

6 files changed

+130
-61
lines changed

6 files changed

+130
-61
lines changed

.travis.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,16 @@ os:
66
julia:
77
- 0.6
88
- nightly
9+
matrix:
10+
allow_failures:
11+
- julia: nightly
12+
913
notifications:
1014
email: false
1115
git:
1216
depth: 99999999
1317

18+
1419
## uncomment the following lines to allow failures on nightly julia
1520
## (tests will run but not make your overall status red)
1621
#matrix:

appveyor.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ environment:
22
matrix:
33
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.6/julia-0.6-latest-win32.exe"
44
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.6/julia-0.6-latest-win64.exe"
5-
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe"
6-
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe"
75

86
## uncomment the following lines to allow failures on nightly julia
97
## (tests will run but not make your overall status red)

src/PackageCompiler.jl

Lines changed: 105 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -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"\1XXX\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, "\nend")
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
9697
end
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
144189
end
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+
146208
end # module

src/build_sysimg.jl

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,7 @@ current processor. Include the user image file given by `userimg_path`, which sh
5353
directives such as `using MyPackage` to include that package in the new system image. New
5454
system image will not replace an older image unless `force` is set to true.
5555
"""
56-
function build_sysimg(sysimg_path, cpu_target = "native", userimg_path = nothing; debug=false)
57-
58-
# Canonicalize userimg_path before we enter the base_dir
59-
if userimg_path !== nothing
60-
userimg_path = abspath(userimg_path)
61-
end
56+
function build_sysimg(sysimg_path, cpu_target, userimg_path; debug = false)
6257
# Enter base and setup some useful paths
6358
base_dir = dirname(Base.find_source_file("sysimg.jl"))
6459
cd(base_dir) do
@@ -74,15 +69,13 @@ function build_sysimg(sysimg_path, cpu_target = "native", userimg_path = nothing
7469
end
7570

7671
# Copy in userimg.jl if it exists
77-
if userimg_path !== nothing
78-
if !isfile(userimg_path)
79-
error("$userimg_path is not found, ensure it is an absolute path.")
80-
end
81-
if isfile("userimg.jl")
82-
error("$base_dir/userimg.jl already exists, delete manually to continue.")
83-
end
84-
cp(userimg_path, "userimg.jl")
72+
if !isfile(userimg_path)
73+
error("$userimg_path is not found, ensure it is an absolute path.")
74+
end
75+
if isfile("userimg.jl")
76+
error("$base_dir/userimg.jl already exists, delete manually to continue.")
8577
end
78+
cp(userimg_path, "userimg.jl")
8679
try
8780
# Start by building inference.{ji,o}
8881
inference_path = joinpath(dirname(sysimg_path), "inference")
@@ -99,7 +92,7 @@ function build_sysimg(sysimg_path, cpu_target = "native", userimg_path = nothing
9992

10093
finally
10194
# Cleanup userimg.jl
102-
if userimg_path !== nothing && isfile("userimg.jl")
95+
if isfile("userimg.jl")
10396
rm("userimg.jl")
10497
end
10598
end

test/REQUIRE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
Matcha
2+
UnicodeFun

test/runtests.jl

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,15 @@ using Base.Test
33

44
# If this works without error we should be in pretty good shape!
55
# This command will use the runtest.jl of Matcha to find out what functions to precompile!
6-
PackageCompiler.compile_package("Matcha", false) # false to not force overwriting julia's current system image
6+
PackageCompiler.compile_package("Matcha", "UnicodeFun", force = false, reuse = false) # false to not force overwriting julia's current system image
7+
# build again, with resuing the snoop file
8+
PackageCompiler.compile_package("Matcha", "UnicodeFun", force = false, reuse = true)
79
# TODO test revert - I suppose i wouldn't have enough rights on travis to move around dll's?
10+
11+
@testset "basic tests" begin
12+
@test isfile(PackageCompiler.sysimg_folder("sys.$(Libdl.dlext)"))
13+
userimg = PackageCompiler.sysimg_folder("precompile.jl")
14+
@test isfile(userimg)
15+
# Make sure we actually snooped stuff
16+
@test length(readlines(userimg)) > 700
17+
end

0 commit comments

Comments
 (0)