Skip to content

Commit 8987c26

Browse files
authored
Merge pull request #175 from JuliaLang/sd-precompile_toml
precompile toml
2 parents c168129 + b96b341 commit 8987c26

File tree

3 files changed

+59
-92
lines changed

3 files changed

+59
-92
lines changed

src/PackageCompiler.jl

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,20 @@ use a toml instead.
110110
"""
111111
function compile_package(
112112
packages::Tuple{String, String}...;
113-
force = false, reuse = false, debug = false, cpu_target = nothing,
114-
additional_packages = Symbol[], verbose = false
113+
force = false, reuse = false, debug = false,
114+
cpu_target = nothing, verbose = false
115115
)
116116
userimg = sysimg_folder("precompile.jl")
117117
if !reuse
118-
snoop_userimg(userimg, packages...; additional_packages = additional_packages)
118+
# TODO that's a pretty weak way to check that it's not a path...
119+
ispackage = all(x-> !occursin(Base.Filesystem.path_separator, x), first.(packages))
120+
isruntests = all(x-> x == "test/runtests.jl", last.(packages))
121+
if ispackage && isruntests
122+
snoop_packages(Symbol.(first.(packages))...; file = userimg)
123+
else
124+
ispackage || @warn "Giving path to package deprecated. Use Package name!"
125+
isruntests || @warn "Giving a snoopfile is deprecated. Use runtests from package!"
126+
end
119127
end
120128
!isfile(userimg) && reuse && error("Nothing to reuse. Please run `compile_package(reuse = true)`")
121129
image_path = sysimg_folder()
@@ -127,10 +135,12 @@ function compile_package(
127135
backup = syspath * ".packagecompiler_backup"
128136
isfile(backup) || mv(syspath, backup)
129137
cp(imgfile, syspath)
130-
@info """Replaced system image successfully. Next start of julia will load the newly compiled system image.
131-
If you encounter any errors with the new julia image, try `PackageCompiler.revert([debug = false])`."""
138+
@info """
139+
Replaced system image successfully. Next start of julia will load the newly compiled system image.
140+
If you encounter any errors with the new julia image, try `PackageCompiler.revert([debug = false])`.
141+
"""
132142
catch e
133-
@warn "An error occured while replacing sysimg files:" error=e
143+
@warn "An error occured while replacing sysimg files:" error = e
134144
@info "Recovering old system image from backup"
135145
# if any file is missing in default system image, revert!
136146
if !isfile(syspath)
@@ -139,18 +149,14 @@ function compile_package(
139149
end
140150
end
141151
else
142-
@info """Not replacing system image.
143-
You can start julia with $(`julia -J $imgfile`) at a posix shell to load the compiled files."""
152+
@info """
153+
Not replacing system image.
154+
You can start julia with $(`julia -J $imgfile`) at a posix shell to load the compiled files.
155+
"""
144156
end
145157
imgfile
146158
end
147159

148-
function __init__()
149-
if Base.julia_cmd().exec[2] != "-Cnative"
150-
@warn "Your Julia system image is not compiled natively for this CPU architecture.\n" *
151-
"Please run `PackageCompiler.force_native_image!()` for optimal Julia performance."
152-
end
153-
end
154160

155161
export compile_package, revert, force_native_image!, executable_ext, build_executable, build_shared_lib, static_julia, compile_incremental
156162

src/incremental.jl

Lines changed: 6 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -72,23 +72,10 @@ end
7272
To compile just a single package, see the simpler version `compile_incremental(package::Symbol)`:
7373
"""
7474
function compile_incremental(
75-
toml_path::Union{String, Nothing}, snoopfile::Union{String, Nothing};
76-
force = false, precompile_file = nothing, verbose = true,
75+
toml_path::Union{String, Nothing}, precompiles::String;
76+
force = false, verbose = true,
7777
debug = false, cc_flags = nothing
7878
)
79-
precompiles = package_folder("incremental_precompile.jl")
80-
81-
if snoopfile == nothing && precompile_file != nothing
82-
# we directly got a precompile_file
83-
isfile(precompile_file) || error("Need to pass an existing file to precompile_file. Found: $(repr(precompile_file))")
84-
if precompile_file != precompiles
85-
cp(precompile_file, precompiles, force = true)
86-
end
87-
elseif snoopfile == nothing && precompile_file == nothing
88-
# reuse precompiles
89-
else
90-
snoop(nothing, toml_path, snoopfile, precompiles)
91-
end
9279
systemp = sysimg_folder("sys.a")
9380
sysout = sysimg_folder("sys.$(Libdl.dlext)")
9481
code = PrecompileCommand(precompiles)
@@ -104,7 +91,7 @@ end
10491

10592
"""
10693
compile_incremental(
107-
package::Symbol;
94+
packages::Symbol...;
10895
force = false, reuse = false, verbose = true,
10996
debug = false, cc_flags = nothing
11097
)
@@ -117,38 +104,7 @@ end
117104
For a more explicit version of compile_incremental, see:
118105
`compile_incremental(toml_path::String, snoopfile::String)`
119106
"""
120-
function compile_incremental(package::Symbol; kw...)
121-
toml, testfile = package_toml(package)
122-
compile_incremental(toml, testfile; kw...)
123-
end
124-
125-
126-
function compile_incremental(packages::Symbol...; kw...)
127-
finaltoml = Dict{Any, Any}(
128-
"deps" => Dict(),
129-
"compat" => Dict(),
130-
)
131-
precompiles_all = package_folder("incremental_precompile.jl")
132-
open(precompiles_all, "w") do compile_io
133-
println(compile_io, "# Precompile file for $(join(packages, " "))")
134-
for package in packages
135-
precompiles = package_folder(string(package), "incremental_precompile.jl")
136-
toml, testfile = package_toml(package)
137-
snoop(package, toml, testfile, precompiles)
138-
pkg_toml = TOML.parsefile(toml)
139-
merge!(finaltoml["deps"], get(pkg_toml, "deps", Dict()))
140-
merge!(finaltoml["compat"], get(pkg_toml, "compat", Dict()))
141-
println(compile_io)
142-
write(compile_io, read(precompiles))
143-
end
144-
end
145-
toml = package_folder("Project.toml")
146-
finaltoml["name"] = "PackagesPrecompile"
147-
open(toml, "w") do io
148-
TOML.print(
149-
io, finaltoml,
150-
sorted = true, by = key-> (Types.project_key_order(key), key)
151-
)
152-
end
153-
compile_incremental(toml, nothing; precompile_file = precompiles_all)
107+
function compile_incremental(pkg::Symbol, packages::Symbol...; kw...)
108+
toml, precompile = snoop_packages(pkg, packages...)
109+
compile_incremental(toml, precompile; kw...)
154110
end

src/snooping.jl

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,15 @@ function snoop(package, tomlpath, snoopfile, outputfile, reuse = false)
3434
if package != nothing
3535
push!(used_packages, string(package))
3636
end
37+
usings = ""
3738
if tomlpath != nothing
3839
# add toml packages, in case extract_used_packages misses a package
3940
deps = get(TOML.parsefile(tomlpath), "deps", Dict{String, Any}())
4041
union!(used_packages, string.(keys(deps)))
4142
end
42-
usings = if isempty(used_packages)
43-
""
44-
else
43+
if !isempty(used_packages)
4544
packages = join(used_packages, ", ")
46-
"""
45+
usings *= """
4746
using $packages
4847
for Mod in [$packages]
4948
isdefined(Mod, :__init__) && Mod.__init__()
@@ -98,31 +97,37 @@ function snoop(package, tomlpath, snoopfile, outputfile, reuse = false)
9897
end
9998

10099

101-
"""
102-
snoop_userimg(userimg, packages::Tuple{String, String}...)
103-
104-
Traces all function calls in packages and writes out `precompile` statements into the file `userimg`
105-
"""
106-
function snoop_userimg(userimg, packages::Tuple{String, String}...; additional_packages = Symbol[])
107-
snooped_precompiles = map(packages) do package_snoopfile
108-
package, snoopfile = package_snoopfile
109-
module_name = Symbol(package)
110-
toml, runtests = package_toml(module_name)
111-
pkg_root = normpath(joinpath(dirname(runtests), ".."))
112-
file2snoop = if isfile(pkg_root, snoopfile)
113-
joinpath(pkg_root, snoopfile)
114-
else
115-
joinpath(pkg_root, snoopfile)
100+
function snoop_packages(packages::Symbol...; file = package_folder("incremental_precompile.jl"))
101+
finaltoml = Dict{Any, Any}(
102+
"deps" => Dict(),
103+
"compat" => Dict(),
104+
)
105+
toml_path = package_folder("Project.toml")
106+
open(file, "w") do compile_io
107+
println(compile_io, "# Precompile file for $(join(packages, " "))")
108+
# make sure we have all packages from toml installed
109+
println(compile_io, """
110+
using Pkg
111+
Pkg.activate($(repr(toml_path)))
112+
Pkg.instantiate()
113+
""")
114+
for package in packages
115+
precompiles = package_folder(string(package), "incremental_precompile.jl")
116+
toml, testfile = package_toml(package)
117+
snoop(package, toml, testfile, precompiles)
118+
pkg_toml = TOML.parsefile(toml)
119+
merge!(finaltoml["deps"], get(pkg_toml, "deps", Dict()))
120+
merge!(finaltoml["compat"], get(pkg_toml, "compat", Dict()))
121+
println(compile_io)
122+
write(compile_io, read(precompiles))
116123
end
117-
precompile_file = package_folder(package, "precompile.jl")
118-
snoop(package, toml, file2snoop, precompile_file)
119-
return precompile_file
120124
end
121-
# merge all of the temporary files into a single output
122-
open(userimg, "w") do output
123-
for path in snooped_precompiles
124-
open(input -> write(output, input), path)
125-
end
125+
finaltoml["name"] = "PackagesPrecompile"
126+
open(toml_path, "w") do io
127+
TOML.print(
128+
io, finaltoml,
129+
sorted = true, by = key-> (Types.project_key_order(key), key)
130+
)
126131
end
127-
nothing
132+
return toml_path, file
128133
end

0 commit comments

Comments
 (0)