From 87d896f1107a077f3d1876f8feb9dcf9ee93ea3c Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 6 Apr 2020 16:20:29 +0200 Subject: Pass LC_ALL=C when extracting locale-dependent information on POSIX --- libbuild2/cc/gcc.cxx | 41 +++++++++++++++++++++++++++++++++++------ libbuild2/cc/guess.cxx | 46 +++++++++++++++++++++++++++++++++------------- libbuild2/diagnostics.cxx | 26 ++++++++++++++++++++++---- libbuild2/diagnostics.hxx | 28 ++++++++++++++++++++++++++-- libbuild2/utility.cxx | 2 +- 5 files changed, 117 insertions(+), 26 deletions(-) diff --git a/libbuild2/cc/gcc.cxx b/libbuild2/cc/gcc.cxx index 84d4e01..29bf824 100644 --- a/libbuild2/cc/gcc.cxx +++ b/libbuild2/cc/gcc.cxx @@ -101,14 +101,35 @@ namespace build2 args.push_back ("-"); args.push_back (nullptr); + process_env env (xc); + + // For now let's assume that all the platforms other than Windows + // recognize LC_ALL. + // +#ifndef _WIN32 + const char* evars[] = {"LC_ALL=C", nullptr}; + env.vars = evars; +#endif + if (verb >= 3) - print_process (args); + print_process (env, args); try { + //@@ TODO: why don't we use run_start() here? Because it's unable to + // open pipe for stderr and we need to change it first, for example, + // making the err parameter a file descriptor rather than a flag. + // + // Open pipe to stderr, redirect stdin and stdout to /dev/null. // - process pr (xc, args.data (), -2, -2, -1); + process pr (xc, + args.data (), + -2, /* stdin */ + -2, /* stdout */ + -1, /* stderr */ + nullptr /* cwd */, + env.vars); try { @@ -237,12 +258,22 @@ namespace build2 args.push_back ("-print-search-dirs"); args.push_back (nullptr); + process_env env (xc); + + // For now let's assume that all the platforms other than Windows + // recognize LC_ALL. + // +#ifndef _WIN32 + const char* evars[] = {"LC_ALL=C", nullptr}; + env.vars = evars; +#endif + if (verb >= 3) - print_process (args); + print_process (env, args); // Open pipe to stdout. // - process pr (run_start (xc, + process pr (run_start (env, args, 0, /* stdin */ -1 /* stdout */)); @@ -316,7 +347,5 @@ namespace build2 return make_pair (move (r), rn); } - - } } diff --git a/libbuild2/cc/guess.cxx b/libbuild2/cc/guess.cxx index c47e5a1..f10d9f8 100644 --- a/libbuild2/cc/guess.cxx +++ b/libbuild2/cc/guess.cxx @@ -941,16 +941,25 @@ namespace build2 args.push_back (nullptr); // Placeholder for the option. args.push_back (nullptr); - auto run = [&cs, &xp, &args] (const char* o, - auto&& f, - const char* const* env = nullptr, - bool checksum = false) -> guess_result + process_env env (xp); + + // For now let's assume that all the platforms other than Windows + // recognize LC_ALL. + // +#ifndef _WIN32 + const char* evars[] = {"LC_ALL=C", nullptr}; + env.vars = evars; +#endif + + auto run = [&cs, &env, &args] (const char* o, + auto&& f, + bool checksum = false) -> guess_result { args[args.size () - 2] = o; return build2::run ( 3 /* verbosity */, - process_env (xp, env), + env, args.data (), forward (f), false /* error */, @@ -1070,7 +1079,7 @@ namespace build2 // (e.g., via LC_ALL), then the compiler signature will most likely // change as well because of the translated text. // - r = run ("-v", f, nullptr /* env */, true /* checksum */); + r = run ("-v", f, true /* checksum */); if (r.empty ()) { @@ -1183,9 +1192,9 @@ namespace build2 // // This is also the reason why we don't pass the mode options. // - const char* env[] = {"CL=", "_CL_=", nullptr}; + const char* evars[] = {"CL=", "_CL_=", nullptr}; - r = build2::run (3, process_env (xp, env), f, false); + r = build2::run (3, process_env (xp, evars), f, false); if (r.empty ()) { @@ -1807,7 +1816,8 @@ namespace build2 args.push_back (nullptr); // The output of both -print-multiarch and -dumpmachine is a single - // line containing just the target triplet. + // line containing just the target triplet. We don't expect any + // localization so no need for LC_ALL. // auto f = [] (string& l, bool) {return move (l);}; @@ -2287,7 +2297,8 @@ namespace build2 args.push_back (nullptr); // The output of -dumpmachine is a single line containing just the - // target triplet. + // target triplet. Again, we don't expect any localization so no need + // for LC_ALL. // auto f = [] (string& l, bool) {return move (l);}; t = run (3, xp, args.data (), f, false); @@ -2520,8 +2531,15 @@ namespace build2 // Intel(R) C Intel(R) 64 Compiler for applications running on Intel(R) MIC Architecture, Version 16.0.2.181 Build 20160204 // // We should probably also assume the language words can be translated - // and even rearranged. + // and even rearranged. Thus pass LC_ALL=C. // + process_env env (xp); + +#ifndef _WIN32 + const char* evars[] = {"LC_ALL=C", nullptr}; + env.vars = evars; +#endif + auto f = [] (string& l, bool) { return l.compare (0, 5, "Intel") == 0 && (l[5] == '(' || l[5] == ' ') @@ -2538,7 +2556,7 @@ namespace build2 // // @@ TODO: running without the mode options. // - s = run (3, xp, "-V", f, false); + s = run (3, env, "-V", f, false); if (s.empty ()) fail << "unable to extract signature from " << xc << " -V output"; @@ -2664,7 +2682,7 @@ namespace build2 // The -V output is sent to STDERR. // - t = run (3, xp, args.data (), f, false); + t = run (3, env, args.data (), f, false); if (t.empty ()) fail << "unable to extract target architecture from " << xc @@ -2709,6 +2727,8 @@ namespace build2 // in the future. So instead we are going to use -dumpmachine and // substitute the CPU. // + // Note: no localication expected so running without LC_ALL. + // // @@ TODO: running without the mode options. // { diff --git a/libbuild2/diagnostics.cxx b/libbuild2/diagnostics.cxx index 0a01457..ee4651d 100644 --- a/libbuild2/diagnostics.cxx +++ b/libbuild2/diagnostics.cxx @@ -49,14 +49,32 @@ namespace build2 void print_process (const char* const* args, size_t n) { - diag_record r (text); - print_process (r, args, n); + diag_record dr (text); + print_process (dr, args, n); } void - print_process (diag_record& r, const char* const* args, size_t n) + print_process (diag_record& dr, + const char* const* args, size_t n) { - r << butl::process_args {args, n}; + dr << butl::process_args {args, n}; + } + + void + print_process (const process_env& pe, const char* const* args, size_t n) + { + diag_record dr (text); + print_process (dr, pe, args, n); + } + + void + print_process (diag_record& dr, + const process_env& pe, const char* const* args, size_t n) + { + if (pe.env ()) + dr << pe << ' '; + + dr << butl::process_args {args, n}; } // Diagnostics stack. diff --git a/libbuild2/diagnostics.hxx b/libbuild2/diagnostics.hxx index aef7bec..1290634 100644 --- a/libbuild2/diagnostics.hxx +++ b/libbuild2/diagnostics.hxx @@ -32,13 +32,15 @@ namespace build2 // nameN arg arg ... nullptr nullptr // LIBBUILD2_SYMEXPORT void - print_process (diag_record&, const char* const* args, size_t n = 0); + print_process (diag_record&, + const char* const* args, size_t n = 0); LIBBUILD2_SYMEXPORT void print_process (const char* const* args, size_t n = 0); inline void - print_process (diag_record& dr, const cstrings& args, size_t n = 0) + print_process (diag_record& dr, + const cstrings& args, size_t n = 0) { print_process (dr, args.data (), n != 0 ? n : args.size ()); } @@ -49,6 +51,28 @@ namespace build2 print_process (args.data (), n != 0 ? n : args.size ()); } + // As above but with process_env. + // + LIBBUILD2_SYMEXPORT void + print_process (diag_record&, + const process_env&, const char* const* args, size_t n = 0); + + LIBBUILD2_SYMEXPORT void + print_process (const process_env&, const char* const* args, size_t n = 0); + + inline void + print_process (diag_record& dr, + const process_env& pe, const cstrings& args, size_t n = 0) + { + print_process (dr, pe, args.data (), n != 0 ? n : args.size ()); + } + + inline void + print_process (const process_env& pe, const cstrings& args, size_t n = 0) + { + print_process (pe, args.data (), n != 0 ? n : args.size ()); + } + // Program verbosity level (-v/--verbose plus --silent). // // 0 - disabled diff --git a/libbuild2/utility.cxx b/libbuild2/utility.cxx index 3b4b94f..a45e901 100644 --- a/libbuild2/utility.cxx +++ b/libbuild2/utility.cxx @@ -219,7 +219,7 @@ namespace build2 assert (args[0] == pe.path->recall_string ()); if (verb >= verbosity) - print_process (args, 0); + print_process (pe, args, 0); return process ( *pe.path, -- cgit v1.1