summaryrefslogtreecommitdiff
path: root/src/tools.cc
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2022-07-10 17:24:16 +0200
committerBent Bisballe Nyeng <deva@aasimon.org>2022-07-15 10:11:05 +0200
commitae1871ca0ffcac3e8bd337f8d8bb4e7fd6c59295 (patch)
treed15df8a03fab6bdacebb6ba53c8ad30c290781fc /src/tools.cc
parent2a55edcc40372403fb2de8ed20ed5c44464d416e (diff)
Make tools abstraction around compiler options to better support tool agnostic arguments.
Diffstat (limited to 'src/tools.cc')
-rw-r--r--src/tools.cc136
1 files changed, 136 insertions, 0 deletions
diff --git a/src/tools.cc b/src/tools.cc
new file mode 100644
index 0000000..7e8ac78
--- /dev/null
+++ b/src/tools.cc
@@ -0,0 +1,136 @@
+// -*- c++ -*-
+// Distributed under the BSD 2-Clause License.
+// See accompanying file LICENSE for details.
+#include "tools.h"
+
+#include <filesystem>
+#include <iostream>
+
+#include <cassert>
+
+ToolChain getToolChain(OutputSystem system)
+{
+ std::string compiler;
+ switch(system)
+ {
+ case OutputSystem::Host:
+ compiler = getConfiguration(cfg::host_cxx, "g++");
+ break;
+ case OutputSystem::Build:
+ compiler = getConfiguration(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;
+ }
+ else if(cc_cmd.find("g++") != std::string::npos)
+ {
+ return ToolChain::gcc;
+ }
+
+ std::cerr << "Unsupported output system.\n";
+ return ToolChain::gcc;
+}
+
+namespace
+{
+std::vector<std::string> getOptionGcc(opt option, const std::string& arg)
+{
+ switch(option)
+ {
+ case opt::output:
+ return {"-o", arg};
+ case opt::debug:
+ return {"-g"};
+ case opt::strip:
+ return {"-s"};
+ case opt::warn_all:
+ return {"-Wall"};
+ case opt::warnings_as_errors:
+ return {"-Werror"};
+ case opt::generate_dep_tree:
+ return {"-MMD"};
+ case opt::no_link:
+ return {"-c"};
+ case opt::include_path:
+ return {"-I" + arg};
+ case opt::library_path:
+ return {"-L" + arg};
+ case opt::link:
+ return {"-l" + arg};
+ case opt::cpp_std:
+ return {"-std=" + arg};
+ case opt::build_shared:
+ return {"-shared"};
+ case opt::threads:
+ return {"-pthread"};
+ case opt::optimization:
+ return {"-O" + arg};
+ case opt::position_independent_code:
+ return {"-fPIC"};
+ case opt::position_independent_executable:
+ return {"-fPIE"};
+ case opt::custom:
+ return {arg};
+ }
+
+ std::cerr << "Unsupported compiler option.\n";
+ return {};
+}
+}
+
+std::vector<std::string> getOption(ToolChain tool_chain,
+ opt option,
+ const std::string& arg)
+{
+ switch(tool_chain)
+ {
+ case ToolChain::gcc:
+ case ToolChain::clang:
+ return getOptionGcc(option, arg);
+ }
+
+ std::cerr << "Unsupported tool-chain.\n";
+ return {};
+}
+
+namespace {
+std::pair<opt, std::string> getOptionGcc(const std::string& flag)
+{
+ if(flag.substr(0, 2) == "-I")
+ {
+ std::string path = flag.substr(2);
+ path.erase(0, path.find_first_not_of(' '));
+ return { opt::include_path, path };
+ }
+
+ if(flag.substr(0, 2) == "-L")
+ {
+ std::string path = flag.substr(2);
+ path.erase(0, path.find_first_not_of(' '));
+ return { opt::library_path, path };
+ }
+
+ return { opt::custom, flag };
+}
+}
+
+std::pair<opt, std::string> getOption(const std::string& flag,
+ ToolChain tool_chain)
+{
+ switch(tool_chain)
+ {
+ case ToolChain::gcc:
+ case ToolChain::clang:
+ return getOptionGcc(flag);
+ }
+
+ std::cerr << "Unsupported tool-chain.\n";
+ return { opt::custom, flag };
+}