aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/buildfile
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2/buildfile')
-rw-r--r--libbuild2/buildfile293
1 files changed, 233 insertions, 60 deletions
diff --git a/libbuild2/buildfile b/libbuild2/buildfile
index 17003b5..3518d93 100644
--- a/libbuild2/buildfile
+++ b/libbuild2/buildfile
@@ -4,7 +4,7 @@
# NOTE: remember to update bundled_modules in libbuild2/module.cxx if adding a
# new module.
#
-bundled_modules = bash/ bin/ c/ cc/ cxx/ in/ version/
+bundled_modules = bash/ bin/ c/ cc/ cli/ cxx/ in/ version/
./: lib{build2} $bundled_modules
@@ -25,14 +25,22 @@ include $bundled_modules
#
intf_libs = $libbutl
-lib{build2}: libul{build2}: \
- {hxx ixx txx cxx}{* -utility-*installed -config -version -*.test...} \
+lib{build2}: libul{build2}: \
+ {hxx ixx txx cxx}{* -utility-*installed \
+ -common-options \
+ -b-options \
+ -config \
+ -version \
+ -*.test...} \
+ {hxx ixx cxx}{common-options} \
+ {hxx ixx cxx}{b-options} \
{hxx}{config version}
libul{build2}: script/{hxx ixx txx cxx}{** -*-options -**.test...} \
script/{hxx ixx cxx}{builtin-options}
-libul{build2}: build/{hxx ixx txx cxx}{** -**.test...}
+libul{build2}: build/script/{hxx ixx txx cxx}{** -*-options -**.test...} \
+ build/script/{hxx ixx cxx}{builtin-options}
# Note that this won't work in libul{} since it's not installed.
#
@@ -51,39 +59,120 @@ lib{build2}: cxx{utility-uninstalled}: for_install = false
libul{build2}: config/{hxx ixx txx cxx}{** -host-config -**.test...} \
config/cxx{host-config}
+# Derive ~host and ~build2 configurations from current configuration.
+#
# This will of course blow up spectacularly if we are cross-compiling. But
# let's wait and enjoy the fireworks (and get a sense of why someone would
# want to cross-compile a build system).
#
-config/cxx{host-config}: config/in{host-config}
+# For the ~host configuration we only want c/cxx/cc and bin that they load.
+# For ~build2 we want to keep everything except dist.
+#
+# We also remove comment lines which could be confused with preprocessor
+# directives by some lesser compilers and blank lines between groups of
+# options which could cause spurious rebuilds when we filter out entire
+# groups.
+#
+# For ~host also filter out config.bin.lib/config.bin.*.lib (static/shared
+# library build/link preferences). In particular, we don't want to force
+# config.bin.lib=shared since that will cause static libraries to link shared
+# versions of their prerequisites (see mysql-client for a case where this can
+# make a difference).
+#
+# For ~build2 also filter out config.install.chroot -- we definitely don't
+# want it carried through. Also filter out variables that control tests
+# execution.
+#
+# Finally, for both ~host and ~build2 we keep config.config.environment
+# but strip config.config.hermetic* (we shouldn't be forcing hermiticity
+# on the users of ~host/~build2; they can decide for themselves if they
+# want it).
+#
+# 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])
{
- # For the ~host configuration we only want c/cxx/cc and bin that they load.
- # For ~build2 we want to keep everything except dist.
- #
- # We also remove comment lines which could be confused with preprocessor
- # directives by some lesser compilers.
- #
- # For ~build2 also filter out config.install.chroot -- we definitely don't
- # want it carried through.
+ # Note: also preserve config.version.
#
- # Finally, for both ~host and ~build2 we keep config.config.environment
- # but strip config.config.hermetic* (we shouldn't be forcing hermiticity
- # on the users of ~host/~build2; they can decide for themselves if they
- # want it).
- #
- build2_config = $regex.replace_lines( \
- $config.save(), \
- '^ *(#|(config\.(dist\.|install\.chroot|config\.hermetic))).*$', \
- [null], \
- return_lines)
+ h = [null]
+ if $regex.match( \
+ $l, \
+ ' *config\.(c[. ]|cxx[. ]|cc[.]|bin[.]|config.environment |version ).*')
+ {
+ if! ($regex.match(\
+ $l, \
+ ' *config\.bin\.(lib|exe\.lib|liba\.lib|libs\.lib)[ =].*'))
+ {
+ # Filter out sanitizer options in ~host. We run the toolchain with
+ # various sanitizers on CI but sanitizers cause issues in some packages.
+ # Note that we can have both -fsanitize and -fno-sanitize forms. For
+ # example:
+ #
+ # -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all
+ #
+ if $regex.match($l, ' *config\.(c|cxx|cc)\.(coptions|loptions)[ =].*')
+ {
+ h = $regex.replace($l, ' ?-f(no-)?sanitize[=-][^ ]+', '')
+ }
+ else
+ h = $l
+ }
+ }
+
+ if ($h != [null])
+ host_config_lines += $h
+
+ build2_config_lines += $l
- # Also preserve config.version and blank lines between groups of options.
+ # Append the warning suppressing option to config.{c,cxx}.coptions rather
+ # than config.cc.coptions since the former could re-enable them.
#
- host_config = $regex.replace_lines( \
- $build2_config, \
- '^( *config\.(c[. ]|cxx[. ]|cc[.]|bin[.]|config.environment |version ).*|)$', \
- '$&', \
- format_no_copy return_lines)
+ 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}
+{
+ 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...}
@@ -158,14 +247,48 @@ if! $cross
{
{obja objs}{context}: cxx.poptions += \
-DBUILD2_IMPORT_PATH=\"$regex.replace($out_root, '\\', '\\\\')\"
+}
- # While this object file should only be linked when we are installing, it
- # will be compiled even in the uninstalled case.
+# Note that while the -installed object file should only be linked when we
+# are installing, it will be compiled even in the uninstalled case.
+#
+if ($install.root != [null])
+{
+ # Only if installed.
+ #
+ {obja objs}{utility-installed}: cxx.poptions += \
+ -DBUILD2_INSTALL_LIB=\"$regex.replace(\
+ $install.resolve($install.lib), '\\', '\\\\')\"
+
+ # Only if configured.
+ #
+ # Note: strip the last directory component (<project>).
#
- if ($install.root != [null])
- {obja objs}{utility-installed}: cxx.poptions += \
- -DBUILD2_INSTALL_LIB=\"$regex.replace(\
- $install.resolve($install.lib), '\\', '\\\\')\"
+ # @@ TMP drop after 0.16.0 release.
+ #
+ install_buildfile = ($install.buildfile != [null] \
+ ? $directory($install.resolve($install.buildfile)) \
+ :)
+ {obja objs}{utility-installed utility-uninstalled}: cxx.poptions += \
+ -DBUILD2_INSTALL_BUILDFILE=\"$regex.replace($install_buildfile, '\\', '\\\\')\"
+
+ #\
+ {obja objs}{utility-installed utility-uninstalled}: cxx.poptions += \
+ -DBUILD2_INSTALL_BUILDFILE=\"$regex.replace(\
+ $directory($install.resolve($install.buildfile)), '\\', '\\\\')\"
+ #\
+
+ # Data directory or src_root if not installed.
+ #
+ # Note: normalized in both cases.
+ #
+ {obja objs}{utility-installed}: cxx.poptions += \
+ -DBUILD2_INSTALL_DATA=\"$regex.replace(\
+ $install.resolve($install.data), '\\', '\\\\')\"
+
+ {obja objs}{utility-uninstalled}: cxx.poptions += \
+ -DBUILD2_INSTALL_DATA=\"$regex.replace(\
+ $src_root, '\\', '\\\\')\"
}
if ($cxx.target.class != 'windows')
@@ -216,38 +339,88 @@ else
# Generated options parser.
#
-script/
+# Note that the cli runtime namespace is build2::build::cli rather than
+# build2::cli. That's because the cli namespace inside build2 is reserved for
+# the cli build system module (libbuild2-cli). In fact, every namespace inside
+# build2 is reserved for a potential module and the only namespace names we
+# can use are build (this name, along with import and export, is reserved by
+# the build system core) and names that start with an underscore.
+#
+if $cli.configured
{
- if $cli.configured
+ cli.options += --std c++11 -I $src_root --include-with-brackets \
+--cli-namespace build2::build::cli --generate-specifier
+
+ cli.cxx{*}:
{
- cli.cxx{builtin-options}: cli{builtin}
+ # Include the generated cli files into the distribution and don't remove
+ # them when cleaning in src (so that clean results in a state identical
+ # to distributed).
+ #
+ dist = true
+ clean = ($src_root != $out_root)
- cli.options += --std c++11 -I $src_root --include-with-brackets \
---include-prefix libbuild2/script --guard-prefix LIBBUILD2_SCRIPT \
---cli-namespace build2::script::cli --generate-vector-scanner \
---generate-modifier --generate-specifier --suppress-usage
+ # We keep the generated code in the repository so copy it back to src in
+ # case of a forwarded configuration.
+ #
+ backlink = overwrite
+ }
- cli.cxx{*}:
- {
- # Include the generated cli files into the distribution and don't remove
- # them when cleaning in src (so that clean results in a state identical
- # to distributed). But don't install their headers since they are only
- # used internally in the testscript implementation.
- #
- dist = true
- clean = ($src_root != $out_root)
- install = false
+ cli.cxx{common-options}: cli{common}
+ {
+ cli.options += --include-prefix libbuild2 --guard-prefix LIBBUILD2 \
+--export-symbol LIBBUILD2_SYMEXPORT \
+--hxx-prologue '#include <libbuild2/export.hxx>' \
+--generate-file-scanner --generate-vector-scanner
+ }
- # We keep the generated code in the repository so copy it back to src in
- # case of a forwarded configuration.
- #
- backlink = overwrite
- }
+ cli.cxx{b-options}: cli{b}
+ {
+ cli.options += --include-prefix libbuild2 --guard-prefix LIBBUILD2 \
+--export-symbol LIBBUILD2_SYMEXPORT \
+--hxx-prologue '#include <libbuild2/export.hxx>' \
+--cxx-prologue "#include <libbuild2/types-parsers.hxx>" \
+--keep-separator --generate-parse --generate-merge
+
+ # Usage options.
+ #
+ cli.options += --suppress-undocumented --long-usage --ansi-color \
+--ascii-tree --page-usage 'build2::print_$name$_' --option-length 23
+ }
+
+ script/cli.cxx{builtin-options}: script/cli{builtin}
+ {
+ cli.options += --include-prefix libbuild2/script \
+--guard-prefix LIBBUILD2_SCRIPT --generate-modifier --suppress-usage
+
+ # Don't install the generated cli headers since they are only used
+ # internally in the script implementation.
+ #
+ install = false
}
- else
- # No install for the pre-generated case.
+
+ build/script/cli.cxx{builtin-options}: build/script/cli{builtin}
+ {
+ cli.options += --include-prefix libbuild2/build/script \
+--guard-prefix LIBBUILD2_BUILD_SCRIPT \
+--cxx-prologue "#include <libbuild2/types-parsers.hxx>" \
+--generate-parse --generate-modifier --suppress-usage
+
+ # Don't install the generated cli headers since they are only used
+ # internally in the buildscript implementation.
#
- hxx{builtin-options}@./ ixx{builtin-options}@./: install = false
+ install = false
+ }
+}
+else
+{
+ # No install for the pre-generated case.
+ #
+ script/hxx{builtin-options}@script/ \
+ script/ixx{builtin-options}@script/: install = false
+
+ build/script/hxx{builtin-options}@build/script/ \
+ build/script/ixx{builtin-options}@build/script/: install = false
}
# Install into the libbuild2/ subdirectory of, say, /usr/include/