From f89d2c16c1dad9b8d2f3b0e402a47e30521f5a69 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 30 Aug 2016 09:51:03 +0200 Subject: Add support for config.build file versioning --- build2/config/init.cxx | 43 +++++++++++++++++++++++++++++++++++++++---- build2/config/module | 2 ++ build2/config/operation.cxx | 10 +++++----- 3 files changed, 46 insertions(+), 9 deletions(-) (limited to 'build2/config') diff --git a/build2/config/init.cxx b/build2/config/init.cxx index 6c713df..368b9d0 100644 --- a/build2/config/init.cxx +++ b/build2/config/init.cxx @@ -23,9 +23,10 @@ namespace build2 namespace config { const string module::name ("config"); + const uint64_t module::version; void - boot (scope& rs, const location&, unique_ptr&) + boot (scope& rs, const location& loc, unique_ptr&) { tracer trace ("config::boot"); @@ -44,10 +45,44 @@ namespace build2 // possible that some module which needs the configuration will get // called first. // - path f (out_root / config_file); + const variable& c_v (var_pool.insert ("config.version")); - if (file_exists (f)) - source (f, rs, rs); + // Don't load it if we are disfiguring. This is a bit tricky since the + // build2 core may not yet know it is disfiguring. But we know. + // + if (*current_mname != disfigure.name && + (!current_mname->empty () || *current_oname != disfigure.name)) + { + path f (out_root / config_file); + + if (file_exists (f)) + { + // Check the config version. We assume that old versions cannot + // understand new configs and new versions are incompatible with old + // configs. + // + // We extract the value manually instead of loading and then + // checking in order to be able to fixup/migrate the file which we + // may want to do in the future. + // + { + // Assume missing version is 0. + // + auto p (extract_variable (f, c_v.name.c_str ())); + uint64_t v (p.second ? cast (p.first) : 0); + + if (v != module::version) + fail (loc) << "incompatible config file " << f << + info << "config file version " << v + << (p.second ? "" : " (missing)") << + info << "config module version " << module::version << + info << "consider reconfiguring " << project (rs) << '@' + << out_root; + } + + source (f, rs, rs); + } + } } bool diff --git a/build2/config/module b/build2/config/module index e6fb197..8f9a9b9 100644 --- a/build2/config/module +++ b/build2/config/module @@ -78,7 +78,9 @@ namespace build2 struct module: module_base { config::saved_modules saved_modules; + static const string name; // init.cxx + static constexpr const uint64_t version = 1; }; } } diff --git a/build2/config/operation.cxx b/build2/config/operation.cxx index 90c2bbb..e6ab14a 100644 --- a/build2/config/operation.cxx +++ b/build2/config/operation.cxx @@ -80,6 +80,8 @@ namespace build2 "free to edit." << endl << "#" << endl; + ofs << "config.version = " << module::version << endl; + if (auto l = root.vars["amalgamation"]) { const dir_path& d (cast (l)); @@ -371,13 +373,11 @@ namespace build2 id < rs->operations.size (); ++id) { - const operation_info* oi (rs->operations[id]); - if (oi == nullptr) + const operation_info* oif (rs->operations[id]); + if (oif == nullptr) continue; - current_inner_oif = oi; - current_outer_oif = nullptr; - current_mode = oi->mode; + set_current_oif (*oif); dependency_count = 0; match (action (configure_id, id), t); -- cgit v1.1