aboutsummaryrefslogtreecommitdiff
path: root/libbuild2
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2')
-rw-r--r--libbuild2/adhoc-rule-cxx.cxx42
-rw-r--r--libbuild2/buildfile56
-rw-r--r--libbuild2/config/host-config.cxx.in3
-rw-r--r--libbuild2/config/init.cxx14
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.<project>.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<bool> (*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
}