diff options
Diffstat (limited to 'libbuild2/file.cxx')
-rw-r--r-- | libbuild2/file.cxx | 162 |
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; + } + } + } } |