From 3c29644d3bc8c4daad68ab92003a9e754f39de2a Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Thu, 18 Nov 2021 22:02:57 +0100 Subject: Refactor configure and the way it generates its cache. --- src/bootstrap.cc | 4 +- src/configure.cc | 190 ++++++++++++++++++++++++++++++++++++++++++------------- src/configure.h | 4 +- src/libctor.cc | 14 ++-- src/libctor.h | 10 ++- 5 files changed, 171 insertions(+), 51 deletions(-) diff --git a/src/bootstrap.cc b/src/bootstrap.cc index 9b8e029..53018cc 100644 --- a/src/bootstrap.cc +++ b/src/bootstrap.cc @@ -22,8 +22,8 @@ std::filesystem::path configurationFile("configuration.cc"); std::filesystem::path configHeaderFile("config.h"); -const std::map default_configuration{}; -const std::map& configuration() +const Configuration default_configuration{}; +const Configuration& configuration() { return default_configuration; } diff --git a/src/configure.cc b/src/configure.cc index 9ebed8a..13409ef 100644 --- a/src/configure.cc +++ b/src/configure.cc @@ -19,8 +19,8 @@ std::filesystem::path configurationFile("configuration.cc"); std::filesystem::path configHeaderFile("config.h"); -const std::map default_configuration{}; -const std::map& __attribute__((weak)) configuration() +const Configuration default_configuration{}; +const Configuration& __attribute__((weak)) configuration() { return default_configuration; } @@ -44,7 +44,7 @@ bool hasConfiguration(const std::string& key) } const auto& c = configuration(); - return c.find(key) != c.end(); + return c.tools.find(key) != c.tools.end(); } const std::string& getConfiguration(const std::string& key, @@ -63,7 +63,7 @@ const std::string& getConfiguration(const std::string& key, const auto& c = configuration(); if(hasConfiguration(key)) { - return c.at(key); + return c.tools.at(key); } return defaultValue; @@ -120,19 +120,36 @@ std::string locate(const std::string& arch, const std::string& app) return {}; } -int configure(const Settings& global_settings, int argc, char* argv[]) +class Args + : public std::vector { - Settings settings{global_settings}; - std::string cmd_str; - for(int i = 0; i < argc; ++i) +public: + Args(const std::vector& args) { - if(i > 0) + resize(args.size() + 1); + (*this)[0] = strdup("./ctor"); + for(std::size_t i = 0; i < size() - 1; ++i) { - cmd_str += " "; + (*this)[i + 1] = strdup(args[i].data()); } - cmd_str += argv[i]; } + ~Args() + { + for(std::size_t i = 0; i < size(); ++i) + { + free((*this)[i]); + } + } +}; + +int regenerateCache(const Settings& default_settings, + const std::vector& args, + const std::map& env) +{ + Settings settings{default_settings}; + Args vargs(args); + dg::Options opt; int key{128}; @@ -241,7 +258,7 @@ int configure(const Settings& global_settings, int argc, char* argv[]) return 0; }); - opt.process(argc, argv); + opt.process(vargs.size(), vargs.data()); if(host_arch.empty()) { @@ -274,32 +291,29 @@ int configure(const Settings& global_settings, int argc, char* argv[]) } } */ - auto cc_env = getenv("CC"); - if(cc_env) + + auto cc_env = env.find("CC"); + if(cc_env != env.end()) { - cmd_str = std::string("CC=") + cc_env + " " + cmd_str; - cc_prog = cc_env; + cc_prog = cc_env->second; } - auto cxx_env = getenv("CXX"); - if(cxx_env) + auto cxx_env = env.find("CXX"); + if(cxx_env != env.end()) { - cmd_str = std::string("CXX=") + cxx_env + " " + cmd_str; - cxx_prog = cxx_env; + cxx_prog = cxx_env->second; } - auto ar_env = getenv("AR"); - if(ar_env) + auto ar_env = env.find("AR"); + if(ar_env != env.end()) { - cmd_str = std::string("AR=") + ar_env + " " + cmd_str; - ar_prog = ar_env; + ar_prog = ar_env->second; } - auto ld_env = getenv("LD"); - if(ld_env) + auto ld_env = env.find("LD"); + if(ld_env != env.end()) { - cmd_str = std::string("LD=") + ld_env + " " + cmd_str; - ld_prog = ld_env; + ld_prog = ld_env->second; } std::string host_cc = locate(host_arch, cc_prog); @@ -315,32 +329,47 @@ int configure(const Settings& global_settings, int argc, char* argv[]) { std::ofstream istr(configurationFile); istr << "#include \n\n"; - istr << "const std::map& configuration()\n"; + istr << "const Configuration& configuration()\n"; istr << "{\n"; - istr << " static std::map c =\n"; + istr << " static Configuration cfg =\n"; istr << " {\n"; - istr << " { \"cmd\", \"" << cmd_str << "\" },\n"; - istr << " { \"" << cfg::builddir << "\", \"" << settings.builddir << "\" },\n"; - istr << " { \"" << cfg::host_cc << "\", \"" << host_cc << "\" },\n"; - istr << " { \"" << cfg::host_cxx << "\", \"" << host_cxx << "\" },\n"; - istr << " { \"" << cfg::host_ar << "\", \"" << host_ar << "\" },\n"; - istr << " { \"" << cfg::host_ld << "\", \"" << host_ld << "\" },\n"; - istr << " { \"" << cfg::build_cc << "\", \"" << build_cc << "\" },\n"; - istr << " { \"" << cfg::build_cxx << "\", \"" << build_cxx << "\" },\n"; - istr << " { \"" << cfg::build_ar << "\", \"" << build_ar << "\" },\n"; - istr << " { \"" << cfg::build_ld << "\", \"" << build_ld << "\" },\n"; + istr << " .args = {"; + for(const auto& arg : args) + { + istr << "\"" << arg << "\","; + } + istr << "},\n"; + istr << " .env = {"; + for(const auto& e : env) + { + istr << "{\"" << e.first << "\", \"" << e.second << "\"}, "; + } + istr << "},\n"; + + istr << " .tools = {\n"; + istr << " { \"" << cfg::builddir << "\", \"" << settings.builddir << "\" },\n"; + istr << " { \"" << cfg::host_cc << "\", \"" << host_cc << "\" },\n"; + istr << " { \"" << cfg::host_cxx << "\", \"" << host_cxx << "\" },\n"; + istr << " { \"" << cfg::host_ar << "\", \"" << host_ar << "\" },\n"; + istr << " { \"" << cfg::host_ld << "\", \"" << host_ld << "\" },\n"; + istr << " { \"" << cfg::build_cc << "\", \"" << build_cc << "\" },\n"; + istr << " { \"" << cfg::build_cxx << "\", \"" << build_cxx << "\" },\n"; + istr << " { \"" << cfg::build_ar << "\", \"" << build_ar << "\" },\n"; + istr << " { \"" << cfg::build_ld << "\", \"" << build_ld << "\" },\n"; if(!ctor_includedir.empty()) { - istr << " { \"" << cfg::ctor_includedir << "\", \"" << ctor_includedir << "\" },\n"; + istr << " { \"" << cfg::ctor_includedir << "\", \"" << ctor_includedir << "\" },\n"; ctor::includedir = ctor_includedir; } if(!ctor_libdir.empty()) { - istr << " { \"" << cfg::ctor_libdir << "\", \"" << ctor_libdir << "\" },\n"; + istr << " { \"" << cfg::ctor_libdir << "\", \"" << ctor_libdir << "\" },\n"; ctor::libdir = ctor_libdir; } + + istr << " },\n"; istr << " };\n"; - istr << " return c;\n"; + istr << " return cfg;\n"; istr << "}\n"; } @@ -351,7 +380,82 @@ int configure(const Settings& global_settings, int argc, char* argv[]) istr << "//#define HAS_BAR 1\n"; } + return 0; +} + +int configure(const Settings& global_settings, int argc, char* argv[]) +{ + Settings settings{global_settings}; + + std::vector args; + for(int i = 2; i < argc; ++i) // skip command and the first 'configure' arg + { + args.push_back(argv[i]); + } + + std::map env; + auto cc_env = getenv("CC"); + if(cc_env) + { + env["CC"] = cc_env; + } + + auto cxx_env = getenv("CXX"); + if(cxx_env) + { + env["CXX"] = cxx_env; + } + + auto ar_env = getenv("AR"); + if(ar_env) + { + env["AR"] = ar_env; + } + + auto ld_env = getenv("LD"); + if(ld_env) + { + env["LD"] = ld_env; + } + + auto ret = regenerateCache(settings, args, env); + if(ret != 0) + { + return ret; + } + recompileCheck(settings, 1, argv, false); return 0; } + +int reconfigure(const Settings& settings, int argc, char* argv[]) +{ + const auto& cfg = configuration(); + + std::cout << "Re-running configure:\n"; + for(const auto& e : cfg.env) + { + std::cout << e.first << "=\"" << e.second << "\" "; + } + std::cout << argv[0] << " configure "; + for(const auto& arg : cfg.args) + { + std::cout << arg << " "; + } + std::cout << "\n"; + + auto ret = regenerateCache(settings, cfg.args, cfg.env); + if(ret != 0) + { + return ret; + } + + std::vector args; + for(int i = 2; i < argc; ++i) // skip command and the first 'reconfigure' arg + { + args.push_back(argv[i]); + } + + return execute(argv[0], args); +} diff --git a/src/configure.h b/src/configure.h index a350820..d9160a5 100644 --- a/src/configure.h +++ b/src/configure.h @@ -13,7 +13,8 @@ extern std::filesystem::path configurationFile;; extern std::filesystem::path configHeaderFile; int configure(const Settings& settings, int argc, char* argv[]); - +int reconfigure(const Settings& settings, int argc, char* argv[]); +/* bool hasConfiguration(const std::string& key); const std::string& getConfiguration(const std::string& key, const std::string& defaultValue); @@ -21,3 +22,4 @@ const std::string& getConfiguration(const std::string& key, const std::map& configuration(); extern const std::map default_configuration; +*/ diff --git a/src/libctor.cc b/src/libctor.cc index 1fe1298..fcd3a95 100644 --- a/src/libctor.cc +++ b/src/libctor.cc @@ -39,6 +39,11 @@ int main(int argc, char* argv[]) return configure(settings, argc, argv); } + if(argc > 1 && std::string(argv[1]) == "reconfigure") + { + return reconfigure(settings, argc, argv); + } + bool write_compilation_database{false}; std::string compilation_database; bool print_configure_cmd{false}; @@ -154,9 +159,10 @@ int main(int argc, char* argv[]) std::cout << "Usage: " << argv[0] << " [options] [target] ...\n"; std::cout << R"_( where target can be either: - configure - run configuration step (cannot be used with other targets). - clean - clean all generated files. - all - build all targets (default) + configure - run configuration step (cannot be used with other targets). + reconfigure - rerun configuration step with the same arguments as last (cannot be used with other targets). + clean - clean all generated files. + all - build all targets (default) or the name of a target which will be built along with its dependencies. Use '-l' to see a list of possible target names. @@ -264,7 +270,7 @@ Options: { no_default_build = true; const auto& c = configuration(); - for(const auto& config : c) + for(const auto& config : c.tools) { std::cout << config.first << ": " << config.second << "\n"; } diff --git a/src/libctor.h b/src/libctor.h index 6d3becf..bcbe3a5 100644 --- a/src/libctor.h +++ b/src/libctor.h @@ -105,7 +105,15 @@ constexpr auto ctor_includedir = "ctor-includedir"; constexpr auto ctor_libdir = "ctor-libdir"; } -const std::map& configuration(); +struct Configuration +{ + std::vector args; // vector of arguments used when last calling configure + std::map env; // env used when last calling configure + + std::map tools; // tools +}; + +const Configuration& configuration(); bool hasConfiguration(const std::string& key); const std::string& getConfiguration(const std::string& key, const std::string& defaultValue = {}); -- cgit v1.2.3