From d28970114e5807f57ae339764ac05384ef163379 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 1 Apr 2024 07:39:12 +0200 Subject: Add ~host-no-warnings and ~build2-no-warnings special configurations These are parallel to ~host and ~build2 but with suppressed C/C++ compiler warnings. Note also that the C++ ad hoc recipes are now by default built in ~build2-no-warnings instead of ~build2 unless the project is configured for development with config..develop=true. --- libbuild2/adhoc-rule-cxx.cxx | 42 +++++++++++++++++++++++++++- libbuild2/buildfile | 56 +++++++++++++++++++++++++++++++++---- libbuild2/config/host-config.cxx.in | 3 ++ libbuild2/config/init.cxx | 14 ++++++++-- 4 files changed, 106 insertions(+), 9 deletions(-) diff --git a/libbuild2/adhoc-rule-cxx.cxx b/libbuild2/adhoc-rule-cxx.cxx index 2ac97eb..8a91809 100644 --- a/libbuild2/adhoc-rule-cxx.cxx +++ b/libbuild2/adhoc-rule-cxx.cxx @@ -358,6 +358,46 @@ namespace build2 // This way the configuration will be always in sync with ~build2 // and we can update the recipe manually (e.g., for debugging). // + // Should we use ~build2 or ~build2-no-warnings? This case is similar + // to private host/module configurations in that the user doesn't have + // any control over the options used, etc. So it would be natural to + // use the no-warnings variant. However, unlike with tools/modules + // which can be configured in a user-created configuration (and which + // will normally be the case during development), for recipes it's + // always this automatically-create configuration. It feels like the + // best we can do is use ~build2-no-warnings by default but switch to + // ~build2 if the project is configured for development + // (config..develop). + // + string cfg; + { + const project_name& pn (named_project (rs)); + + if (!pn.empty ()) + { + string var ("config." + pn.variable () + ".develop"); + + if (lookup l = rs[var]) + { + // The value could be untyped if the project didn't declare this + // variable. Let's handle that case gracefully. + // + try + { + if (convert (*l)) + cfg = "~build2"; + } + catch (const invalid_argument& e) + { + fail << "invalid " << var << " value: " << e; + } + } + } + + if (cfg.empty ()) + cfg = "~build2-no-warnings"; + } + create_project ( pd, dir_path (), /* amalgamation */ @@ -366,7 +406,7 @@ namespace build2 {"cxx."}, /* root_modules */ "", /* root_post */ string ("config"), /* config_module */ - string ("config.config.load = ~build2"), /* config_file */ + "config.config.load = " + cfg, /* config_file */ false, /* buildfile */ "build2 core", /* who */ verbosity); /* verbosity */ diff --git a/libbuild2/buildfile b/libbuild2/buildfile index 6289bbf..3518d93 100644 --- a/libbuild2/buildfile +++ b/libbuild2/buildfile @@ -88,18 +88,24 @@ libul{build2}: config/{hxx ixx txx cxx}{** -host-config -**.test...} \ # on the users of ~host/~build2; they can decide for themselves if they # want it). # -build2_config_lines = [strings] +# The *_no_warnings variants are with the suppressed C/C++ compiler warnings +# (in particular, used for private host configuration in bpkg). +# +# host_config_lines = [strings] +build2_config_lines = [strings] + +host_config_no_warnings_lines = [strings] +build2_config_no_warnings_lines = [strings] for l: $regex.replace_lines( \ $config.save(), \ '^( *(#|(config\.(test[. ]|dist\.|install\.chroot|config\.hermetic))).*|)$', \ [null]) { - build2_config_lines += $l - # Note: also preserve config.version. # + h = [null] if $regex.match( \ $l, \ ' *config\.(c[. ]|cxx[. ]|cc[.]|bin[.]|config.environment |version ).*') @@ -117,18 +123,56 @@ for l: $regex.replace_lines( \ # if $regex.match($l, ' *config\.(c|cxx|cc)\.(coptions|loptions)[ =].*') { - l = $regex.replace($l, ' ?-f(no-)?sanitize[=-][^ ]+', '') + h = $regex.replace($l, ' ?-f(no-)?sanitize[=-][^ ]+', '') } + else + h = $l + } + } + + if ($h != [null]) + host_config_lines += $h + + build2_config_lines += $l - host_config_lines += $l + # Append the warning suppressing option to config.{c,cxx}.coptions rather + # than config.cc.coptions since the former could re-enable them. + # + if ($regex.match($l, ' *config\.(c|cxx)\.coptions[ =].*')) + { + # Note that in MSVC overriding one warning option (say /W3) with another + # (say /w) triggers a warning. However, our compile_rule sanitizes the + # command line to resolve such overrides (see msvc_sanitize_cl()). + # + o = ($cxx.class == 'gcc' ? -w : $cxx.class == 'msvc' ? /w : ) + + if ($regex.match($l, '[^=]+= *\[null\] *')) + { + l = $regex.replace($l, '= *\[null\] *$', "= $o") + h = $regex.replace($h, '= *\[null\] *$', "= $o") + } + else + { + l = $regex.replace($l, '=(.*)$', "=\\1 $o") + h = $regex.replace($h, '=(.*)$', "=\\1 $o") } } + + if ($h != [null]) + host_config_no_warnings_lines += $h + + build2_config_no_warnings_lines += $l } config/cxx{host-config}: config/in{host-config} { - build2_config = $regex.merge($build2_config_lines, '(.+)', '\1\n') host_config = $regex.merge($host_config_lines, '(.+)', '\1\n') + build2_config = $regex.merge($build2_config_lines, '(.+)', '\1\n') + + host_config_no_warnings = $regex.merge($host_config_no_warnings_lines, \ + '(.+)', '\1\n') + build2_config_no_warnings = $regex.merge($build2_config_no_warnings_lines, \ + '(.+)', '\1\n') } libul{build2}: dist/{hxx ixx txx cxx}{** -**.test...} diff --git a/libbuild2/config/host-config.cxx.in b/libbuild2/config/host-config.cxx.in index 9e3e0c2..6b1ce77 100644 --- a/libbuild2/config/host-config.cxx.in +++ b/libbuild2/config/host-config.cxx.in @@ -9,5 +9,8 @@ namespace build2 // extern const char host_config[] = R"###($host_config$)###"; extern const char build2_config[] = R"###($build2_config$)###"; + + extern const char host_config_no_warnings[] = R"###($host_config_no_warnings$)###"; + extern const char build2_config_no_warnings[] = R"###($build2_config_no_warnings$)###"; } } diff --git a/libbuild2/config/init.cxx b/libbuild2/config/init.cxx index 38590ae..d1a57b9 100644 --- a/libbuild2/config/init.cxx +++ b/libbuild2/config/init.cxx @@ -210,6 +210,9 @@ namespace build2 #ifndef BUILD2_BOOTSTRAP extern const char host_config[]; extern const char build2_config[]; + + extern const char host_config_no_warnings[]; + extern const char build2_config_no_warnings[]; #endif bool @@ -486,12 +489,19 @@ namespace build2 if (s[0] != '~') load_config_file (f, l); - else if (s == "~host" || s == "~build2") + else if (s == "~host" || s == "~host-no-warnings" || + s == "~build2" || s == "~build2-no-warnings") { #ifdef BUILD2_BOOTSTRAP assert (false); #else - istringstream is (s[1] == 'h' ? host_config : build2_config); + istringstream is (s[1] == 'h' + ? (s.size () == 5 + ? host_config + : host_config_no_warnings) + : (s.size () == 7 + ? build2_config + : build2_config_no_warnings)); load_config (is, path_name (s), l); #endif } -- cgit v1.1