aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2022-10-27 19:11:12 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2022-11-23 19:41:21 +0300
commit112916e8d7e40af118e58a3ded2825a37d7e8a93 (patch)
tree764fe6f233f6bafc7f47f8d9417559a4a3c8753d
parentb67a3e4eaa09201a8e22ccfba8fe510568a60e7f (diff)
Add *-build-config, *-builds, *-build-{include,exclude} package manifest values
-rw-r--r--libbpkg/manifest.cxx92
-rw-r--r--libbpkg/manifest.hxx70
-rw-r--r--tests/manifest/testscript69
3 files changed, 222 insertions, 9 deletions
diff --git a/libbpkg/manifest.cxx b/libbpkg/manifest.cxx
index 732b689..c362379 100644
--- a/libbpkg/manifest.cxx
+++ b/libbpkg/manifest.cxx
@@ -3542,6 +3542,27 @@ namespace bpkg
}
};
+ // Return the package build configuration with the specified name, if
+ // already exists, or the newly created configuration otherwise.
+ //
+ auto build_conf = [&m] (string&& nm) -> build_package_config&
+ {
+ vector<build_package_config>& cs (m.build_configs);
+
+ auto i (find_if (cs.begin (), cs.end (),
+ [&nm] (const build_package_config& c)
+ {return c.name == nm;}));
+
+ if (i != cs.end ())
+ return *i;
+
+ // Add the new build configuration (arguments, builds, etc will come
+ // later).
+ //
+ cs.emplace_back (move (nm));
+ return cs.back ();
+ };
+
// Cache the upstream version manifest value and validate whether it's
// allowed later, after the version value is parsed.
//
@@ -3862,6 +3883,50 @@ namespace bpkg
m.build_constraints.push_back (
parse_build_constraint (nv, true /* exclusion */, name));
}
+ else if ((n.size () > 13 &&
+ n.compare (n.size () - 13, 13, "-build-config") == 0))
+ {
+ auto vc (parser::split_comment (v));
+
+ n.resize (n.size () - 13);
+
+ build_package_config& bc (build_conf (move (n)));
+
+ if (!bc.arguments.empty () || !bc.comment.empty ())
+ bad_name ("build configuration redefinition");
+
+ bc.arguments = move (vc.first);
+ bc.comment = move (vc.second);
+ }
+ else if ((n.size () > 7 && n.compare (n.size () - 7, 7, "-builds") == 0))
+ {
+ n.resize (n.size () - 7);
+
+ build_package_config& bc (build_conf (move (n)));
+
+ bc.builds.push_back (
+ parse_build_class_expr (nv, bc.builds.empty (), name));
+ }
+ else if ((n.size () > 14 &&
+ n.compare (n.size () - 14, 14, "-build-include") == 0))
+ {
+ n.resize (n.size () - 14);
+
+ build_package_config& bc (build_conf (move (n)));
+
+ bc.constraints.push_back (
+ parse_build_constraint (nv, false /* exclusion */, name));
+ }
+ else if ((n.size () > 14 &&
+ n.compare (n.size () - 14, 14, "-build-exclude") == 0))
+ {
+ n.resize (n.size () - 14);
+
+ build_package_config& bc (build_conf (move (n)));
+
+ bc.constraints.push_back (
+ parse_build_constraint (nv, true /* exclusion */, name));
+ }
// @@ TMP time to drop *-0.14.0?
//
else if (n == "tests" || n == "tests-0.14.0" ||
@@ -4699,6 +4764,33 @@ namespace bpkg
: c.config + '/' + *c.target,
c.comment));
+ for (const build_package_config& bc: m.build_configs)
+ {
+ if (!bc.arguments.empty () || !bc.comment.empty ())
+ s.next (bc.name + "-build-config",
+ serializer::merge_comment (bc.arguments, bc.comment));
+
+ if (!bc.builds.empty ())
+ {
+ string n (bc.name + "-builds");
+ for (const build_class_expr& e: bc.builds)
+ s.next (n, serializer::merge_comment (e.string (), e.comment));
+ }
+
+ if (!bc.constraints.empty ())
+ {
+ string in (bc.name + "-build-include");
+ string en (bc.name + "-build-exclude");
+
+ for (const build_constraint& c: bc.constraints)
+ s.next (c.exclusion ? en : in,
+ serializer::merge_comment (!c.target
+ ? c.config
+ : c.config + '/' + *c.target,
+ c.comment));
+ }
+ }
+
bool an (m.alt_naming && *m.alt_naming);
if (m.bootstrap_build)
diff --git a/libbpkg/manifest.hxx b/libbpkg/manifest.hxx
index cad3c1e..ae2051e 100644
--- a/libbpkg/manifest.hxx
+++ b/libbpkg/manifest.hxx
@@ -776,7 +776,7 @@ namespace bpkg
class build_constraint
{
public:
- // If true, then the package should not be built for matching
+ // If true, then the package should not be built for matching target
// configurations by automated build bots.
//
bool exclusion;
@@ -853,7 +853,7 @@ namespace bpkg
return x |= y;
}
- // Build configuration class term.
+ // Target build configuration class term.
//
class LIBBPKG_EXPORT build_class_term
{
@@ -903,8 +903,8 @@ namespace bpkg
//
using build_class_inheritance_map = std::map<std::string, std::string>;
- // Build configuration class expression. Includes comment and optional
- // underlying set.
+ // Target build configuration class expression. Includes comment and
+ // optional underlying set.
//
class LIBBPKG_EXPORT build_class_expr
{
@@ -953,10 +953,10 @@ namespace bpkg
std::string
string () const;
- // Match a build configuration that belongs to the specified list of
- // classes (and recursively to their bases) against the expression. Either
- // return or update the result (the latter allows to sequentially matching
- // against a list of expressions).
+ // Match a target build configuration that belongs to the specified list
+ // of classes (and recursively to their bases) against the expression.
+ // Either return or update the result (the latter allows to sequentially
+ // matching against a list of expressions).
//
// Notes:
//
@@ -964,7 +964,8 @@ namespace bpkg
// inheritance cycles, etc.).
//
// - The underlying class set doesn't affect the match in any way (it
- // should have been used to pre-filter the set of build configurations).
+ // should have been used to pre-filter the set of target build
+ // configurations).
//
void
match (const strings&,
@@ -986,6 +987,52 @@ namespace bpkg
return os << bce.string ();
}
+ // Package build configuration. Includes comment and optional target build
+ // configuration class expressions/constraints overrides.
+ //
+ class build_package_config
+ {
+ public:
+ std::string name;
+
+ // Whitespace separated list of potentially double/single-quoted package
+ // configuration arguments for bpkg-pkg-build command executed by
+ // automated build bots.
+ //
+ std::string arguments;
+
+ std::string comment;
+
+ butl::small_vector<build_class_expr, 1> builds;
+ std::vector<build_constraint> constraints;
+
+ build_package_config () = default;
+
+ // Built incrementally.
+ //
+ explicit
+ build_package_config (std::string n): name (move (n)) {}
+
+ // Return the configuration's build class expressions/constraints if they
+ // override the specified common expressions/constraints and return the
+ // latter otherwise (see package_manifest::override() for the override
+ // semantics details).
+ //
+ const butl::small_vector<build_class_expr, 1>&
+ effective_builds (const butl::small_vector<build_class_expr, 1>& common)
+ const noexcept
+ {
+ return !builds.empty () ? builds : common;
+ }
+
+ const std::vector<build_constraint>&
+ effective_constraints (const std::vector<build_constraint>& common) const
+ noexcept
+ {
+ return !builds.empty () || !constraints.empty () ? constraints : common;
+ }
+ };
+
enum class text_type
{
plain,
@@ -1116,9 +1163,14 @@ namespace bpkg
std::vector<requirement_alternatives> requirements;
butl::small_vector<test_dependency, 1> tests;
+ // Common build classes/constraints that apply to all configurations
+ // unless overridden.
+ //
butl::small_vector<build_class_expr, 1> builds;
std::vector<build_constraint> build_constraints;
+ std::vector<build_package_config> build_configs;
+
// If true, then this package use the alternative buildfile naming scheme
// (build2/, .build2). In the manifest serialization this is encoded as
// either *-build or *-build2 value names.
diff --git a/tests/manifest/testscript b/tests/manifest/testscript
index 440e61f..336b288 100644
--- a/tests/manifest/testscript
+++ b/tests/manifest/testscript
@@ -541,6 +541,71 @@
EOI
}
+ : build-config
+ :
+ {
+ : multiple
+ :
+ {
+ $* <<EOF >>EOF
+ : 1
+ name: foo
+ version: 2.0.0
+ summary: Modern C++ parser
+ license: LGPLv2
+ bar-build-config: config.foo.bar = true; Bar.
+ bar-builds: all
+ baz-build-config: config.foo.baz = true; Baz.
+ EOF
+ }
+
+ : empty
+ :
+ $* <<EOF >>EOF
+ : 1
+ name: foo
+ version: 2.0.0
+ summary: Modern C++ parser
+ license: LGPLv2
+ network-build-config: ; None.
+ EOF
+
+ : undefined
+ :
+ {
+ $* <<EOF >>EOF
+ : 1
+ name: foo
+ version: 2.0.0
+ summary: Modern C++ parser
+ license: LGPLv2
+ bar-builds: default
+ baz-build-config: config.foo.bar = true
+ EOF
+ }
+
+ : redefinition
+ :
+ {
+ $* <<EOI 2>"stdin:3:1: error: build configuration redefinition" != 0
+ : 1
+ bar-build-config: config.foo.bar = true
+ bar-build-config: config.foo.bar = true
+ EOI
+ }
+
+ : unexpected-underlying-class-set
+ :
+ {
+ $* <<EOI 2>"stdin:4:13: error: invalid package builds: unexpected underlying class set" != 0
+ : 1
+ bar-build-config: config.foo.bar = true
+ bar-builds: all
+ bar-builds: all
+ EOI
+ }
+ }
+
: depends
:
{
@@ -3773,6 +3838,10 @@
build-include: linux*
build-include: freebsd*
build-exclude: *; Only supports Linux and FreeBSD.
+ network-build-config: config.libfoo.network=true; Enable networking API.
+ network-builds: default
+ network-build-include: linux*
+ network-build-exclude: *; Only supports Linux.
bootstrap-build:\
project = libfoo