From ae5cab7489fe014dd3aa818cf2655d7a4714af83 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sat, 16 Dec 2017 17:42:12 +0200 Subject: Improve process execution diagnostics by reusing run_*() API --- build2/cc/compile.cxx | 14 ++++------- build2/cc/gcc.cxx | 66 ++++++++++++++++++++------------------------------- build2/cc/guess.cxx | 18 +++++++------- build2/cc/link.cxx | 25 ++++--------------- build2/cc/module.cxx | 3 ++- build2/cc/msvc.cxx | 5 +++- 6 files changed, 49 insertions(+), 82 deletions(-) (limited to 'build2/cc') diff --git a/build2/cc/compile.cxx b/build2/cc/compile.cxx index d73e67c..3b60a5b 100644 --- a/build2/cc/compile.cxx +++ b/build2/cc/compile.cxx @@ -2723,7 +2723,7 @@ namespace build2 continue; } else - fail << args[0] << " terminated abnormally: " << e.description (); + run_finish (args, pr); // Throws. } catch (const process_error& e) { @@ -3012,7 +3012,7 @@ namespace build2 info << "then run failing command to display compiler diagnostics"; } else - fail << args[0] << " terminated abnormally: " << e.description (); + run_finish (args, pr); // Throws. } catch (const process_error& e) { @@ -4489,17 +4489,12 @@ namespace build2 catch (const io_error&) {} // Assume exits with error. } - if (!pr.wait ()) - throw failed (); + run_finish (args, pr); } catch (const process_error& e) { error << "unable to execute " << args[0] << ": " << e; - // In a multi-threaded program that fork()'ed but did not exec(), - // it is unwise to try to do any kind of cleanup (like unwinding - // the stack and running destructors). - // if (e.child) exit (1); @@ -4541,8 +4536,7 @@ namespace build2 nullptr, // CWD env.empty () ? nullptr : env.data ()); - if (!pr.wait ()) - throw failed (); + run_finish (args, pr); } catch (const process_error& e) { diff --git a/build2/cc/gcc.cxx b/build2/cc/gcc.cxx index ce1450e..0ce4c4f 100644 --- a/build2/cc/gcc.cxx +++ b/build2/cc/gcc.cxx @@ -180,57 +180,43 @@ namespace build2 if (verb >= 3) print_process (args); + process pr (run_start (xc, args.data (), -1)); // Open pipe to stdout. + string l; try { - process pr (xc, args.data (), 0, -1); // Open pipe to stdout. - - try + ifdstream is ( + move (pr.in_ofd), fdstream_mode::skip, ifdstream::badbit); + + // The output of -print-search-dirs are a bunch of lines that start + // with ": =" where name can be "install", "programs", or + // "libraries". If you have English locale, that is. If you set your + // LC_ALL="tr_TR", then it becomes "kurulum", "programlar", and + // "kitapl?klar". Also, Clang omits "install" while GCC and Intel icc + // print all three. The "libraries" seem to be alwasy last, however. + // + string s; + for (bool found (false); !found && getline (is, s); ) { - ifdstream is ( - move (pr.in_ofd), fdstream_mode::skip, ifdstream::badbit); - - // The output of -print-search-dirs are a bunch of lines that start - // with ": =" where name can be "install", "programs", or - // "libraries". If you have English locale, that is. If you set your - // LC_ALL="tr_TR", then it becomes "kurulum", "programlar", and - // "kitapl?klar". Also, Clang omits "install" while GCC and Intel - // icc print all three. The "libraries" seem to be alwasy last, - // however. - // - string s; - for (bool found (false); !found && getline (is, s); ) - { - found = (s.compare (0, 12, "libraries: =") == 0); - - size_t p (found ? 9 : s.find (": =")); - - if (p != string::npos) - l.assign (s, p + 3, string::npos); - } + found = (s.compare (0, 12, "libraries: =") == 0); - is.close (); // Don't block. + size_t p (found ? 9 : s.find (": =")); - if (!pr.wait ()) - throw failed (); // Assume issued diagnostics to stderr. - } - catch (const io_error&) - { - pr.wait (); - fail << "error reading " << x_lang << " compiler -print-search-dirs " - << "output"; + if (p != string::npos) + l.assign (s, p + 3, string::npos); } + + is.close (); // Don't block. } - catch (const process_error& e) + catch (const io_error&) { - error << "unable to execute " << args[0] << ": " << e; - - if (e.child) - exit (1); - - throw failed (); + pr.wait (); + fail << "error reading " << x_lang << " compiler -print-search-dirs " + << "output"; } + run_finish (args, pr); + if (l.empty ()) fail << "unable to extract " << x_lang << " compiler system library " << "search paths"; diff --git a/build2/cc/guess.cxx b/build2/cc/guess.cxx index 6dea97d..c39c02e 100644 --- a/build2/cc/guess.cxx +++ b/build2/cc/guess.cxx @@ -248,7 +248,7 @@ namespace build2 // Suppress all the compiler errors because we may be trying an // unsupported option. // - r = run (pp, "-v", f, false, false, &cs); + r = run (3, pp, "-v", f, false, false, &cs); if (!r.empty ()) { @@ -284,7 +284,7 @@ namespace build2 return guess_result (); }; - r = run (pp, "--version", f, false); + r = run (3, pp, "--version", f, false); } // Finally try to run it without any options to detect msvc. @@ -317,7 +317,7 @@ namespace build2 return guess_result (); }; - r = run (pp, f, false); + r = run (3, pp, f, false); } if (!r.empty ()) @@ -487,7 +487,7 @@ namespace build2 // auto f = [] (string& l) {return move (l);}; - string t (run (args.data (), f, false)); + string t (run (3, args.data (), f, false)); if (t.empty ()) { @@ -495,7 +495,7 @@ namespace build2 << "falling back to -dumpmachine";}); args[1] = "-dumpmachine"; - t = run (args.data (), f); + t = run (3, args.data (), f); } if (t.empty ()) @@ -609,7 +609,7 @@ namespace build2 // The output of -dumpmachine is a single line containing just the // target triplet. // - string t (run (args.data (), [] (string& l) {return move (l);})); + string t (run (3, args.data (), [](string& l) {return move (l);})); if (t.empty ()) fail << "unable to extract target architecture from " << xc @@ -682,7 +682,7 @@ namespace build2 // The -V output is sent to STDERR. // - s = run (xc, "-V", f, false); + s = run (3, xc, "-V", f, false); if (s.empty ()) fail << "unable to extract signature from " << xc << " -V output"; @@ -781,7 +781,7 @@ namespace build2 // The -V output is sent to STDERR. // - string t (run (args.data (), f, false)); + string t (run (3, args.data (), f, false)); if (t.empty ()) fail << "unable to extract target architecture from " << xc @@ -823,7 +823,7 @@ namespace build2 // on which we are running), who knows what will happen in the future. // So instead we are going to use -dumpmachine and substitute the CPU. // - t = run (xc, "-dumpmachine", [] (string& l) {return move (l);}); + t = run (3, xc, "-dumpmachine", [](string& l) {return move (l);}); if (t.empty ()) fail << "unable to extract target architecture from " << xc diff --git a/build2/cc/link.cxx b/build2/cc/link.cxx index c0ff10c..f69d549 100644 --- a/build2/cc/link.cxx +++ b/build2/cc/link.cxx @@ -1297,9 +1297,6 @@ namespace build2 os << "\"" << endl; os.close (); - - if (!pr.wait ()) - throw failed (); // Assume diagnostics issued. } catch (const io_error& e) { @@ -1307,6 +1304,8 @@ namespace build2 fail << "unable to pipe resource file to " << args[0] << ": " << e; } + + run_finish (args, pr); } catch (const process_error& e) { @@ -1963,8 +1962,7 @@ namespace build2 catch (const io_error&) {} // Assume exits with error. } - if (!pr.wait ()) - throw failed (); + run_finish (args, pr); } catch (const process_error& e) { @@ -1997,22 +1995,7 @@ namespace build2 if (verb >= 2) print_process (args); - try - { - process pr (rl, args); - - if (!pr.wait ()) - throw failed (); - } - catch (const process_error& e) - { - error << "unable to execute " << args[0] << ": " << e; - - if (e.child) - exit (1); - - throw failed (); - } + run (rl, args); } if (tclass == "windows") diff --git a/build2/cc/module.cxx b/build2/cc/module.cxx index 9fbae4b..d4962a4 100644 --- a/build2/cc/module.cxx +++ b/build2/cc/module.cxx @@ -119,7 +119,8 @@ namespace build2 if (ops.config_sub_specified ()) { - ct = run (ops.config_sub (), + ct = run (3, + ops.config_sub (), ci.target.c_str (), [] (string& l) {return move (l);}); l5 ([&]{trace << "config.sub target: '" << ct << "'";}); diff --git a/build2/cc/msvc.cxx b/build2/cc/msvc.cxx index a4c4317..59bb55c 100644 --- a/build2/cc/msvc.cxx +++ b/build2/cc/msvc.cxx @@ -151,10 +151,13 @@ namespace build2 l.string ().c_str (), nullptr}; + if (verb >= 3) + print_process (args); + // Link.exe seem to always dump everything to stdout but just in case // redirect stderr to stdout. // - process pr (run_start (ld, args, false)); + process pr (run_start (ld, args, -1 /* stdout */, false /* error */)); bool obj (false), dll (false); string s; -- cgit v1.1