diff --git a/README.md b/README.md
index e8808087..ead14baa 100644
--- a/README.md
+++ b/README.md
@@ -64,12 +64,15 @@ Run `juliac.jl -h` for help:
```
usage: juliac.jl [-v] [-q] [-d
] [-n ] [-c] [-a] [-o] [-s]
- [-e] [-j] [-J ] [--compile {yes|no|all|min}]
- [-C ] [-O {0,1,2,3}] [-g {0,1,2}]
- [--inline {yes|no}] [--check-bounds {yes|no}]
- [--math-mode {ieee,fast}] [--depwarn {yes|no|error}]
- [--cc ] [--cc-flags ] [--version] [-h]
- juliaprog [cprog]
+ [-e] [-j] [-J ] [--precompiled {yes|no}]
+ [--compilecache {yes|no}] [-H ]
+ [--startup-file {yes|no}] [--handle-signals {yes|no}]
+ [--compile {yes|no|all|min}] [-C ]
+ [-O {0,1,2,3}] [-g ] [--inline {yes|no}]
+ [--check-bounds {yes|no}] [--math-mode {ieee,fast}]
+ [--depwarn {yes|no|error}] [--cc ]
+ [--cc-flags ] [--version] [-h] juliaprog
+ [cprog]
Static Julia Compiler
@@ -92,15 +95,27 @@ optional arguments:
-j, --julialibs copy Julia libraries to build directory
-J, --sysimage
start up with the given system image file
+ --precompiled {yes|no}
+ use precompiled code from system image if
+ available
+ --compilecache {yes|no}
+ enable/disable incremental precompilation of
+ modules
+ -H, --home set location of `julia` executable
+ --startup-file {yes|no}
+ load ~/.juliarc.jl
+ --handle-signals {yes|no}
+ enable or disable Julia's default signal
+ handlers
--compile {yes|no|all|min}
enable or disable JIT compiler, or request
exhaustive compilation
-C, --cpu-target
limit usage of CPU features up to
- (forces --precompiled=no)
+ (implies default `--precompiled=no`)
-O, --optimize {0,1,2,3}
set the optimization level (type: Int64)
- -g {0,1,2} enable / set the level of debug info
+ -g enable / set the level of debug info
generation (type: Int64)
--inline {yes|no} control whether inlining is permitted
--check-bounds {yes|no}
diff --git a/juliac.jl b/juliac.jl
index 5b051dd3..aef14d9f 100644
--- a/juliac.jl
+++ b/juliac.jl
@@ -50,45 +50,69 @@ Base.@ccallable function julia_main(args::Vector{String})::Cint
arg_type = String
metavar = ""
help = "start up with the given system image file"
+ "--precompiled"
+ arg_type = String
+ metavar = "{yes|no}"
+ range_tester = (x -> x ∈ ("yes", "no"))
+ help = "use precompiled code from system image if available"
+ "--compilecache"
+ arg_type = String
+ metavar = "{yes|no}"
+ range_tester = (x -> x ∈ ("yes", "no"))
+ help = "enable/disable incremental precompilation of modules"
+ "--home", "-H"
+ arg_type = String
+ metavar = ""
+ help = "set location of `julia` executable"
+ "--startup-file"
+ arg_type = String
+ metavar = "{yes|no}"
+ range_tester = (x -> x ∈ ("yes", "no"))
+ help = "load ~/.juliarc.jl"
+ "--handle-signals"
+ arg_type = String
+ metavar = "{yes|no}"
+ range_tester = (x -> x ∈ ("yes", "no"))
+ help = "enable or disable Julia's default signal handlers"
"--compile"
arg_type = String
metavar = "{yes|no|all|min}"
- range_tester = (x -> x == "yes" || x == "no" || x == "all" || x == "min")
+ range_tester = (x -> x ∈ ("yes", "no", "all", "min"))
help = "enable or disable JIT compiler, or request exhaustive compilation"
"--cpu-target", "-C"
arg_type = String
metavar = ""
- help = "limit usage of CPU features up to (forces --precompiled=no)"
+ help = "limit usage of CPU features up to (implies default `--precompiled=no`)"
"--optimize", "-O"
arg_type = Int
metavar = "{0,1,2,3}"
- range_tester = (x -> 0 <= x <= 3)
+ range_tester = (x -> x ∈ (0, 1, 2, 3))
help = "set the optimization level"
"-g"
arg_type = Int
dest_name = "debug"
- metavar = "{0,1,2}"
- range_tester = (x -> 0 <= x <= 2)
+ metavar = ""
+ range_tester = (x -> x ∈ (0, 1, 2))
help = "enable / set the level of debug info generation"
"--inline"
arg_type = String
metavar = "{yes|no}"
- range_tester = (x -> x == "yes" || x == "no")
+ range_tester = (x -> x ∈ ("yes", "no"))
help = "control whether inlining is permitted"
"--check-bounds"
arg_type = String
metavar = "{yes|no}"
- range_tester = (x -> x == "yes" || x == "no")
+ range_tester = (x -> x ∈ ("yes", "no"))
help = "emit bounds checks always or never"
"--math-mode"
arg_type = String
metavar = "{ieee,fast}"
- range_tester = (x -> x == "ieee" || x == "fast")
+ range_tester = (x -> x ∈ ("ieee", "fast"))
help = "disallow or enable unsafe floating point optimizations"
"--depwarn"
arg_type = String
metavar = "{yes|no|error}"
- range_tester = (x -> x == "yes" || x == "no" || x == "error")
+ range_tester = (x -> x ∈ ("yes", "no", "error"))
help = "enable or disable syntax and method deprecation warnings"
"--cc"
arg_type = String
diff --git a/src/api.jl b/src/api.jl
index a74526ff..20159759 100644
--- a/src/api.jl
+++ b/src/api.jl
@@ -10,41 +10,43 @@ current processor. Include the user image file given by `userimg_path`, which sh
directives such as `using MyPackage` to include that package in the new system image. New
system image will not replace an older image unless `force` is set to true.
"""
-function build_sysimg(sysimg_path, userimg_path = nothing;
+function build_sysimg(
+ sysimg_path, userimg_path = nothing;
verbose = false, quiet = false,
- cpu_target = nothing, optimize = nothing,
- debug = nothing, inline = nothing, check_bounds = nothing,
- math_mode = nothing
+ precompiled = nothing, compilecache = nothing,
+ home = nothing, startup_file = nothing, handle_signals = nothing,
+ compile = nothing, cpu_target = nothing, optimize = nothing, debug = nothing,
+ inline = nothing, check_bounds = nothing, math_mode = nothing, depwarn = nothing
)
# build vanilla backup system image
clean_sysimg = get_backup!(contains(basename(Base.julia_cmd().exec[1]), "debug"), cpu_target)
static_julia(
- userimg_path, outname = "sys",
- cpu_target = cpu_target, optimize = optimize,
- debug = debug, inline = inline, check_bounds = check_bounds,
- math_mode = math_mode, verbose = verbose, quiet = quiet,
- cprog = nothing, builddir = sysimg_path,
- clean = false, sysimage = clean_sysimg,
- compile = nothing, depwarn = nothing, autodeps = false,
- object = true, shared = true, executable = false, julialibs = false,
+ userimg_path, verbose = verbose, quiet = quiet,
+ builddir = sysimg_path, outname = "sys",
+ object = true, shared = true,
+ sysimage = clean_sysimg, precompiled = precompiled, compilecache = compilecache,
+ home = home, startup_file = startup_file, handle_signals = handle_signals,
+ compile = compile, cpu_target = cpu_target, optimize = optimize, debug = debug,
+ inline = inline, check_bounds = check_bounds, math_mode = math_mode, depwarn = depwarn
)
end
function build_shared_lib(
library, library_name;
verbose = false, quiet = false,
- cpu_target = nothing, optimize = nothing, debug = nothing,
- inline = nothing, check_bounds = nothing, math_mode = nothing
+ sysimage = nothing, precompiled = nothing, compilecache = nothing,
+ home = nothing, startup_file = nothing, handle_signals = nothing,
+ compile = nothing, cpu_target = nothing, optimize = nothing, debug = nothing,
+ inline = nothing, check_bounds = nothing, math_mode = nothing, depwarn = nothing
)
static_julia(
- library, outname = library_name,
- cpu_target = cpu_target, optimize = optimize,
- debug = debug, inline = inline, check_bounds = check_bounds,
- math_mode = math_mode, verbose = verbose, quiet = quiet,
- cprog = nothing, builddir = sysimg_path,
- clean = false, sysimage = nothing,
- compile = nothing, depwarn = nothing, autodeps = false,
- object = true, shared = true, executable = false, julialibs = true,
+ library, verbose = verbose, quiet = quiet,
+ builddir = sysimg_path, outname = library_name,
+ object = true, shared = true, julialibs = true,
+ sysimage = sysimage, precompiled = precompiled, compilecache = compilecache,
+ home = home, startup_file = startup_file, handle_signals = handle_signals,
+ compile = compile, cpu_target = cpu_target, optimize = optimize, debug = debug,
+ inline = inline, check_bounds = check_bounds, math_mode = math_mode, depwarn = depwarn
)
end
@@ -52,8 +54,8 @@ end
build_executable(
library,
library_name = splitext(basename(library))[1],
- cprogram = joinpath(@__DIR__, "..", "examples", "program.c");
- snoopfile = nothing, builddir = "build",
+ cprog = joinpath(@__DIR__, "..", "examples", "program.c");
+ snoopfile = nothing, builddir = "builddir",
verbose = false, quiet = false,
cpu_target = nothing, optimize = nothing, debug = nothing,
inline = nothing, check_bounds = nothing, math_mode = nothing
@@ -63,13 +65,14 @@ end
`builddir` is where library_name.exe and shared libraries will end up
"""
function build_executable(
- library,
- library_name = splitext(basename(library))[1],
- cprogram = joinpath(@__DIR__, "..", "examples", "program.c");
- snoopfile = nothing, builddir = "build",
+ library, library_name = splitext(basename(library))[1],
+ cprog = joinpath(@__DIR__, "..", "examples", "program.c");
+ snoopfile = nothing, builddir = "builddir",
verbose = false, quiet = false,
- cpu_target = nothing, optimize = nothing, debug = nothing,
- inline = nothing, check_bounds = nothing, math_mode = nothing
+ sysimage = nothing, precompiled = nothing, compilecache = nothing,
+ home = nothing, startup_file = nothing, handle_signals = nothing,
+ compile = nothing, cpu_target = nothing, optimize = nothing, debug = nothing,
+ inline = nothing, check_bounds = nothing, math_mode = nothing, depwarn = nothing
)
if snoopfile != nothing
precompfile = joinpath(builddir, "precompiled.jl")
@@ -82,14 +85,13 @@ function build_executable(
library = jlmain
end
static_julia(
- library, outname = library_name,
- cpu_target = cpu_target, optimize = optimize,
- debug = debug, inline = inline, check_bounds = check_bounds,
- math_mode = math_mode, verbose = verbose, quiet = quiet,
- cprog = cprogram, builddir = builddir,
- clean = false, sysimage = nothing,
- compile = nothing, depwarn = nothing, autodeps = false,
+ library, cprog = cprog, verbose = verbose, quiet = quiet,
+ builddir = builddir, outname = library_name,
object = true, shared = true, executable = true, julialibs = true,
+ sysimage = sysimage, precompiled = precompiled, compilecache = compilecache,
+ home = home, startup_file = startup_file, handle_signals = handle_signals,
+ compile = compile, cpu_target = cpu_target, optimize = optimize, debug = debug,
+ inline = inline, check_bounds = check_bounds, math_mode = math_mode, depwarn = depwarn
)
end
diff --git a/src/snooping.jl b/src/snooping.jl
index abe40dd9..3bf839ec 100644
--- a/src/snooping.jl
+++ b/src/snooping.jl
@@ -6,8 +6,8 @@ function snoop_vanilla(filename, path)
end
"""
julia_cmd = build_julia_cmd(
- get_backup!(false, nothing), nothing, nothing, nothing, nothing,
- nothing, nothing, nothing, nothing, false
+ get_backup!(false, nothing), nothing, nothing, nothing, nothing, nothing,
+ nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing
)
@show julia_cmd
in, io = open(`$julia_cmd --eval $code_object`, "w", STDOUT)
diff --git a/src/static_julia.jl b/src/static_julia.jl
index e4216316..2f29007a 100644
--- a/src/static_julia.jl
+++ b/src/static_julia.jl
@@ -42,10 +42,15 @@ compiles the Julia file at path `juliaprog` with keyword arguments:
executable build executable file
julialibs copy Julia libraries to build directory
sysimage start up with the given system image file
+ precompiled {yes|no} use precompiled code from system image if available
+ compilecache {yes|no} enable/disable incremental precompilation of modules
+ home set location of `julia` executable
+ startup_file {yes|no} load ~/.juliarc.jl
+ handle_signals {yes|no} enable or disable Julia's default signal handlers
compile {yes|no|all|min} enable or disable JIT compiler, or request exhaustive compilation
cpu_target limit usage of CPU features up to (forces --precompiled=no)
optimize {0,1,2,3} set the optimization level
- debug {0,1,2} enable / set the level of debug info generation
+ debug enable / set the level of debug info generation
inline {yes|no} control whether inlining is permitted
check_bounds {yes|no} emit bounds checks always or never
math_mode {ieee,fast} disallow or enable unsafe floating point optimizations
@@ -58,9 +63,10 @@ function static_julia(
cprog = joinpath(@__DIR__, "..", "examples", "program.c"), verbose = false, quiet = false,
builddir = "builddir", outname = splitext(basename(juliaprog))[1], clean = false,
autodeps = false, object = false, shared = false, executable = false, julialibs = false,
- sysimage = nothing, compile = nothing, cpu_target = nothing,
- optimize = nothing, debug = nothing, inline = nothing,
- check_bounds = nothing, math_mode = nothing, depwarn = nothing,
+ sysimage = nothing, precompiled = nothing, compilecache = nothing,
+ home = nothing, startup_file = nothing, handle_signals = nothing,
+ compile = nothing, cpu_target = nothing, optimize = nothing, debug = nothing,
+ inline = nothing, check_bounds = nothing, math_mode = nothing, depwarn = nothing,
cc = system_compiler(), cc_flags = nothing
)
@@ -121,8 +127,8 @@ function static_julia(
object && build_object(
juliaprog, o_file, verbose,
- sysimage, compile, cpu_target, optimize, debug, inline, check_bounds,
- math_mode, depwarn
+ sysimage, precompiled, compilecache, home, startup_file, handle_signals,
+ compile, cpu_target, optimize, debug, inline, check_bounds, math_mode, depwarn
)
shared && build_shared(s_file, o_file, verbose, optimize, debug, cc, cc_flags)
@@ -156,36 +162,43 @@ function julia_flags(optimize, debug, cc_flags)
end
function build_julia_cmd(
- sysimage, compile, cpu_target, optimize, debug, inline, check_bounds,
- math_mode, depwarn, startupfile = false
+ sysimage, precompiled, compilecache, home, startup_file, handle_signals,
+ compile, cpu_target, optimize, debug, inline, check_bounds, math_mode, depwarn
)
+ # TODO: `precompiled` and `compilecache` may be removed in future, see: https://github.com/JuliaLang/PackageCompiler.jl/issues/47
+ precompiled == nothing && cpu_target != nothing && (precompiled = "no")
+ compilecache == nothing && (compilecache = "no")
+ # TODO: `startup_file` may be removed in future with `julia-compile`, see: https://github.com/JuliaLang/julia/issues/15864
+ startup_file == nothing && (startup_file = "no")
julia_cmd = `$(Base.julia_cmd())`
if length(julia_cmd.exec) != 5 || !all(startswith.(julia_cmd.exec[2:5], ["-C", "-J", "--compile", "--depwarn"]))
error("Unexpected format of \"Base.julia_cmd()\", you may be using an incompatible version of Julia")
end
sysimage == nothing || (julia_cmd.exec[3] = "-J$sysimage")
- push!(julia_cmd.exec, string("--startup-file=", startupfile ? "yes" : "no"))
+ precompiled == nothing || push!(julia_cmd.exec, "--precompiled=$precompiled")
+ compilecache == nothing || push!(julia_cmd.exec, "--compilecache=$compilecache")
+ home == nothing || push!(julia_cmd.exec, "-H=$home")
+ startup_file == nothing || push!(julia_cmd.exec, "--startup-file=$startup_file")
+ handle_signals == nothing || push!(julia_cmd.exec, "--handle-signals=$handle_signals")
compile == nothing || (julia_cmd.exec[4] = "--compile=$compile")
- cpu_target == nothing || (julia_cmd.exec[2] = "-C$cpu_target";
- push!(julia_cmd.exec, "--precompiled=no"))
+ cpu_target == nothing || (julia_cmd.exec[2] = "-C$cpu_target")
optimize == nothing || push!(julia_cmd.exec, "-O$optimize")
debug == nothing || push!(julia_cmd.exec, "-g$debug")
inline == nothing || push!(julia_cmd.exec, "--inline=$inline")
check_bounds == nothing || push!(julia_cmd.exec, "--check-bounds=$check_bounds")
math_mode == nothing || push!(julia_cmd.exec, "--math-mode=$math_mode")
depwarn == nothing || (julia_cmd.exec[5] = "--depwarn=$depwarn")
- push!(julia_cmd.exec, "--compilecache=no")
julia_cmd
end
function build_object(
juliaprog, o_file, verbose,
- sysimage, compile, cpu_target, optimize, debug, inline, check_bounds,
- math_mode, depwarn
+ sysimage, precompiled, compilecache, home, startup_file, handle_signals,
+ compile, cpu_target, optimize, debug, inline, check_bounds, math_mode, depwarn
)
julia_cmd = build_julia_cmd(
- sysimage, compile, cpu_target, optimize, debug, inline, check_bounds,
- math_mode, depwarn, false
+ sysimage, precompiled, compilecache, home, startup_file, handle_signals,
+ compile, cpu_target, optimize, debug, inline, check_bounds, math_mode, depwarn
)
if julia_v07
iswindows() && (juliaprog = replace(juliaprog, "\\", "\\\\"))
@@ -205,9 +218,11 @@ function build_object(
include(\"$juliaprog\") # include Julia program file
empty!(Base.LOAD_CACHE_PATH) # reset / remove build-system-relative paths"
end
- command = `$julia_cmd -e $expr`
- verbose && println("Build \".ji\" local cache:\n $command")
- run(command)
+ if compilecache == "yes"
+ command = `$julia_cmd -e $expr`
+ verbose && println("Build \".ji\" local cache:\n $command")
+ run(command)
+ end
command = `$julia_cmd --output-o $o_file -e $expr`
verbose && println("Build object file \"$o_file\":\n $command")
run(command)
@@ -279,5 +294,5 @@ function copy_julia_libs(verbose)
copy = true
end
end
- copy || verbose && println(" none")
+ verbose && !copy && println(" none")
end
diff --git a/test/runtests.jl b/test/runtests.jl
index e54e632c..c280fa70 100644
--- a/test/runtests.jl
+++ b/test/runtests.jl
@@ -23,48 +23,45 @@ julia = Base.julia_cmd().exec[1]
end
end
-
@testset "juliac" begin
- mktempdir() do build
+ mktempdir() do builddir
juliac = joinpath(@__DIR__, "..", "juliac.jl")
jlfile = joinpath(@__DIR__, "..", "examples", "hello.jl")
cfile = joinpath(@__DIR__, "..", "examples", "program.c")
- @test success(`$julia $juliac -vosej $jlfile $cfile --builddir $build`)
- @test isfile(joinpath(build, "hello.$(Libdl.dlext)"))
- @test isfile(joinpath(build, "hello$(executable_ext())"))
- cd(build) do
+ @test success(`$julia $juliac -vosej $jlfile $cfile --builddir $builddir`)
+ @test isfile(joinpath(builddir, "hello.$(Libdl.dlext)"))
+ @test isfile(joinpath(builddir, "hello$(executable_ext())"))
+ cd(builddir) do
@test success(`./$("hello$(executable_ext())")`)
end
@testset "--cc-flags" begin
# Try passing `--help` to $cc. This should work for any system compiler.
# Then grep the output for "-g", which should be present on any system.
- @test contains(readstring(`$julia $juliac -se --cc-flags='--help' $jlfile $cfile --builddir $build`), "-g")
+ @test contains(readstring(`$julia $juliac -se --cc-flags='--help' $jlfile $cfile --builddir $builddir`), "-g")
# Just as a control, make sure that without passing '--help', we don't see "-g"
- @test !contains(readstring(`$julia $juliac -se $jlfile $cfile --builddir $build`), "-g")
+ @test !contains(readstring(`$julia $juliac -se $jlfile $cfile --builddir $builddir`), "-g")
end
end
end
@testset "build_executable" begin
- build = mktempdir()
+ builddir = mktempdir()
jlfile = joinpath(@__DIR__, "..", "examples", "hello.jl")
- snoopfile = open(joinpath(build, "snoop.jl"), "w") do io
+ snoopfile = open(joinpath(builddir, "snoop.jl"), "w") do io
write(io, open(read, jlfile))
println(io)
println(io, "using .Hello; Hello.julia_main(String[])")
end
build_executable(
- jlfile,
- snoopfile = snoopfile, builddir = build,
- verbose = false, quiet = false,
+ jlfile, snoopfile = snoopfile, builddir = builddir
)
- @test isfile(joinpath(build, "hello.$(Libdl.dlext)"))
- @test isfile(joinpath(build, "hello$(executable_ext())"))
- cd(build) do
+ @test isfile(joinpath(builddir, "hello.$(Libdl.dlext)"))
+ @test isfile(joinpath(builddir, "hello$(executable_ext())"))
+ cd(builddir) do
@test success(`./$("hello$(executable_ext())")`)
end
for i = 1:100
- try rm(build, recursive = true) end
+ try rm(builddir, recursive = true) end
sleep(1/100)
end
end