aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/config
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2020-03-13 08:48:43 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2020-03-13 08:58:15 +0200
commit1adbf7b710d52958f6c0168ccb492252c1f19d4a (patch)
tree04ce492fd006d3c5cf98222f923adcc9845194f4 /libbuild2/config
parent1dbaaa16d0ea2c6af53f16ebb14c943fdd11bac4 (diff)
Cleanup and make config/utility.?xx part of build system core
Diffstat (limited to 'libbuild2/config')
-rw-r--r--libbuild2/config/init.cxx3
-rw-r--r--libbuild2/config/module.cxx16
-rw-r--r--libbuild2/config/module.hxx26
-rw-r--r--libbuild2/config/operation.cxx4
-rw-r--r--libbuild2/config/utility.cxx180
-rw-r--r--libbuild2/config/utility.hxx106
-rw-r--r--libbuild2/config/utility.txx3
7 files changed, 111 insertions, 227 deletions
diff --git a/libbuild2/config/init.cxx b/libbuild2/config/init.cxx
index 8dd4d8b..ca34d52 100644
--- a/libbuild2/config/init.cxx
+++ b/libbuild2/config/init.cxx
@@ -300,7 +300,8 @@ namespace build2
{
// Initialize the config entry points in the build system core.
//
- config_save_variable = &save_variable;
+ config_save_variable = &module::save_variable;
+ config_save_module = &module::save_module;
config_preprocess_create = &preprocess_create;
return mod_functions;
diff --git a/libbuild2/config/module.cxx b/libbuild2/config/module.cxx
index 176eef0..96107cc 100644
--- a/libbuild2/config/module.cxx
+++ b/libbuild2/config/module.cxx
@@ -3,6 +3,8 @@
#include <libbuild2/config/module.hxx>
+#include <libbuild2/scope.hxx>
+
using namespace std;
namespace build2
@@ -45,12 +47,26 @@ namespace build2
return true;
}
+ void module::
+ save_variable (scope& rs, const variable& var, uint64_t flags)
+ {
+ if (module* m = rs.find_module<module> (module::name))
+ m->save_variable (var, flags);
+ }
+
bool module::
save_module (const char* name, int prio)
{
return saved_modules.insert (string ("config.") += name, prio).second;
}
+ void module::
+ save_module (scope& rs, const char* name, int prio)
+ {
+ if (module* m = rs.find_module<module> (module::name))
+ m->save_module (name, prio);
+ }
+
const string module::name ("config");
const uint64_t module::version (1);
}
diff --git a/libbuild2/config/module.hxx b/libbuild2/config/module.hxx
index 28c73a3..ade75cd 100644
--- a/libbuild2/config/module.hxx
+++ b/libbuild2/config/module.hxx
@@ -11,6 +11,7 @@
#include <libbuild2/types.hxx>
#include <libbuild2/utility.hxx>
+#include <libbuild2/scope.hxx>
#include <libbuild2/module.hxx>
#include <libbuild2/variable.hxx>
@@ -51,14 +52,6 @@ namespace build2
// Priority order with INT32_MIN being the highest. Modules with the
// same priority are saved in the order inserted.
//
- // Generally, the idea is that we want higher-level modules at the top
- // of the file since that's the configuration that we usualy want to
- // change. So we have the following priority bands/defaults:
- //
- // 101-200/150 - code generators (e.g., yacc, bison)
- // 201-300/250 - compilers (e.g., C, C++),
- // 301-400/350 - binutils (ar, ld)
- //
std::multimap<std::int32_t, const_iterator> order;
pair<iterator, bool>
@@ -82,9 +75,15 @@ namespace build2
bool
save_variable (const variable&, uint64_t flags = 0);
+ static void
+ save_variable (scope&, const variable&, uint64_t);
+
bool
save_module (const char* name, int prio = 0);
+ static void
+ save_module (scope&, const char*, int);
+
// Return true if the variable is already saved.
//
bool
@@ -102,6 +101,17 @@ namespace build2
static const string name;
static const uint64_t version;
};
+
+ // Implementation-specific utilities.
+ //
+
+ inline path
+ config_file (const scope& rs)
+ {
+ return (rs.out_path () /
+ rs.root_extra->build_dir /
+ "config." + rs.root_extra->build_ext);
+ }
}
}
diff --git a/libbuild2/config/operation.cxx b/libbuild2/config/operation.cxx
index 2138986..07110e0 100644
--- a/libbuild2/config/operation.cxx
+++ b/libbuild2/config/operation.cxx
@@ -13,7 +13,7 @@
#include <libbuild2/diagnostics.hxx>
#include <libbuild2/config/module.hxx>
-#include <libbuild2/config/utility.hxx>
+#include <libbuild2/config/utility.hxx> // save_*
using namespace std;
using namespace butl;
@@ -1224,7 +1224,7 @@ namespace build2
"", /* root_pre */
rmod,
"", /* root_post */
- true, /* config */
+ "config", /* config */
true, /* buildfile */
"the create meta-operation");
diff --git a/libbuild2/config/utility.cxx b/libbuild2/config/utility.cxx
index a39d3e0..b9fc513 100644
--- a/libbuild2/config/utility.cxx
+++ b/libbuild2/config/utility.cxx
@@ -3,17 +3,17 @@
#include <libbuild2/config/utility.hxx>
-#include <libbuild2/file.hxx>
-#include <libbuild2/context.hxx>
-#include <libbuild2/filesystem.hxx>
-#include <libbuild2/diagnostics.hxx>
-
-#include <libbuild2/config/module.hxx>
-
using namespace std;
namespace build2
{
+ void (*config_save_variable) (scope&, const variable&, uint64_t);
+ void (*config_save_module) (scope&, const char*, int);
+ const string& (*config_preprocess_create) (context&,
+ values&,
+ vector_view<opspec>&,
+ bool,
+ const location&);
namespace config
{
pair<lookup, bool>
@@ -126,171 +126,5 @@ namespace build2
else
return false;
}
-
- void
- save_variable (scope& rs, const variable& var, uint64_t flags)
- {
- if (module* m = rs.find_module<module> (module::name))
- m->save_variable (var, flags);
- }
-
- void
- save_module (scope& rs, const char* name, int prio)
- {
- if (module* m = rs.find_module<module> (module::name))
- m->save_module (name, prio);
- }
-
- void
- create_project (const dir_path& d,
- const build2::optional<dir_path>& amal,
- const strings& bmod,
- const string& rpre,
- const strings& rmod,
- const string& rpos,
- bool config,
- bool buildfile,
- const char* who,
- uint16_t verbosity)
- {
- string hdr ("# Generated by " + string (who) + ". Edit if you know"
- " what you are doing.\n"
- "#");
-
- // If the directory exists, verify it's empty. Otherwise, create it.
- //
- if (exists (d))
- {
- if (!empty (d))
- fail << "directory " << d << " exists and is not empty";
- }
- else
- mkdir_p (d, verbosity);
-
- // Create the build/ subdirectory.
- //
- // Note that for now we use the standard build file/directory scheme.
- //
- mkdir (d / std_build_dir, verbosity);
-
- // Write build/bootstrap.build.
- //
- {
- path f (d / std_bootstrap_file);
-
- if (verb >= verbosity)
- text << (verb >= 2 ? "cat >" : "save ") << f;
-
- try
- {
- ofdstream ofs (f);
-
- ofs << hdr << endl
- << "project =" << endl;
-
- if (amal)
- {
- ofs << "amalgamation =";
-
- if (!amal->empty ())
- {
- ofs << ' ';
- to_stream (ofs, *amal, true /* representation */);
- }
-
- ofs << endl;
- }
-
- ofs << endl;
-
- if (config)
- ofs << "using config" << endl;
-
- for (const string& m: bmod)
- {
- if (!config || m != "config")
- ofs << "using " << m << endl;
- }
-
- ofs.close ();
- }
- catch (const io_error& e)
- {
- fail << "unable to write to " << f << ": " << e;
- }
- }
-
- // Write build/root.build.
- //
- {
- path f (d / std_root_file);
-
- if (verb >= verbosity)
- text << (verb >= 2 ? "cat >" : "save ") << f;
-
- try
- {
- ofdstream ofs (f);
-
- ofs << hdr << endl;
-
- if (!rpre.empty ())
- ofs << rpre << endl
- << endl;
-
- for (const string& cm: rmod)
- {
- // If the module name start with '?', then use optional load.
- //
- bool opt (cm.front () == '?');
- string m (cm, opt ? 1 : 0);
-
- // Append .config unless the module name ends with '.', in which
- // case strip it.
- //
- if (m.back () == '.')
- m.pop_back ();
- else
- m += ".config";
-
- ofs << "using" << (opt ? "?" : "") << " " << m << endl;
- }
-
- if (!rpos.empty ())
- ofs << endl
- << rpre << endl;
-
- ofs.close ();
- }
- catch (const io_error& e)
- {
- fail << "unable to write to " << f << ": " << e;
- }
- }
-
- // Write root buildfile.
- //
- if (buildfile)
- {
- path f (d / std_buildfile_file);
-
- if (verb >= verbosity)
- text << (verb >= 2 ? "cat >" : "save ") << f;
-
- try
- {
- ofdstream ofs (f);
-
- ofs << hdr << endl
- << "./: {*/ -build/}" << endl;
-
- ofs.close ();
- }
- catch (const io_error& e)
- {
- fail << "unable to write to " << f << ": " << e;
- }
- }
- }
}
}
diff --git a/libbuild2/config/utility.hxx b/libbuild2/config/utility.hxx
index 3e01cd1..493d296 100644
--- a/libbuild2/config/utility.hxx
+++ b/libbuild2/config/utility.hxx
@@ -10,14 +10,73 @@
#include <libbuild2/scope.hxx>
#include <libbuild2/variable.hxx>
-#include <libbuild2/diagnostics.hxx>
#include <libbuild2/export.hxx>
namespace build2
{
+ // Note that the utility functions in this file are part of the build system
+ // core rather than the config module. They define the basic configuration
+ // semantics that should be applicable to both transient configurations as
+ // well as to other implementations of configuration persistence.
+ //
+ // The only persistence-specific aspects of this functionality are marking
+ // of the variables as to be persisted (saved, potentially with flags),
+ // establishing the module saving order (priority), and configuration
+ // creation (the create meta-operation implementation) These are accessed
+ // through the config module entry points (which are NULL for transient
+ // configurations). Note also that the exact interpretation of the save
+ // flags and module order depends on the config module implementation (which
+ // may ignore them as not applicable). An implementation may also define
+ // custom save flags (for example, accessible through the config.save
+ // attribute). Such flags should start from 0x100000000.
+ //
+ LIBBUILD2_SYMEXPORT extern void
+ (*config_save_variable) (scope&, const variable&, uint64_t);
+
+ LIBBUILD2_SYMEXPORT extern void
+ (*config_save_module) (scope&, const char*, int);
+
+ LIBBUILD2_SYMEXPORT extern const string&
+ (*config_preprocess_create) (context&,
+ values&,
+ vector_view<opspec>&,
+ bool,
+ const location&);
+
namespace config
{
+ // Mark the variable to be saved during configuration.
+ //
+ const uint64_t save_default_commented = 0x01; // Based on value::extra.
+ const uint64_t save_null_omitted = 0x02; // Treat NULL as undefined.
+
+ inline void
+ save_variable (scope& rs, const variable& var, uint64_t flags = 0)
+ {
+ if (config_save_variable != nullptr)
+ config_save_variable (rs, var, flags);
+ }
+
+ // Establish module save order/priority with INT32_MIN being the highest.
+ // Modules with the same priority are saved in the order inserted.
+ //
+ // Generally, for user-editable persisten configuration, we want higher-
+ // level modules at the top of the file since that's the configuration
+ // that the user usually wants to change. As a result, we define the
+ // following priority bands/defaults:
+ //
+ // 101-200/150 - code generators (e.g., yacc, bison)
+ // 201-300/250 - compilers (e.g., C, C++),
+ // 301-400/350 - binutils (ar, ld)
+ //
+ inline void
+ save_module (scope& rs, const char* module, int prio = 0)
+ {
+ if (config_save_module != nullptr)
+ config_save_module (rs, module, prio);
+ }
+
// Set, if necessary, a required config.* variable.
//
// If override is true and the variable doesn't come from this root scope
@@ -33,9 +92,12 @@ namespace build2
// (always defined) to pass along its location (could be used to detect
// inheritance, etc).
//
- // Note also that if save_flags has save_commented, then a default value
- // is never considered "new" since for such variables absence of a value
- // means the default value.
+ // Note also that if save_flags has save_default_commented, then a default
+ // value is never considered "new" since for such variables absence of a
+ // value means the default value.
+ //
+ // @@ Should save_null_omitted be interpreted to treat null as undefined?
+ // Sounds logical.
//
template <typename T>
pair<lookup, bool>
@@ -139,42 +201,6 @@ namespace build2
//
LIBBUILD2_SYMEXPORT bool
unconfigured (scope& rs, const string& var, bool value);
-
- // Enter the variable so that it is saved during configuration. See
- // config::module for details.
- //
- const uint64_t save_default_commented = 0x01; // Based on value::extra.
- const uint64_t save_null_omitted = 0x02; // Treat NULL as undefined.
-
- LIBBUILD2_SYMEXPORT void
- save_variable (scope& rs, const variable&, uint64_t flags = 0);
-
- // Establish module order/priority. See config::module for details.
- //
- LIBBUILD2_SYMEXPORT void
- save_module (scope& rs, const char* module, int prio = 0);
-
- // Create a project in the specified directory.
- //
- LIBBUILD2_SYMEXPORT void
- create_project (const dir_path& d,
- const build2::optional<dir_path>& amalgamation,
- const strings& boot_modules, // Bootstrap modules.
- const string& root_pre, // Extra root.build text.
- const strings& root_modules, // Root modules.
- const string& root_post, // Extra root.build text.
- bool config, // Load config module.
- bool buildfile, // Create root buildfile.
- const char* who, // Who is creating it.
- uint16_t verbosity = 1); // Diagnostic verbosity.
-
- inline path
- config_file (const scope& rs)
- {
- return (rs.out_path () /
- rs.root_extra->build_dir /
- "config." + rs.root_extra->build_ext);
- }
}
}
diff --git a/libbuild2/config/utility.txx b/libbuild2/config/utility.txx
index 670a701..f52df8d 100644
--- a/libbuild2/config/utility.txx
+++ b/libbuild2/config/utility.txx
@@ -1,9 +1,6 @@
// file : libbuild2/config/utility.txx -*- C++ -*-
// license : MIT; see accompanying LICENSE file
-#include <libbuild2/scope.hxx>
-#include <libbuild2/context.hxx> // current_mif
-
namespace build2
{
namespace config