From 22e86cb4b6bc403c895a2bbf337755fb91334f42 Mon Sep 17 00:00:00 2001 From: "Steven G. Johnson" Date: Thu, 8 Oct 2015 23:34:56 -0400 Subject: [PATCH] eval build.jl files in a separate Julia process for Pkg.build (fixes #13458) --- base/pkg/entry.jl | 58 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 7 deletions(-) diff --git a/base/pkg/entry.jl b/base/pkg/entry.jl index 8e25da91524b1..9602588ea32ba 100644 --- a/base/pkg/entry.jl +++ b/base/pkg/entry.jl @@ -725,22 +725,66 @@ function warnbanner(msg...; label="[ WARNING ]", prefix="") warn(prefix="", "="^cols) end -function build!(pkgs::Vector, errs::Dict, seen::Set=Set()) +function build!(pkgs::Vector, buildstream::IO, seen::Set) for pkg in pkgs pkg == "julia" && continue pkg in seen && continue - build!(Read.requires_list(pkg),errs,push!(seen,pkg)) + build!(Read.requires_list(pkg),buildstream,push!(seen,pkg)) Read.isinstalled(pkg) || throw(PkgError("$pkg is not an installed package")) path = abspath(pkg,"deps","build.jl") isfile(path) || continue - info("Building $pkg") - cd(dirname(path)) do - try evalfile(path) - catch err - warnbanner(err, label="[ ERROR: $pkg ]") + println(buildstream, path) # send to build process for evalfile + flush(buildstream) + end +end + +function build!(pkgs::Vector, errs::Dict, seen::Set=Set()) + # To isolate the build from the running Julia process, we + # execute the build.jl files in a separate process that + # is sitting there waiting for paths to evaluate. Errors + # are serialized to errfile for later retrieval into errs[pkg] + errfile = tempname() + close(open(errfile, "w")) # create empty file + code = """ + open("$(escape_string(errfile))", "a") do f + for path_ in eachline(STDIN) + path = chomp(path_) + pkg = basename(dirname(dirname(path))) + try + info("Building \$pkg") + cd(dirname(path)) do + evalfile(path) + end + catch err + Base.Pkg.Entry.warnbanner(err, label="[ ERROR: \$pkg ]") + serialize(f, pkg) + serialize(f, err) + end + end + end + """ + io, pobj = open(detach(`$(Base.julia_cmd()) + --history-file=no + --color=$(Base.have_color ? "yes" : "no") + --eval $code`), "w", STDOUT) + try + build!(pkgs, io, seen) + close(io) + wait(pobj) + success(pobj) || error("Build process failed.") + open(errfile, "r") do f + while !eof(f) + pkg = deserialize(f) + err = deserialize(f) errs[pkg] = err end end + catch + kill(pobj) + close(io) + rethrow() + finally + isfile(errfile) && Base.rm(errfile) end end