summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap.cc11
-rw-r--r--src/configure.cc41
-rw-r--r--src/ctor.h11
-rw-r--r--src/tools.cc63
-rw-r--r--src/tools.h15
5 files changed, 104 insertions, 37 deletions
diff --git a/src/bootstrap.cc b/src/bootstrap.cc
index f091849..0604527 100644
--- a/src/bootstrap.cc
+++ b/src/bootstrap.cc
@@ -22,10 +22,17 @@
std::filesystem::path configurationFile("configuration.cc");
std::filesystem::path configHeaderFile("config.h");
-const ctor::configuration default_configuration{};
const ctor::configuration& ctor::get_configuration()
{
- return default_configuration;
+ static ctor::configuration cfg;
+ static bool initialised{false};
+ if(!initialised)
+ {
+ cfg.host_toolchain = getToolChain(cfg.get(ctor::cfg::host_cxx, "/usr/bin/g++"));
+ initialised = true;
+ }
+
+ return cfg;
}
bool ctor::configuration::has(const std::string& key) const
diff --git a/src/configure.cc b/src/configure.cc
index f91f0d9..deeb6a6 100644
--- a/src/configure.cc
+++ b/src/configure.cc
@@ -15,6 +15,7 @@
#include "tasks.h"
#include "rebuild.h"
#include "externals.h"
+#include "tools.h"
std::filesystem::path configurationFile("configuration.cc");
std::filesystem::path configHeaderFile("config.h");
@@ -22,10 +23,16 @@ std::filesystem::path configHeaderFile("config.h");
std::map<std::string, std::string> external_includedir;
std::map<std::string, std::string> external_libdir;
-const ctor::configuration default_configuration{};
const ctor::configuration& __attribute__((weak)) ctor::get_configuration()
{
- return default_configuration;
+ static ctor::configuration cfg;
+ static bool initialised{false};
+ if(!initialised)
+ {
+ cfg.host_toolchain = getToolChain(cfg.get(ctor::cfg::host_cxx, "g++"));
+ initialised = true;
+ }
+ return cfg;
}
namespace ctor {
@@ -164,6 +171,28 @@ public:
}
};
+namespace {
+std::ostream& operator<<(std::ostream& stream, const ctor::toolchain& toolchain)
+{
+ switch(toolchain)
+ {
+ case ctor::toolchain::any:
+ stream << "ctor::toolchain::any";
+ break;
+ case ctor::toolchain::none:
+ stream << "ctor::toolchain::none";
+ break;
+ case ctor::toolchain::gcc:
+ stream << "ctor::toolchain::gcc";
+ break;
+ case ctor::toolchain::clang:
+ stream << "ctor::toolchain::clang";
+ break;
+ }
+ return stream;
+}
+}
+
// helper constant for the visitor
template<class> inline constexpr bool always_false_v = false;
@@ -395,6 +424,12 @@ int regenerateCache(ctor::settings& settings,
std::string build_ar = locate(build_arch, ar_prog);
std::string build_ld = locate(build_arch, ld_prog);
+ if(!host_cxx.empty())
+ {
+ // This is needed for bootstrapping (when running configure for the first time)
+ ctor::conf_values[ctor::cfg::host_cxx] = host_cxx;
+ }
+
// Store current values for execution in this execution context.
if(!ctor_includedir.empty())
{
@@ -419,6 +454,8 @@ int regenerateCache(ctor::settings& settings,
istr << "{\n";
istr << " static ctor::configuration cfg =\n";
istr << " {\n";
+ istr << " .host_toolchain = " << getToolChain(host_cxx) << ",\n";
+ istr << " .build_toolchain = " << getToolChain(build_cxx) << ",\n";
istr << " .args = {";
for(const auto& arg : args)
{
diff --git a/src/ctor.h b/src/ctor.h
index 1754635..8e0e28e 100644
--- a/src/ctor.h
+++ b/src/ctor.h
@@ -58,6 +58,14 @@ struct source
std::string output{};
};
+enum class toolchain
+{
+ any,
+ none,
+ gcc,
+ clang,
+};
+
struct flags
{
std::vector<std::string> cxxflags; // flags for c++ compiler
@@ -146,6 +154,9 @@ struct configuration
bool has(const std::string& key) const;
const std::string& get(const std::string& key, const std::string& default_value = {}) const;
+ ctor::toolchain host_toolchain{ctor::toolchain::none};
+ ctor::toolchain build_toolchain{ctor::toolchain::none};
+
std::vector<std::string> args; // vector of arguments used when last calling configure
std::map<std::string, std::string> env; // env used when last calling configure
diff --git a/src/tools.cc b/src/tools.cc
index 4aaa515..ddb1463 100644
--- a/src/tools.cc
+++ b/src/tools.cc
@@ -8,35 +8,44 @@
#include <cassert>
-ToolChain getToolChain(ctor::output_system system)
+ctor::toolchain getToolChain(const std::string& compiler)
{
- const auto& c = ctor::get_configuration();
- std::string compiler;
- switch(system)
- {
- case ctor::output_system::host:
- compiler = c.get(ctor::cfg::host_cxx, "g++");
- break;
- case ctor::output_system::build:
- compiler = c.get(ctor::cfg::build_cxx, "g++");
- break;
- }
-
std::filesystem::path cc(compiler);
auto cc_cmd = cc.stem().string();
// Note: "g++" is a substring of "clang++" so "clang++" must be tested first.
if(cc_cmd.find("clang++") != std::string::npos)
{
- return ToolChain::clang;
+ return ctor::toolchain::clang;
}
else if(cc_cmd.find("g++") != std::string::npos)
{
- return ToolChain::gcc;
+ return ctor::toolchain::gcc;
}
std::cerr << "Unsupported output system.\n";
- return ToolChain::gcc;
+ return ctor::toolchain::gcc;
+}
+
+ctor::toolchain getToolChain(ctor::output_system system)
+{
+ const auto& cfg = ctor::get_configuration();
+ if(system == ctor::output_system::host)
+ {
+ if(cfg.host_toolchain != ctor::toolchain::none)
+ {
+ return cfg.host_toolchain;
+ }
+ return getToolChain(cfg.get(ctor::cfg::host_cxx, "g++"));
+ }
+ else
+ {
+ if(cfg.build_toolchain != ctor::toolchain::none)
+ {
+ return cfg.build_toolchain;
+ }
+ return getToolChain(cfg.get(ctor::cfg::build_cxx, "g++"));
+ }
}
namespace
@@ -86,15 +95,18 @@ std::vector<std::string> getOptionGcc(opt option, const std::string& arg)
}
}
-std::vector<std::string> getOption(ToolChain tool_chain,
+std::vector<std::string> getOption(ctor::toolchain toolchain,
opt option,
const std::string& arg)
{
- switch(tool_chain)
+ switch(toolchain)
{
- case ToolChain::gcc:
- case ToolChain::clang:
+ case ctor::toolchain::gcc:
+ case ctor::toolchain::clang:
return getOptionGcc(option, arg);
+ case ctor::toolchain::any:
+ case ctor::toolchain::none:
+ break;
}
std::cerr << "Unsupported tool-chain.\n";
@@ -123,13 +135,16 @@ std::pair<opt, std::string> getOptionGcc(const std::string& flag)
}
std::pair<opt, std::string> getOption(const std::string& flag,
- ToolChain tool_chain)
+ ctor::toolchain toolchain)
{
- switch(tool_chain)
+ switch(toolchain)
{
- case ToolChain::gcc:
- case ToolChain::clang:
+ case ctor::toolchain::gcc:
+ case ctor::toolchain::clang:
return getOptionGcc(flag);
+ case ctor::toolchain::any:
+ case ctor::toolchain::none:
+ break;
}
std::cerr << "Unsupported tool-chain.\n";
diff --git a/src/tools.h b/src/tools.h
index 49069d5..bedb708 100644
--- a/src/tools.h
+++ b/src/tools.h
@@ -8,12 +8,6 @@
#include "ctor.h"
-enum class ToolChain
-{
- gcc,
- clang,
-};
-
enum class opt
{
// gcc/clang
@@ -36,12 +30,15 @@ enum class opt
custom, // entire option taken verbatim from <arg>
};
+//! Get tool-chain type from compiler path string
+ctor::toolchain getToolChain(const std::string& compiler);
+
//! Get tool-chain type from output system (via configuration)
-ToolChain getToolChain(ctor::output_system system);
+ctor::toolchain getToolChain(ctor::output_system system);
//! Get tool argument(s) for specific option type matching the supplied
//! tool-chain
-std::vector<std::string> getOption(ToolChain tool_chain,
+std::vector<std::string> getOption(ctor::toolchain toolchain,
opt option,
const std::string& arg = {});
@@ -49,4 +46,4 @@ std::vector<std::string> getOption(ToolChain tool_chain,
//! ie. { opt::InludePath, "foo/bar" } from "-Ifoo/bar"
//! Returns { opt::Custom, flag } if unknown.
std::pair<opt, std::string> getOption(const std::string& flag,
- ToolChain tool_chain = ToolChain::gcc);
+ ctor::toolchain toolchain = ctor::toolchain::gcc);