diff --git a/contrib/juliac.jl b/contrib/juliac.jl index 20d56615c6357..3d1a3ef13fe79 100644 --- a/contrib/juliac.jl +++ b/contrib/juliac.jl @@ -1,8 +1,7 @@ # Julia compiler wrapper script # NOTE: The interface and location of this script are considered unstable/experimental -cmd = Base.julia_cmd() -cmd = `$cmd --startup-file=no --history-file=no` +julia_cmd = `$(Base.julia_cmd()) --startup-file=no --history-file=no` output_type = nothing # exe, sharedlib, sysimage outname = nothing file = nothing @@ -55,9 +54,9 @@ isnothing(outname) && error("No output file specified") isnothing(file) && error("No input file specified") absfile = abspath(file) -cflags = readchomp(`$(cmd) $(joinpath(Sys.BINDIR, Base.DATAROOTDIR,"julia", "julia-config.jl")) --cflags `) +cflags = readchomp(`$(julia_cmd) $(joinpath(Sys.BINDIR, Base.DATAROOTDIR,"julia", "julia-config.jl")) --cflags `) cflags = Base.shell_split(cflags) -allflags = readchomp(`$(cmd) $(joinpath(Sys.BINDIR, Base.DATAROOTDIR,"julia", "julia-config.jl")) --allflags`) +allflags = readchomp(`$(julia_cmd) $(joinpath(Sys.BINDIR, Base.DATAROOTDIR,"julia", "julia-config.jl")) --allflags`) allflags = Base.shell_split(allflags) tmpdir = mktempdir(cleanup=false) initsrc_path = joinpath(tmpdir, "init.c") @@ -65,45 +64,67 @@ init_path = joinpath(tmpdir, "init.a") img_path = joinpath(tmpdir, "img.a") bc_path = joinpath(tmpdir, "img-bc.a") -open(initsrc_path, "w") do io - print(io, """ - #include - __attribute__((constructor)) void static_init(void) { - if (jl_is_initialized()) - return; - julia_init(JL_IMAGE_IN_MEMORY); - jl_exception_clear(); - } - """) -end -cmd = addenv(`$cmd --project=$(Base.active_project()) --output-o $img_path --output-incremental=no --strip-ir --strip-metadata $julia_args $(joinpath(@__DIR__,"juliac-buildscript.jl")) $absfile $output_type $add_ccallables`, "OPENBLAS_NUM_THREADS" => 1, "JULIA_NUM_THREADS" => 1) -verbose && println("Running: $cmd") -if !success(pipeline(cmd; stdout, stderr)) - println(stderr, "\nFailed to compile $file") - exit(1) +function precompile_env() + # Pre-compile the environment + # (otherwise obscure error messages will occur) + cmd = addenv(`$julia_cmd --project=$(Base.active_project()) -e "using Pkg; Pkg.precompile()"`) + verbose && println("Running: $cmd") + if !success(pipeline(cmd; stdout, stderr)) + println(stderr, "\nError encountered during pre-compilation of environment.") + exit(1) + end end -run(`cc $(cflags) -g -c -o $init_path $initsrc_path`) +function compile_products() + # Compile the Julia code + cmd = addenv(`$julia_cmd --project=$(Base.active_project()) --output-o $img_path --output-incremental=no --strip-ir --strip-metadata $julia_args $(joinpath(@__DIR__,"juliac-buildscript.jl")) $absfile $output_type $add_ccallables`, "OPENBLAS_NUM_THREADS" => 1, "JULIA_NUM_THREADS" => 1) + verbose && println("Running: $cmd") + if !success(pipeline(cmd; stdout, stderr)) + println(stderr, "\nFailed to compile $file") + exit(1) + end -if output_type == "--output-lib" || output_type == "--output-sysimage" - of, ext = splitext(outname) - soext = "." * Base.BinaryPlatforms.platform_dlext() - if ext == "" - outname = of * soext + # Compile the initialization code + open(initsrc_path, "w") do io + print(io, """ + #include + __attribute__((constructor)) void static_init(void) { + if (jl_is_initialized()) + return; + julia_init(JL_IMAGE_IN_MEMORY); + jl_exception_clear(); + } + """) end + run(`cc $(cflags) -g -c -o $init_path $initsrc_path`) end -julia_libs = Base.shell_split(Base.isdebugbuild() ? "-ljulia-debug -ljulia-internal-debug" : "-ljulia -ljulia-internal") -try - if output_type == "--output-lib" - run(`cc $(allflags) -o $outname -shared -Wl,$(Base.Linking.WHOLE_ARCHIVE) $img_path -Wl,$(Base.Linking.NO_WHOLE_ARCHIVE) $init_path $(julia_libs)`) - elseif output_type == "--output-sysimage" - run(`cc $(allflags) -o $outname -shared -Wl,$(Base.Linking.WHOLE_ARCHIVE) $img_path -Wl,$(Base.Linking.NO_WHOLE_ARCHIVE) $(julia_libs)`) - else - run(`cc $(allflags) -o $outname -Wl,$(Base.Linking.WHOLE_ARCHIVE) $img_path -Wl,$(Base.Linking.NO_WHOLE_ARCHIVE) $init_path $(julia_libs)`) +function link_products() + global outname + if output_type == "--output-lib" || output_type == "--output-sysimage" + of, ext = splitext(outname) + soext = "." * Base.BinaryPlatforms.platform_dlext() + if ext == "" + outname = of * soext + end + end + + julia_libs = Base.shell_split(Base.isdebugbuild() ? "-ljulia-debug -ljulia-internal-debug" : "-ljulia -ljulia-internal") + try + if output_type == "--output-lib" + run(`cc $(allflags) -o $outname -shared -Wl,$(Base.Linking.WHOLE_ARCHIVE) $img_path -Wl,$(Base.Linking.NO_WHOLE_ARCHIVE) $init_path $(julia_libs)`) + elseif output_type == "--output-sysimage" + run(`cc $(allflags) -o $outname -shared -Wl,$(Base.Linking.WHOLE_ARCHIVE) $img_path -Wl,$(Base.Linking.NO_WHOLE_ARCHIVE) $(julia_libs)`) + else + run(`cc $(allflags) -o $outname -Wl,$(Base.Linking.WHOLE_ARCHIVE) $img_path -Wl,$(Base.Linking.NO_WHOLE_ARCHIVE) $init_path $(julia_libs)`) + end + catch e + println("\nCompilation failed: ", e) + exit(1) end -catch - println("\nCompilation failed.") - exit(1) end + +precompile_env() +compile_products() +link_products()