From a69f728a710bcc4e17913a57ffb01da076467bfb Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sat, 29 Jul 2017 10:54:31 +0200 Subject: Convert to use utility library --- bbot/agent/agent.cxx | 2 +- bbot/agent/machine-manifest.cxx | 355 -------------------------------- bbot/agent/machine-manifest.hxx | 118 ----------- bbot/agent/machine.cxx | 3 +- bbot/buildfile | 35 ++-- bbot/machine-manifest.cxx | 355 ++++++++++++++++++++++++++++++++ bbot/machine-manifest.hxx | 118 +++++++++++ build/root.build | 4 +- unit-tests/bootstrap-manifest/buildfile | 7 +- unit-tests/machine-manifest/buildfile | 7 +- unit-tests/machine-manifest/driver.cxx | 2 +- 11 files changed, 500 insertions(+), 506 deletions(-) delete mode 100644 bbot/agent/machine-manifest.cxx delete mode 100644 bbot/agent/machine-manifest.hxx create mode 100644 bbot/machine-manifest.cxx create mode 100644 bbot/machine-manifest.hxx diff --git a/bbot/agent/agent.cxx b/bbot/agent/agent.cxx index 80b4fb7..c0849c6 100644 --- a/bbot/agent/agent.cxx +++ b/bbot/agent/agent.cxx @@ -30,11 +30,11 @@ #include #include +#include #include #include #include -#include using namespace std; using namespace butl; diff --git a/bbot/agent/machine-manifest.cxx b/bbot/agent/machine-manifest.cxx deleted file mode 100644 index 3312d1b..0000000 --- a/bbot/agent/machine-manifest.cxx +++ /dev/null @@ -1,355 +0,0 @@ -// file : bbot/agent/machine-manifest.cxx -*- C++ -*- -// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd -// license : TBC; see accompanying LICENSE file - -#include - -#include - -#include -#include -#include -#include - -using namespace std; -using namespace butl; - -namespace bbot -{ - using parser = manifest_parser; - using parsing = manifest_parsing; - using serializer = manifest_serializer; - using serialization = manifest_serialization; - using name_value = manifest_name_value; - - // machine_type - // - string - to_string (machine_type t) - { - switch (t) - { - case machine_type::kvm: return "kvm"; - case machine_type::nspawn: return "nspawn"; - } - - assert (false); - return string (); - } - - machine_type - to_machine_type (const string& t) - { - if (t == "kvm") return machine_type::kvm; - else if (t == "nspawn") return machine_type::nspawn; - else throw invalid_argument ("invalid machine type '" + t + "'"); - } - - // machine_manifest - // - machine_manifest:: - machine_manifest (parser& p, bool iu) - : machine_manifest (p, p.next (), iu) - { - // Make sure this is the end. - // - name_value nv (p.next ()); - if (!nv.empty ()) - throw parsing (p.name (), nv.name_line, nv.name_column, - "single machine manifest expected"); - } - - machine_manifest:: - machine_manifest (parser& p, name_value nv, bool iu) - : machine_header_manifest (p, move (nv), unknown_name_mode::stop, &nv) - { - auto bad_name = [&p, &nv] (const string& d) - { - throw parsing (p.name (), nv.name_line, nv.name_column, d); - }; - - // Offsets are used to tie an error to the specific position inside a - // manifest value (possibly a multiline one). - // - auto bad_value = [&p, &nv] ( - const string& d, uint64_t column_offset = 0, uint64_t line_offset = 0) - { - throw parsing (p.name (), - nv.value_line + line_offset, - (line_offset == 0 ? nv.value_column : 1) + column_offset, - d); - }; - - optional type; - - for (; !nv.empty (); nv = p.next ()) - { - string& n (nv.name); - string& v (nv.value); - - if (n == "type") - { - if (type) - bad_name ("machine type redefinition"); - - try - { - type = to_machine_type (v); - } - catch (const invalid_argument&) - { - bad_value ("invalid machine type"); - } - } - else if (n == "mac") - { - if (mac) - bad_name ("machine mac redefinition"); - - // @@ Should we check that the value is a valid mac? - // - mac = move (v); - } - else if (n == "options") - { - if (options) - bad_name ("machine options redefinition"); - - strings op; - - // Note that when reporting errors we combine the manifest value - // position with the respective error position. - // - try - { - istringstream is (v); - tab_parser parser (is, ""); - - tab_fields tl; - while (!(tl = parser.next ()).empty ()) - { - for (auto& tf: tl) - op.emplace_back (move (tf.value)); - } - } - catch (const tab_parsing& e) - { - bad_value ("invalid machine options: " + e.description, - e.column - 1, - e.line - 1); - } - - if (op.empty ()) - bad_value ("empty machine options"); - - options = move (op); - } - else if (!iu) - bad_name ("unknown name '" + n + "' in machine manifest"); - } - - // Verify all non-optional values were specified. - // - if (!type) - bad_value ("no machine type specified"); - - this->type = *type; - } - - void machine_manifest:: - serialize (serializer& s) const - { - // @@ Should we check that all non-optional values are specified and all - // values are valid? - // - - machine_header_manifest::serialize (s, false); - - s.next ("type", to_string (type)); - - if (mac) - s.next ("mac", *mac); - - // Recompose options string as a space-separated option list, - // - if (options) - { - string v; - for (auto b (options->cbegin ()), i (b), e (options->cend ()); i != e; - ++i) - { - if (i != b) - v += ' '; - - v += *i; - } - - s.next ("options", v); - } - - s.next ("", ""); // End of manifest. - } - - strings machine_manifest:: - unquoted_options () const - { - return options - ? string_parser::unquote (*options) - : strings (); - } - - // toolchain_manifest - // - toolchain_manifest:: - toolchain_manifest (parser& p, bool iu) - : toolchain_manifest (p, p.next (), iu) - { - // Make sure this is the end. - // - name_value nv (p.next ()); - if (!nv.empty ()) - throw parsing (p.name (), nv.name_line, nv.name_column, - "single toolchain manifest expected"); - } - - toolchain_manifest:: - toolchain_manifest (parser& p, name_value nv, bool iu) - { - auto bad_name = [&p, &nv] (const string& d) - { - throw parsing (p.name (), nv.name_line, nv.name_column, d); - }; - - auto bad_value = [&p, &nv] (const string& d) - { - throw parsing (p.name (), nv.value_line, nv.value_column, d); - }; - - // Make sure this is the start and we support the version. - // - if (!nv.name.empty ()) - bad_name ("start of toolchain manifest expected"); - - if (nv.value != "1") - bad_value ("unsupported format version"); - - // Parse the toolchain manifest. - // - for (nv = p.next (); !nv.empty (); nv = p.next ()) - { - string& n (nv.name); - string& v (nv.value); - - if (n == "id") - { - if (!id.empty ()) - bad_name ("toolchain id redefinition"); - - if (v.empty ()) - bad_value ("empty toolchain id"); - - id = move (v); - } - else if (!iu) - bad_name ("unknown name '" + n + "' in toolchain manifest"); - } - - // Verify all non-optional values were specified. - // - if (id.empty ()) - bad_value ("no toolchain id specified"); - } - - void toolchain_manifest:: - serialize (serializer& s) const - { - // @@ Should we check that all non-optional values are specified? - // - s.next ("", "1"); // Start of manifest. - s.next ("id", id); - s.next ("", ""); // End of manifest. - } - - // bootstrapped_machine_manifest - // - bootstrapped_machine_manifest:: - bootstrapped_machine_manifest (parser& p, bool iu) - { - name_value nv (p.next ()); - - auto bad_name = [&p, &nv] (const string& d) - { - throw parsing (p.name (), nv.name_line, nv.name_column, d); - }; - - auto bad_value = [&p, &nv] (const string& d) - { - throw parsing (p.name (), nv.value_line, nv.value_column, d); - }; - - // Make sure this is the start and we support the version. - // - if (!nv.name.empty ()) - bad_name ("start of bootstrapped machine manifest expected"); - - if (nv.value != "1") - bad_value ("unsupported format version"); - - // Parse the bootstrapped machine manifest. Currently there is no values - // expected. - // - for (nv = p.next (); !nv.empty (); nv = p.next ()) - { - if (!iu) - bad_name ("unknown name '" + nv.name + - "' in bootstrapped machine manifest"); - } - - nv = p.next (); - if (nv.empty ()) - bad_value ("machine manifest expected"); - - machine = machine_manifest (p, nv, iu); - - if (!machine.mac) - bad_name ("mac address must be present in machine manifest"); - - nv = p.next (); - if (nv.empty ()) - bad_value ("toolchain manifest expected"); - - toolchain = toolchain_manifest (p, nv, iu); - - nv = p.next (); - if (nv.empty ()) - bad_value ("bootstrap manifest expected"); - - bootstrap = bootstrap_manifest (p, nv, iu); - - // Make sure this is the end. - // - nv = p.next (); - if (!nv.empty ()) - throw parsing (p.name (), nv.name_line, nv.name_column, - "single bootstrapped machine manifest expected"); - } - - void bootstrapped_machine_manifest:: - serialize (serializer& s) const - { - // @@ Should we check that all non-optional values are specified? - // - s.next ("", "1"); // Start of manifest. - s.next ("", ""); // End of manifest. - - if (!machine.mac) - throw serialization (s.name (), - "mac address must be present in machine manifest"); - - machine.serialize (s); - toolchain.serialize (s); - bootstrap.serialize (s); - - s.next ("", ""); // End of stream. - } -} diff --git a/bbot/agent/machine-manifest.hxx b/bbot/agent/machine-manifest.hxx deleted file mode 100644 index 37919ba..0000000 --- a/bbot/agent/machine-manifest.hxx +++ /dev/null @@ -1,118 +0,0 @@ -// file : bbot/agent/machine-manifest.hxx -*- C++ -*- -// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd -// license : TBC; see accompanying LICENSE file - -#ifndef BBOT_AGENT_MACHINE_MANIFEST_HXX -#define BBOT_AGENT_MACHINE_MANIFEST_HXX - -#include - -#include - -#include // machine_header - -#include -#include - -#include - -namespace bbot -{ - // Machine type. - // - enum class machine_type {kvm, nspawn}; - - string - to_string (machine_type); - - machine_type - to_machine_type (const string&); // Throws invalid_argument. - - // Machine. - // - class machine_manifest: public machine_header_manifest - { - public: - machine_type type; - optional mac; // Required in bootstrapped machine manifest. - optional options; // Note: could be quoted. - - strings - unquoted_options () const; // Return empty if absent. - - machine_manifest (std::string i, - std::string n, - std::string s, - machine_type t, - optional m, - optional o) - : machine_header_manifest (std::move (i), - std::move (n), - std::move (s)), - type (t), - mac (std::move (m)), - options (std::move (o)) {} - - public: - machine_manifest () = default; // VC export. - machine_manifest (butl::manifest_parser&, bool ignore_unknown = false); - machine_manifest (butl::manifest_parser&, - butl::manifest_name_value start, - bool ignore_unknown = false); - - void - serialize (butl::manifest_serializer&) const; - }; - - // Toolchain. - // - class toolchain_manifest - { - public: - - // Toolchain id (SHAXXX). - // - string id; - - explicit - toolchain_manifest (string i): id (i) {} - - public: - toolchain_manifest () = default; // VC export. - toolchain_manifest (butl::manifest_parser&, bool ignore_unknown = false); - toolchain_manifest (butl::manifest_parser&, - butl::manifest_name_value start, - bool ignore_unknown = false); - - void - serialize (butl::manifest_serializer&) const; - }; - - // The manifest stored in -/ consists of the machine - // manifest (original), toolchain manifest, and bootstrap manifest. - // - class bootstrapped_machine_manifest - { - public: - machine_manifest machine; - toolchain_manifest toolchain; - bootstrap_manifest bootstrap; - - bootstrapped_machine_manifest (machine_manifest m, - toolchain_manifest t, - bootstrap_manifest b) - : machine (move (m)), toolchain (move (t)), bootstrap (move (b)) {} - - public: - bootstrapped_machine_manifest () = default; // VC export. - bootstrapped_machine_manifest (butl::manifest_parser&, - bool ignore_unknown = false); - - void - serialize (butl::manifest_serializer&) const; - }; - - using bootstrapped_machine_manifests = vector; -} - -#endif // BBOT_AGENT_MACHINE_MANIFEST_HXX diff --git a/bbot/agent/machine.cxx b/bbot/agent/machine.cxx index 422c623..f3c9874 100644 --- a/bbot/agent/machine.cxx +++ b/bbot/agent/machine.cxx @@ -12,8 +12,9 @@ #include // snprintf() #include // strcpy() +#include + #include -#include using namespace std; using namespace butl; diff --git a/bbot/buildfile b/bbot/buildfile index a576cce..60f120f 100644 --- a/bbot/buildfile +++ b/bbot/buildfile @@ -5,7 +5,7 @@ # Systemd .service file. # # @@ Currently the executable path is hardcoded as /usr/bin/bbot-agent. To -# handle this properly would need to generate/pre-process it )and detect +# handle this properly would need to generate/pre-process it (and detect # update for install). # define service: file @@ -24,18 +24,19 @@ if ($cxx.target.class == "linux") { ./: exe{bbot-agent} service{'bbot-agent@'} - exe{bbot-agent}: {hxx ixx txx cxx}{* +agent/* -**-options -version} \ - {hxx ixx cxx}{common-options agent/agent-options} \ - {hxx}{version} \ - $libs + exe{bbot-agent}: agent/{hxx ixx txx cxx}{* -agent-options} \ + agent/{hxx ixx cxx}{agent-options} libu{bbot} } ./: exe{bbot-worker} -exe{bbot-worker}: {hxx ixx txx cxx}{* +worker/* -**-options -version} \ - {hxx ixx cxx}{common-options worker/worker-options} \ - {hxx}{version} \ - $libs +exe{bbot-worker}: worker/{hxx ixx txx cxx}{* -worker-options} \ + worker/{hxx ixx cxx}{worker-options} libu{bbot} + +libu{bbot}: bin.whole = false +libu{bbot}: {hxx ixx txx cxx}{* -common-options -version} \ + {hxx ixx cxx}{common-options} {hxx}{version} \ + $libs hxx{version}: in{version} $src_root/file{manifest} hxx{version}: dist = true @@ -45,26 +46,26 @@ hxx{version}: dist = true if $cli.configured { cli.cxx{common-options}: cli{common} - cli.cxx{agent/agent-options}: cli{agent/agent} - cli.cxx{worker/worker-options}: cli{worker/worker} + agent/cli.cxx{agent-options}: cli{agent/agent} + worker/cli.cxx{worker-options}: cli{worker/worker} cli.options += -I $src_root --include-with-brackets \ --cxx-prologue "#include " \ --cli-namespace bbot::cli --generate-specifier --generate-parse - cli.cxx{common-options}: \ - cli.options += --include-prefix bbot --guard-prefix BBOT # No usage. + cli.cxx{common-options}: cli.options += --include-prefix bbot \ +--guard-prefix BBOT # No usage. # Usage options. # cli.options += --suppress-undocumented --long-usage --ansi-color \ --page-usage 'bbot::print_$name$_' --option-length 23 - cli.cxx{agent/agent-options}: \ - cli.options += --include-prefix bbot/agent --guard-prefix BBOT_AGENT + agent/cli.cxx{agent-options}: cli.options += --include-prefix bbot/agent \ +--guard-prefix BBOT_AGENT - cli.cxx{worker/worker-options}: \ - cli.options += --include-prefix bbot/worker --guard-prefix BBOT_WORKER + worker/cli.cxx{worker-options}: cli.options += --include-prefix bbot/worker \ +--guard-prefix BBOT_WORKER # Include generated cli files into the distribution. # diff --git a/bbot/machine-manifest.cxx b/bbot/machine-manifest.cxx new file mode 100644 index 0000000..b7baf7e --- /dev/null +++ b/bbot/machine-manifest.cxx @@ -0,0 +1,355 @@ +// file : bbot/machine-manifest.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +// license : TBC; see accompanying LICENSE file + +#include + +#include + +#include +#include +#include +#include + +using namespace std; +using namespace butl; + +namespace bbot +{ + using parser = manifest_parser; + using parsing = manifest_parsing; + using serializer = manifest_serializer; + using serialization = manifest_serialization; + using name_value = manifest_name_value; + + // machine_type + // + string + to_string (machine_type t) + { + switch (t) + { + case machine_type::kvm: return "kvm"; + case machine_type::nspawn: return "nspawn"; + } + + assert (false); + return string (); + } + + machine_type + to_machine_type (const string& t) + { + if (t == "kvm") return machine_type::kvm; + else if (t == "nspawn") return machine_type::nspawn; + else throw invalid_argument ("invalid machine type '" + t + "'"); + } + + // machine_manifest + // + machine_manifest:: + machine_manifest (parser& p, bool iu) + : machine_manifest (p, p.next (), iu) + { + // Make sure this is the end. + // + name_value nv (p.next ()); + if (!nv.empty ()) + throw parsing (p.name (), nv.name_line, nv.name_column, + "single machine manifest expected"); + } + + machine_manifest:: + machine_manifest (parser& p, name_value nv, bool iu) + : machine_header_manifest (p, move (nv), unknown_name_mode::stop, &nv) + { + auto bad_name = [&p, &nv] (const string& d) + { + throw parsing (p.name (), nv.name_line, nv.name_column, d); + }; + + // Offsets are used to tie an error to the specific position inside a + // manifest value (possibly a multiline one). + // + auto bad_value = [&p, &nv] ( + const string& d, uint64_t column_offset = 0, uint64_t line_offset = 0) + { + throw parsing (p.name (), + nv.value_line + line_offset, + (line_offset == 0 ? nv.value_column : 1) + column_offset, + d); + }; + + optional type; + + for (; !nv.empty (); nv = p.next ()) + { + string& n (nv.name); + string& v (nv.value); + + if (n == "type") + { + if (type) + bad_name ("machine type redefinition"); + + try + { + type = to_machine_type (v); + } + catch (const invalid_argument&) + { + bad_value ("invalid machine type"); + } + } + else if (n == "mac") + { + if (mac) + bad_name ("machine mac redefinition"); + + // @@ Should we check that the value is a valid mac? + // + mac = move (v); + } + else if (n == "options") + { + if (options) + bad_name ("machine options redefinition"); + + strings op; + + // Note that when reporting errors we combine the manifest value + // position with the respective error position. + // + try + { + istringstream is (v); + tab_parser parser (is, ""); + + tab_fields tl; + while (!(tl = parser.next ()).empty ()) + { + for (auto& tf: tl) + op.emplace_back (move (tf.value)); + } + } + catch (const tab_parsing& e) + { + bad_value ("invalid machine options: " + e.description, + e.column - 1, + e.line - 1); + } + + if (op.empty ()) + bad_value ("empty machine options"); + + options = move (op); + } + else if (!iu) + bad_name ("unknown name '" + n + "' in machine manifest"); + } + + // Verify all non-optional values were specified. + // + if (!type) + bad_value ("no machine type specified"); + + this->type = *type; + } + + void machine_manifest:: + serialize (serializer& s) const + { + // @@ Should we check that all non-optional values are specified and all + // values are valid? + // + + machine_header_manifest::serialize (s, false); + + s.next ("type", to_string (type)); + + if (mac) + s.next ("mac", *mac); + + // Recompose options string as a space-separated option list, + // + if (options) + { + string v; + for (auto b (options->cbegin ()), i (b), e (options->cend ()); i != e; + ++i) + { + if (i != b) + v += ' '; + + v += *i; + } + + s.next ("options", v); + } + + s.next ("", ""); // End of manifest. + } + + strings machine_manifest:: + unquoted_options () const + { + return options + ? string_parser::unquote (*options) + : strings (); + } + + // toolchain_manifest + // + toolchain_manifest:: + toolchain_manifest (parser& p, bool iu) + : toolchain_manifest (p, p.next (), iu) + { + // Make sure this is the end. + // + name_value nv (p.next ()); + if (!nv.empty ()) + throw parsing (p.name (), nv.name_line, nv.name_column, + "single toolchain manifest expected"); + } + + toolchain_manifest:: + toolchain_manifest (parser& p, name_value nv, bool iu) + { + auto bad_name = [&p, &nv] (const string& d) + { + throw parsing (p.name (), nv.name_line, nv.name_column, d); + }; + + auto bad_value = [&p, &nv] (const string& d) + { + throw parsing (p.name (), nv.value_line, nv.value_column, d); + }; + + // Make sure this is the start and we support the version. + // + if (!nv.name.empty ()) + bad_name ("start of toolchain manifest expected"); + + if (nv.value != "1") + bad_value ("unsupported format version"); + + // Parse the toolchain manifest. + // + for (nv = p.next (); !nv.empty (); nv = p.next ()) + { + string& n (nv.name); + string& v (nv.value); + + if (n == "id") + { + if (!id.empty ()) + bad_name ("toolchain id redefinition"); + + if (v.empty ()) + bad_value ("empty toolchain id"); + + id = move (v); + } + else if (!iu) + bad_name ("unknown name '" + n + "' in toolchain manifest"); + } + + // Verify all non-optional values were specified. + // + if (id.empty ()) + bad_value ("no toolchain id specified"); + } + + void toolchain_manifest:: + serialize (serializer& s) const + { + // @@ Should we check that all non-optional values are specified? + // + s.next ("", "1"); // Start of manifest. + s.next ("id", id); + s.next ("", ""); // End of manifest. + } + + // bootstrapped_machine_manifest + // + bootstrapped_machine_manifest:: + bootstrapped_machine_manifest (parser& p, bool iu) + { + name_value nv (p.next ()); + + auto bad_name = [&p, &nv] (const string& d) + { + throw parsing (p.name (), nv.name_line, nv.name_column, d); + }; + + auto bad_value = [&p, &nv] (const string& d) + { + throw parsing (p.name (), nv.value_line, nv.value_column, d); + }; + + // Make sure this is the start and we support the version. + // + if (!nv.name.empty ()) + bad_name ("start of bootstrapped machine manifest expected"); + + if (nv.value != "1") + bad_value ("unsupported format version"); + + // Parse the bootstrapped machine manifest. Currently there is no values + // expected. + // + for (nv = p.next (); !nv.empty (); nv = p.next ()) + { + if (!iu) + bad_name ("unknown name '" + nv.name + + "' in bootstrapped machine manifest"); + } + + nv = p.next (); + if (nv.empty ()) + bad_value ("machine manifest expected"); + + machine = machine_manifest (p, nv, iu); + + if (!machine.mac) + bad_name ("mac address must be present in machine manifest"); + + nv = p.next (); + if (nv.empty ()) + bad_value ("toolchain manifest expected"); + + toolchain = toolchain_manifest (p, nv, iu); + + nv = p.next (); + if (nv.empty ()) + bad_value ("bootstrap manifest expected"); + + bootstrap = bootstrap_manifest (p, nv, iu); + + // Make sure this is the end. + // + nv = p.next (); + if (!nv.empty ()) + throw parsing (p.name (), nv.name_line, nv.name_column, + "single bootstrapped machine manifest expected"); + } + + void bootstrapped_machine_manifest:: + serialize (serializer& s) const + { + // @@ Should we check that all non-optional values are specified? + // + s.next ("", "1"); // Start of manifest. + s.next ("", ""); // End of manifest. + + if (!machine.mac) + throw serialization (s.name (), + "mac address must be present in machine manifest"); + + machine.serialize (s); + toolchain.serialize (s); + bootstrap.serialize (s); + + s.next ("", ""); // End of stream. + } +} diff --git a/bbot/machine-manifest.hxx b/bbot/machine-manifest.hxx new file mode 100644 index 0000000..efcdda4 --- /dev/null +++ b/bbot/machine-manifest.hxx @@ -0,0 +1,118 @@ +// file : bbot/machine-manifest.hxx -*- C++ -*- +// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +// license : TBC; see accompanying LICENSE file + +#ifndef BBOT_MACHINE_MANIFEST_HXX +#define BBOT_MACHINE_MANIFEST_HXX + +#include + +#include + +#include // machine_header + +#include +#include + +#include + +namespace bbot +{ + // Machine type. + // + enum class machine_type {kvm, nspawn}; + + string + to_string (machine_type); + + machine_type + to_machine_type (const string&); // Throws invalid_argument. + + // Machine. + // + class machine_manifest: public machine_header_manifest + { + public: + machine_type type; + optional mac; // Required in bootstrapped machine manifest. + optional options; // Note: could be quoted. + + strings + unquoted_options () const; // Return empty if absent. + + machine_manifest (std::string i, + std::string n, + std::string s, + machine_type t, + optional m, + optional o) + : machine_header_manifest (std::move (i), + std::move (n), + std::move (s)), + type (t), + mac (std::move (m)), + options (std::move (o)) {} + + public: + machine_manifest () = default; // VC export. + machine_manifest (butl::manifest_parser&, bool ignore_unknown = false); + machine_manifest (butl::manifest_parser&, + butl::manifest_name_value start, + bool ignore_unknown = false); + + void + serialize (butl::manifest_serializer&) const; + }; + + // Toolchain. + // + class toolchain_manifest + { + public: + + // Toolchain id (SHAXXX). + // + string id; + + explicit + toolchain_manifest (string i): id (i) {} + + public: + toolchain_manifest () = default; // VC export. + toolchain_manifest (butl::manifest_parser&, bool ignore_unknown = false); + toolchain_manifest (butl::manifest_parser&, + butl::manifest_name_value start, + bool ignore_unknown = false); + + void + serialize (butl::manifest_serializer&) const; + }; + + // The manifest stored in -/ consists of the machine + // manifest (original), toolchain manifest, and bootstrap manifest. + // + class bootstrapped_machine_manifest + { + public: + machine_manifest machine; + toolchain_manifest toolchain; + bootstrap_manifest bootstrap; + + bootstrapped_machine_manifest (machine_manifest m, + toolchain_manifest t, + bootstrap_manifest b) + : machine (move (m)), toolchain (move (t)), bootstrap (move (b)) {} + + public: + bootstrapped_machine_manifest () = default; // VC export. + bootstrapped_machine_manifest (butl::manifest_parser&, + bool ignore_unknown = false); + + void + serialize (butl::manifest_serializer&) const; + }; + + using bootstrapped_machine_manifests = vector; +} + +#endif // BBOT_MACHINE_MANIFEST_HXX diff --git a/build/root.build b/build/root.build index f63ff10..363cb62 100644 --- a/build/root.build +++ b/build/root.build @@ -21,9 +21,11 @@ cxx.poptions =+ "-I$out_root" "-I$src_root" # using? cli -# All exe{} in unit-tests/ are, well, tests. +# All exe{} in unit-tests/ are, well, tests. Also don't link whole archives +# by default there. # unit-tests/exe{*}: test = true +unit-tests/libu{*}: bin.whole = false # Specify the test target for cross-testing. # diff --git a/unit-tests/bootstrap-manifest/buildfile b/unit-tests/bootstrap-manifest/buildfile index 2be37fb..c628833 100644 --- a/unit-tests/bootstrap-manifest/buildfile +++ b/unit-tests/bootstrap-manifest/buildfile @@ -2,10 +2,5 @@ # copyright : Copyright (c) 2014-2017 Code Synthesis Ltd # license : TBC; see accompanying LICENSE file -import libs = libbutl%lib{butl} -import libs += libbbot%lib{bbot} - -exe{driver}: {hxx cxx}{*} ../../bbot/{hxx cxx}{bootstrap-manifest} $libs \ - test{testscript} - include ../../bbot/ +exe{driver}: {hxx cxx}{*} ../../bbot/libu{bbot} test{testscript} diff --git a/unit-tests/machine-manifest/buildfile b/unit-tests/machine-manifest/buildfile index d56aa1f..6d47d77 100644 --- a/unit-tests/machine-manifest/buildfile +++ b/unit-tests/machine-manifest/buildfile @@ -2,10 +2,5 @@ # copyright : Copyright (c) 2014-2017 Code Synthesis Ltd # license : TBC; see accompanying LICENSE file -import libs = libbutl%lib{butl} -import libs += libbbot%lib{bbot} - -exe{driver}: {hxx cxx}{*} ../../bbot/{hxx cxx}{**-manifest} $libs \ - test{testscript} - include ../../bbot/ +exe{driver}: {hxx cxx}{*} ../../bbot/libu{bbot} test{testscript} diff --git a/unit-tests/machine-manifest/driver.cxx b/unit-tests/machine-manifest/driver.cxx index db42434..44b1e36 100644 --- a/unit-tests/machine-manifest/driver.cxx +++ b/unit-tests/machine-manifest/driver.cxx @@ -11,7 +11,7 @@ #include #include -#include +#include using namespace std; using namespace butl; -- cgit v1.1