aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/file.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2/file.cxx')
-rw-r--r--libbuild2/file.cxx162
1 files changed, 157 insertions, 5 deletions
diff --git a/libbuild2/file.cxx b/libbuild2/file.cxx
index 225c506..7903918 100644
--- a/libbuild2/file.cxx
+++ b/libbuild2/file.cxx
@@ -6,7 +6,7 @@
#include <libbuild2/scope.hxx>
#include <libbuild2/target.hxx>
#include <libbuild2/context.hxx>
-#include <libbuild2/filesystem.hxx> // exists()
+#include <libbuild2/filesystem.hxx>
#include <libbuild2/prerequisite.hxx>
#include <libbuild2/diagnostics.hxx>
@@ -14,6 +14,8 @@
#include <libbuild2/lexer.hxx>
#include <libbuild2/parser.hxx>
+#include <libbuild2/config/utility.hxx> // save_variable()
+
using namespace std;
using namespace butl;
@@ -1369,8 +1371,7 @@ namespace build2
// Mark as part of config.
//
- if (config_save_variable != nullptr)
- config_save_variable (iroot, var, 0 /* flags */);
+ config::save_variable (iroot, var);
// Empty config.import.* value means don't look in subprojects or
// amalgamations and go straight to the rule-specific import (e.g.,
@@ -1405,8 +1406,7 @@ namespace build2
if (r.empty ())
fail (loc) << "empty path in " << var.name;
- if (config_save_variable != nullptr)
- config_save_variable (iroot, var, 0 /* flags */);
+ config::save_variable (iroot, var);
}
return r;
@@ -1786,4 +1786,156 @@ namespace build2
dr << endf;
}
+
+ void
+ create_project (const dir_path& d,
+ const optional<dir_path>& amal,
+ const strings& bmod,
+ const string& rpre,
+ const strings& rmod,
+ const string& rpos,
+ const optional<string>& 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;
+ }
+ }
+ }
}