summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/configure.cc44
-rw-r--r--src/ctor.h86
-rw-r--r--src/externals_manual.cc8
-rw-r--r--src/rebuild.cc20
-rw-r--r--src/task_ar.cc13
-rw-r--r--src/task_cc.cc116
-rw-r--r--src/task_ld.cc24
-rw-r--r--src/task_so.cc25
-rw-r--r--src/tools.cc560
-rw-r--r--src/tools.h83
-rw-r--r--src/util.h5
11 files changed, 867 insertions, 117 deletions
diff --git a/src/configure.cc b/src/configure.cc
index deeb6a6..34812fa 100644
--- a/src/configure.cc
+++ b/src/configure.cc
@@ -191,6 +191,42 @@ std::ostream& operator<<(std::ostream& stream, const ctor::toolchain& toolchain)
}
return stream;
}
+
+std::ostream& operator<<(std::ostream& ostr, const ctor::c_flag& flag)
+{
+ for(const auto& s : to_strings(ctor::toolchain::any, flag))
+ {
+ ostr << s;
+ }
+ return ostr;
+}
+
+std::ostream& operator<<(std::ostream& ostr, const ctor::cxx_flag& flag)
+{
+ for(const auto& s : to_strings(ctor::toolchain::any, flag))
+ {
+ ostr << s;
+ }
+ return ostr;
+}
+
+std::ostream& operator<<(std::ostream& ostr, const ctor::ld_flag& flag)
+{
+ for(const auto& s : to_strings(ctor::toolchain::any, flag))
+ {
+ ostr << s;
+ }
+ return ostr;
+}
+
+std::ostream& operator<<(std::ostream& ostr, const ctor::asm_flag& flag)
+{
+ for(const auto& s : to_strings(ctor::toolchain::any, flag))
+ {
+ ostr << s;
+ }
+ return ostr;
+}
}
// helper constant for the visitor
@@ -521,7 +557,7 @@ int regenerateCache(ctor::settings& settings,
istr << " .cxxflags = {";
for(const auto& flag : resolved_flags.cxxflags)
{
- istr << "\"" << flag << "\",";
+ istr << flag << ",";
}
istr << "},\n";
}
@@ -531,7 +567,7 @@ int regenerateCache(ctor::settings& settings,
istr << " .cflags = {";
for(const auto& flag : resolved_flags.cflags)
{
- istr << "\"" << flag << "\",";
+ istr << flag << ",";
}
istr << "},\n";
}
@@ -541,7 +577,7 @@ int regenerateCache(ctor::settings& settings,
istr << " .ldflags = {";
for(const auto& flag : resolved_flags.ldflags)
{
- istr << "\"" << flag << "\",";
+ istr << flag << ",";
}
istr << "},\n";
}
@@ -551,7 +587,7 @@ int regenerateCache(ctor::settings& settings,
istr << " .asmflags = {";
for(const auto& flag : resolved_flags.asmflags)
{
- istr << "\"" << flag << "\",";
+ istr << flag << ",";
}
istr << "},\n";
}
diff --git a/src/ctor.h b/src/ctor.h
index 388ec1b..36aa46a 100644
--- a/src/ctor.h
+++ b/src/ctor.h
@@ -66,34 +66,106 @@ enum class toolchain
clang,
};
-enum class opt
+enum class cxx_opt
{
// gcc/clang
output, // -o
debug, // -g
- strip, // -s
warn_all, // -Wall
warnings_as_errors, // -Werror
generate_dep_tree, // -MMD
no_link, // -c
include_path, // -I<arg>
+ cpp_std, // -std=<arg>
+ optimization, // -O<arg>
+ position_independent_code, // -fPIC
+ position_independent_executable, // -fPIE
+ custom, // entire option taken verbatim from <arg>
+};
+
+enum class c_opt
+{
+ // gcc/clang
+ output, // -o
+ debug, // -g
+ warn_all, // -Wall
+ warnings_as_errors, // -Werror
+ generate_dep_tree, // -MMD
+ no_link, // -c
+ include_path, // -I<arg>
+ c_std, // -std=<arg>
+ optimization, // -O<arg>
+ position_independent_code, // -fPIC
+ position_independent_executable, // -fPIE
+ custom, // entire option taken verbatim from <arg>
+};
+
+enum class ld_opt
+{
+ // gcc/clang
+ output, // -o
+ strip, // -s
+ warn_all, // -Wall
+ warnings_as_errors, // -Werror
library_path, // -L<arg>
link, // -l<arg>
cpp_std, // -std=<arg>
build_shared, // -shared
threads, // -pthread
- optimization, // -O<arg>
position_independent_code, // -fPIC
position_independent_executable, // -fPIE
custom, // entire option taken verbatim from <arg>
};
+enum class ar_opt
+{
+ // gcc/clang
+ custom, // entire option taken verbatim from <arg>
+};
+
+enum class asm_opt
+{
+ // gcc/clang
+ custom, // entire option taken verbatim from <arg>
+};
+
+template<typename T>
+class flag
+{
+public:
+ flag(const std::string& str);
+ flag(const char* str);
+ flag(T opt) : opt(opt) {}
+ flag(T opt, const std::string& arg) : opt(opt), arg(arg) {}
+ flag(T opt, const char* arg) : opt(opt), arg(arg) {}
+ flag(ctor::toolchain toolchain, T opt) : toolchain(toolchain), opt(opt) {}
+ flag(ctor::toolchain toolchain, T opt, const char* arg) : toolchain(toolchain), opt(opt), arg(arg) {}
+ flag(ctor::toolchain toolchain, T opt, const std::string& arg) : toolchain(toolchain), opt(opt), arg(arg) {}
+
+ ctor::toolchain toolchain{ctor::toolchain::any};
+ T opt;
+ std::string arg;
+};
+
+using c_flag = ctor::flag<ctor::c_opt>;
+using cxx_flag = ctor::flag<ctor::cxx_opt>;
+using ld_flag = ctor::flag<ctor::ld_opt>;
+using ar_flag = ctor::flag<ctor::ar_opt>;
+using asm_flag = ctor::flag<ctor::asm_opt>;
+
+using c_flags = std::vector<ctor::c_flag>;
+using cxx_flags = std::vector<ctor::cxx_flag>;
+using ld_flags= std::vector<ctor::ld_flag>;
+using ar_flags = std::vector<ctor::ar_flag>;
+using asm_flags = std::vector<ctor::asm_flag>;
+
struct flags
{
- std::vector<std::string> cxxflags; // flags for c++ compiler
- std::vector<std::string> cflags; // flags for c compiler
- std::vector<std::string> ldflags; // flags for linker
- std::vector<std::string> asmflags; // flags for asm translator
+ ctor::c_flags cflags; // flags for c compiler
+ ctor::cxx_flags cxxflags; // flags for c++ compiler
+ ctor::ld_flags ldflags; // flags for linker
+ ctor::ar_flags arflags; // flags for archiver
+ ctor::asm_flags asmflags; // flags for asm translator
};
struct settings
diff --git a/src/externals_manual.cc b/src/externals_manual.cc
index bc8e9d0..3b96263 100644
--- a/src/externals_manual.cc
+++ b/src/externals_manual.cc
@@ -16,21 +16,19 @@ extern std::map<std::string, std::string> external_libdir;
int resolv(const ctor::settings& settings, const ctor::external_configuration& config,
const ctor::external_manual& ext, ctor::flags& flags)
{
- auto toolchain = getToolChain(config.system);
-
flags = ext.flags;
auto inc = external_includedir.find(config.name);
if(inc != external_includedir.end())
{
- append(flags.cflags, getOption(toolchain, ctor::opt::include_path, inc->second));
- append(flags.cxxflags, getOption(toolchain, ctor::opt::include_path, inc->second));
+ flags.cflags.push_back({ctor::c_opt::include_path, inc->second});
+ flags.cxxflags.push_back({ctor::cxx_opt::include_path, inc->second});
}
auto lib = external_libdir.find(config.name);
if(lib != external_libdir.end())
{
- append(flags.ldflags, getOption(toolchain, ctor::opt::library_path, lib->second));
+ flags.ldflags.push_back({ctor::ld_opt::library_path, lib->second});
}
return 0;
diff --git a/src/rebuild.cc b/src/rebuild.cc
index dec7119..c97452d 100644
--- a/src/rebuild.cc
+++ b/src/rebuild.cc
@@ -162,27 +162,21 @@ bool recompileCheck(const ctor::settings& global_settings, int argc, char* argv[
config.name = "ctor";
config.system = ctor::output_system::build;
- auto toolchain = getToolChain(config.system);
+ config.flags.cxxflags.push_back({ctor::cxx_opt::optimization, "3"});
+ config.flags.cxxflags.push_back({ctor::cxx_opt::cpp_std, "c++20"});
- append(config.flags.cxxflags,
- getOption(toolchain, ctor::opt::optimization, "3"));
- append(config.flags.cxxflags,
- getOption(toolchain, ctor::opt::cpp_std, "c++20"));
const auto& c = ctor::get_configuration();
if(c.has(ctor::cfg::ctor_includedir))
{
- append(config.flags.cxxflags,
- getOption(toolchain, ctor::opt::include_path,
- c.get(ctor::cfg::ctor_includedir)));
+ config.flags.cxxflags.push_back({ctor::cxx_opt::include_path,
+ c.get(ctor::cfg::ctor_includedir)});
}
if(c.has(ctor::cfg::ctor_libdir))
{
- append(config.flags.ldflags,
- getOption(toolchain, ctor::opt::library_path,
- c.get(ctor::cfg::ctor_libdir)));
+ config.flags.ldflags.push_back({ctor::ld_opt::library_path, c.get(ctor::cfg::ctor_libdir)});
}
- append(config.flags.ldflags, getOption(toolchain, ctor::opt::link, "ctor"));
- append(config.flags.ldflags, getOption(toolchain, ctor::opt::threads));
+ config.flags.ldflags.push_back({ctor::ld_opt::link, "ctor"});
+ config.flags.ldflags.push_back({ctor::ld_opt::threads});
ctor::settings settings{global_settings};
settings.verbose = -1; // Make check completely silent.
diff --git a/src/task_ar.cc b/src/task_ar.cc
index edd60ae..81ced0f 100644
--- a/src/task_ar.cc
+++ b/src/task_ar.cc
@@ -9,6 +9,7 @@
#include "ctor.h"
#include "execute.h"
#include "util.h"
+#include "tools.h"
TaskAR::TaskAR(const ctor::build_configuration& config,
const ctor::settings& settings,
@@ -160,14 +161,20 @@ bool TaskAR::derived() const
std::string TaskAR::flagsString() const
{
+ auto toolchain = getToolChain(config.system);
std::string flagsStr;
+ bool first{true};
for(const auto& flag : config.flags.ldflags)
{
- if(flag != config.flags.ldflags[0])
+ for(const auto& str : to_strings(toolchain, flag))
{
- flagsStr += " ";
+ if(first)
+ {
+ flagsStr += " ";
+ first = false;
+ }
+ flagsStr += str;
}
- flagsStr += flag;
}
flagsStr += "\n";
diff --git a/src/task_cc.cc b/src/task_cc.cc
index c15bd6a..56915f5 100644
--- a/src/task_cc.cc
+++ b/src/task_cc.cc
@@ -256,12 +256,23 @@ std::string TaskCC::source() const
std::vector<std::string> TaskCC::flags() const
{
+ std::vector<std::string> flags;
+ auto toolchain = getToolChain(config.system);
+
switch(sourceLanguage())
{
case ctor::language::c:
- return config.flags.cflags;
+ for(const auto& flag : config.flags.cflags)
+ {
+ append(flags, to_strings(toolchain, flag));
+ }
+ return flags;
case ctor::language::cpp:
- return config.flags.cxxflags;
+ for(const auto& flag : config.flags.cxxflags)
+ {
+ append(flags, to_strings(toolchain, flag));
+ }
+ return flags;
default:
std::cerr << "Unknown CC target type\n";
exit(1);
@@ -285,39 +296,96 @@ std::vector<std::string> TaskCC::getCompilerArgs() const
auto compiler_flags = flags();
std::vector<std::string> args;
- append(args, getOption(toolchain, ctor::opt::generate_dep_tree));
- if(std::filesystem::path(config.target).extension() == ".so")
+ switch(sourceLanguage())
{
- // Add -fPIC arg to all contained object files
- append(args, getOption(toolchain, ctor::opt::position_independent_code));
- }
+ case ctor::language::c:
+ {
+ append(args, c_option(toolchain, ctor::c_opt::generate_dep_tree));
- append(args, getOption(toolchain, ctor::opt::no_link));
- args.push_back(sourceFile.string());
- append(args, getOption(toolchain, ctor::opt::output, targetFile().string()));
+ if(std::filesystem::path(config.target).extension() == ".so")
+ {
+ // Add -fPIC arg to all contained object files
+ append(args, c_option(toolchain,
+ ctor::c_opt::position_independent_code));
+ }
- for(const auto& flag : compiler_flags)
- {
- auto option = getOption(flag);
- switch(option.first)
+ append(args, c_option(toolchain, ctor::c_opt::no_link));
+ args.push_back(sourceFile.string());
+ append(args, c_option(toolchain,
+ ctor::c_opt::output, targetFile().string()));
+
+ // Relative include paths has to be altered to be relative to sourceDir
+ for(const auto& flag : compiler_flags)
+ {
+ auto option = c_option(flag, toolchain);
+ switch(option.opt)
+ {
+ case ctor::c_opt::include_path:
+ {
+ std::filesystem::path path(option.arg);
+ if(path.is_relative())
+ {
+ path = (sourceDir / path).lexically_normal();
+ append(args, c_option(toolchain,
+ ctor::c_opt::include_path, path.string()));
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ args.push_back(flag);
+ }
+ }
+ break;
+
+ case ctor::language::cpp:
{
- // Relative include paths has to be altered to be relative to sourceDir
- case ctor::opt::include_path:
+ append(args, cxx_option(toolchain, ctor::cxx_opt::generate_dep_tree));
+
+ if(std::filesystem::path(config.target).extension() == ".so")
{
- std::filesystem::path path(option.second);
- if(path.is_relative())
+ // Add -fPIC arg to all contained object files
+ append(args, cxx_option(toolchain,
+ ctor::cxx_opt::position_independent_code));
+ }
+
+ append(args, cxx_option(toolchain, ctor::cxx_opt::no_link));
+ args.push_back(sourceFile.string());
+ append(args, cxx_option(toolchain,
+ ctor::cxx_opt::output, targetFile().string()));
+
+ // Relative include paths has to be altered to be relative to sourceDir
+ for(const auto& flag : compiler_flags)
+ {
+ auto option = cxx_option(flag, toolchain);
+ switch(option.opt)
{
- path = (sourceDir / path).lexically_normal();
- append(args, getOption(toolchain, ctor::opt::include_path, path.string()));
+ case ctor::cxx_opt::include_path:
+ {
+ std::filesystem::path path(option.arg);
+ if(path.is_relative())
+ {
+ path = (sourceDir / path).lexically_normal();
+ append(args, cxx_option(toolchain,
+ ctor::cxx_opt::include_path, path.string()));
+ }
+ }
+ break;
+ default:
+ break;
}
+
+ args.push_back(flag);
}
- continue;
- default:
- break;
+
}
+ break;
- args.push_back(flag);
+ default:
+ break;
}
return args;
diff --git a/src/task_ld.cc b/src/task_ld.cc
index 4915de9..3d917e4 100644
--- a/src/task_ld.cc
+++ b/src/task_ld.cc
@@ -90,10 +90,10 @@ int TaskLD::runInner()
auto depFile = dep->targetFile();
if(depFile.extension() == ".so")
{
- append(args, getOption(toolchain, ctor::opt::library_path,
+ append(args, ld_option(toolchain, ctor::ld_opt::library_path,
targetFile().parent_path().string()));
auto lib = depFile.stem().string().substr(3); // strip 'lib' prefix
- append(args, getOption(toolchain, ctor::opt::link, lib));
+ append(args, ld_option(toolchain, ctor::ld_opt::link, lib));
}
else if(depFile.extension() == ".a" || depFile.extension() == ".o")
{
@@ -101,8 +101,12 @@ int TaskLD::runInner()
}
}
- append(args, config.flags.ldflags);
- append(args, getOption(toolchain, ctor::opt::output, targetFile().string()));
+ for(const auto& flag : config.flags.ldflags)
+ {
+ append(args, to_strings(toolchain, flag));
+ }
+
+ append(args, ld_option(toolchain, ctor::ld_opt::output, targetFile().string()));
{ // Write flags to file.
std::ofstream flagsStream(flagsFile);
@@ -168,14 +172,20 @@ bool TaskLD::derived() const
std::string TaskLD::flagsString() const
{
+ auto toolchain = getToolChain(config.system);
std::string flagsStr;
+ bool first{true};
for(const auto& flag : config.flags.ldflags)
{
- if(flag != config.flags.ldflags[0])
+ for(const auto& str : to_strings(toolchain, flag))
{
- flagsStr += " ";
+ if(first)
+ {
+ flagsStr += " ";
+ first = false;
+ }
+ flagsStr += str;
}
- flagsStr += flag;
}
flagsStr += "\n";
diff --git a/src/task_so.cc b/src/task_so.cc
index 93a5ddb..9061591 100644
--- a/src/task_so.cc
+++ b/src/task_so.cc
@@ -83,17 +83,20 @@ int TaskSO::runInner()
std::vector<std::string> args;
- append(args, getOption(toolchain, ctor::opt::position_independent_code));
- append(args, getOption(toolchain, ctor::opt::build_shared));
+ append(args, ld_option(toolchain, ctor::ld_opt::position_independent_code));
+ append(args, ld_option(toolchain, ctor::ld_opt::build_shared));
- append(args, getOption(toolchain, ctor::opt::output, targetFile().string()));
+ append(args, ld_option(toolchain, ctor::ld_opt::output, targetFile().string()));
for(const auto& task : getDependsTasks())
{
args.push_back(task->targetFile().string());
}
- append(args, config.flags.ldflags);
+ for(const auto& flag : config.flags.ldflags)
+ {
+ append(args, to_strings(toolchain, flag));
+ }
{ // Write flags to file.
std::ofstream flagsStream(flagsFile);
@@ -159,10 +162,20 @@ bool TaskSO::derived() const
std::string TaskSO::flagsString() const
{
- std::string flagsStr = compiler();
+ auto toolchain = getToolChain(config.system);
+ std::string flagsStr;
+ bool first{true};
for(const auto& flag : config.flags.ldflags)
{
- flagsStr += " " + flag;
+ for(const auto& str : to_strings(toolchain, flag))
+ {
+ if(first)
+ {
+ flagsStr += " ";
+ first = false;
+ }
+ flagsStr += str;
+ }
}
flagsStr += "\n";
diff --git a/src/tools.cc b/src/tools.cc
index 610a550..476386b 100644
--- a/src/tools.cc
+++ b/src/tools.cc
@@ -5,9 +5,98 @@
#include <filesystem>
#include <iostream>
+#include <sstream>
#include <cassert>
+std::ostream& operator<<(std::ostream& stream, const ctor::c_opt& opt)
+{
+ // Adding to this enum should also imply adding to the unit-tests below
+ switch(opt)
+ {
+ case ctor::c_opt::output: stream << "ctor::c_opt::output"; break;
+ case ctor::c_opt::debug: stream << "ctor::c_opt::debug"; break;
+ case ctor::c_opt::warn_all: stream << "ctor::c_opt::warn_all"; break;
+ case ctor::c_opt::warnings_as_errors: stream << "ctor::c_opt::warnings_as_errors"; break;
+ case ctor::c_opt::generate_dep_tree: stream << "ctor::c_opt::generate_dep_tree"; break;
+ case ctor::c_opt::no_link: stream << "ctor::c_opt::no_link"; break;
+ case ctor::c_opt::include_path: stream << "ctor::c_opt::include_path"; break;
+ case ctor::c_opt::c_std: stream << "ctor::c_opt::c_std"; break;
+ case ctor::c_opt::optimization: stream << "ctor::c_opt::optimization"; break;
+ case ctor::c_opt::position_independent_code: stream << "ctor::c_opt::position_independent_code"; break;
+ case ctor::c_opt::position_independent_executable: stream << "ctor::c_opt::position_independent_executable"; break;
+ case ctor::c_opt::custom: stream << "ctor::c_opt::custom"; break;
+ }
+
+ return stream;
+}
+
+std::ostream& operator<<(std::ostream& stream, const ctor::cxx_opt& opt)
+{
+ // Adding to this enum should also imply adding to the unit-tests below
+ switch(opt)
+ {
+ case ctor::cxx_opt::output: stream << "ctor::cxx_opt::output"; break;
+ case ctor::cxx_opt::debug: stream << "ctor::cxx_opt::debug"; break;
+ case ctor::cxx_opt::warn_all: stream << "ctor::cxx_opt::warn_all"; break;
+ case ctor::cxx_opt::warnings_as_errors: stream << "ctor::cxx_opt::warnings_as_errors"; break;
+ case ctor::cxx_opt::generate_dep_tree: stream << "ctor::cxx_opt::generate_dep_tree"; break;
+ case ctor::cxx_opt::no_link: stream << "ctor::cxx_opt::no_link"; break;
+ case ctor::cxx_opt::include_path: stream << "ctor::cxx_opt::include_path"; break;
+ case ctor::cxx_opt::cpp_std: stream << "ctor::cxx_opt::cpp_std"; break;
+ case ctor::cxx_opt::optimization: stream << "ctor::cxx_opt::optimization"; break;
+ case ctor::cxx_opt::position_independent_code: stream << "ctor::cxx_opt::position_independent_code"; break;
+ case ctor::cxx_opt::position_independent_executable: stream << "ctor::cxx_opt::position_independent_executable"; break;
+ case ctor::cxx_opt::custom: stream << "ctor::cxx_opt::custom"; break;
+ }
+
+ return stream;
+}
+
+std::ostream& operator<<(std::ostream& stream, const ctor::ld_opt& opt)
+{
+ // Adding to this enum should also imply adding to the unit-tests below
+ switch(opt)
+ {
+ case ctor::ld_opt::output: stream << "ctor::ld_opt::output"; break;
+ case ctor::ld_opt::strip: stream << "ctor::ld_opt::strip"; break;
+ case ctor::ld_opt::warn_all: stream << "ctor::ld_opt::warn_all"; break;
+ case ctor::ld_opt::warnings_as_errors: stream << "ctor::ld_opt::warnings_as_errors"; break;
+ case ctor::ld_opt::library_path: stream << "ctor::ld_opt::library_path"; break;
+ case ctor::ld_opt::link: stream << "ctor::ld_opt::link"; break;
+ case ctor::ld_opt::cpp_std: stream << "ctor::ld_opt::cpp_std"; break;
+ case ctor::ld_opt::build_shared: stream << "ctor::ld_opt::build_shared"; break;
+ case ctor::ld_opt::threads: stream << "ctor::ld_opt::threads"; break;
+ case ctor::ld_opt::position_independent_code: stream << "ctor::ld_opt::position_independent_code"; break;
+ case ctor::ld_opt::position_independent_executable: stream << "ctor::ld_opt::position_independent_executable"; break;
+ case ctor::ld_opt::custom: stream << "ctor::ld_opt::custom"; break;
+ }
+
+ return stream;
+}
+
+std::ostream& operator<<(std::ostream& stream, const ctor::ar_opt& opt)
+{
+ // Adding to this enum should also imply adding to the unit-tests below
+ switch(opt)
+ {
+ case ctor::ar_opt::custom: stream << "ctor::ar_opt::custom"; break;
+ }
+
+ return stream;
+}
+
+std::ostream& operator<<(std::ostream& stream, const ctor::asm_opt& opt)
+{
+ // Adding to this enum should also imply adding to the unit-tests below
+ switch(opt)
+ {
+ case ctor::asm_opt::custom: stream << "ctor::asm_opt::custom"; break;
+ }
+
+ return stream;
+}
+
ctor::toolchain getToolChain(const std::string& compiler)
{
std::filesystem::path cc(compiler);
@@ -48,63 +137,191 @@ ctor::toolchain getToolChain(ctor::output_system system)
}
}
-namespace
+namespace gcc {
+ctor::c_flag c_option(const std::string& flag)
{
-std::vector<std::string> getOptionGcc(ctor::opt option, const std::string& arg)
+ if(flag.substr(0, 2) == "-I")
+ {
+ std::string path = flag.substr(2);
+ path.erase(0, path.find_first_not_of(' '));
+ return { ctor::c_opt::include_path, path };
+ }
+
+ return { ctor::c_opt::custom, flag };
+}
+
+ctor::cxx_flag cxx_option(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 { ctor::cxx_opt::include_path, path };
+ }
+
+ return { ctor::cxx_opt::custom, flag };
+}
+
+ctor::ld_flag ld_option(const std::string& flag)
+{
+ if(flag.substr(0, 2) == "-L")
+ {
+ std::string path = flag.substr(2);
+ path.erase(0, path.find_first_not_of(' '));
+ return { ctor::ld_opt::library_path, path };
+ }
+
+ return { ctor::ld_opt::custom, flag };
+}
+
+std::vector<std::string> cxx_option(ctor::cxx_opt opt, const std::string& arg)
{
- switch(option)
+ switch(opt)
{
- case ctor::opt::output:
+ case ctor::cxx_opt::output:
return {"-o", arg};
- case ctor::opt::debug:
+ case ctor::cxx_opt::debug:
return {"-g"};
- case ctor::opt::strip:
- return {"-s"};
- case ctor::opt::warn_all:
+ case ctor::cxx_opt::warn_all:
return {"-Wall"};
- case ctor::opt::warnings_as_errors:
+ case ctor::cxx_opt::warnings_as_errors:
return {"-Werror"};
- case ctor::opt::generate_dep_tree:
+ case ctor::cxx_opt::generate_dep_tree:
return {"-MMD"};
- case ctor::opt::no_link:
+ case ctor::cxx_opt::no_link:
return {"-c"};
- case ctor::opt::include_path:
+ case ctor::cxx_opt::include_path:
return {"-I" + arg};
- case ctor::opt::library_path:
+ case ctor::cxx_opt::cpp_std:
+ return {"-std=" + arg};
+ case ctor::cxx_opt::optimization:
+ return {"-O" + arg};
+ case ctor::cxx_opt::position_independent_code:
+ return {"-fPIC"};
+ case ctor::cxx_opt::position_independent_executable:
+ return {"-fPIE"};
+ case ctor::cxx_opt::custom:
+ return {arg};
+ }
+
+ std::cerr << "Unsupported compiler option.\n";
+ return {};
+}
+
+std::vector<std::string> c_option(ctor::c_opt opt, const std::string& arg)
+{
+ switch(opt)
+ {
+ case ctor::c_opt::output:
+ return {"-o", arg};
+ case ctor::c_opt::debug:
+ return {"-g"};
+ case ctor::c_opt::warn_all:
+ return {"-Wall"};
+ case ctor::c_opt::warnings_as_errors:
+ return {"-Werror"};
+ case ctor::c_opt::generate_dep_tree:
+ return {"-MMD"};
+ case ctor::c_opt::no_link:
+ return {"-c"};
+ case ctor::c_opt::include_path:
+ return {"-I" + arg};
+ case ctor::c_opt::c_std:
+ return {"-std=" + arg};
+ case ctor::c_opt::optimization:
+ return {"-O" + arg};
+ case ctor::c_opt::position_independent_code:
+ return {"-fPIC"};
+ case ctor::c_opt::position_independent_executable:
+ return {"-fPIE"};
+ case ctor::c_opt::custom:
+ return {arg};
+ }
+
+ std::cerr << "Unsupported compiler option.\n";
+ return {};
+}
+
+std::vector<std::string> ld_option(ctor::ld_opt opt, const std::string& arg)
+{
+ switch(opt)
+ {
+ case ctor::ld_opt::output:
+ return {"-o", arg};
+ case ctor::ld_opt::strip:
+ return {"-s"};
+ case ctor::ld_opt::warn_all:
+ return {"-Wall"};
+ case ctor::ld_opt::warnings_as_errors:
+ return {"-Werror"};
+ case ctor::ld_opt::library_path:
return {"-L" + arg};
- case ctor::opt::link:
+ case ctor::ld_opt::link:
return {"-l" + arg};
- case ctor::opt::cpp_std:
+ case ctor::ld_opt::cpp_std:
return {"-std=" + arg};
- case ctor::opt::build_shared:
+ case ctor::ld_opt::build_shared:
return {"-shared"};
- case ctor::opt::threads:
+ case ctor::ld_opt::threads:
return {"-pthread"};
- case ctor::opt::optimization:
- return {"-O" + arg};
- case ctor::opt::position_independent_code:
+ case ctor::ld_opt::position_independent_code:
return {"-fPIC"};
- case ctor::opt::position_independent_executable:
+ case ctor::ld_opt::position_independent_executable:
return {"-fPIE"};
- case ctor::opt::custom:
+ case ctor::ld_opt::custom:
return {arg};
}
std::cerr << "Unsupported compiler option.\n";
return {};
}
+
+std::vector<std::string> ar_option(ctor::ar_opt opt, const std::string& arg)
+{
+ switch(opt)
+ {
+ case ctor::ar_opt::custom:
+ return {arg};
+ }
+
+ std::cerr << "Unsupported compiler option.\n";
+ return {};
}
-std::vector<std::string> getOption(ctor::toolchain toolchain,
- ctor::opt option,
- const std::string& arg)
+std::vector<std::string> asm_option(ctor::asm_opt opt, const std::string& arg)
+{
+ switch(opt)
+ {
+ case ctor::asm_opt::custom:
+ return {arg};
+ }
+
+ std::cerr << "Unsupported compiler option.\n";
+ return {};
+}
+} // gcc::
+
+
+std::vector<std::string> c_option(ctor::toolchain toolchain,
+ ctor::c_opt opt,
+ const std::string& arg)
{
switch(toolchain)
{
case ctor::toolchain::gcc:
case ctor::toolchain::clang:
- return getOptionGcc(option, arg);
+ return gcc::c_option(opt, arg);
case ctor::toolchain::any:
+ {
+ std::ostringstream ss;
+ ss << "{" << opt;
+ if(!arg.empty())
+ {
+ ss << ", \"" << arg << "\"";
+ }
+ ss << "}";
+ return { ss.str() };
+ }
case ctor::toolchain::none:
break;
}
@@ -113,40 +330,301 @@ std::vector<std::string> getOption(ctor::toolchain toolchain,
return {};
}
-namespace {
-std::pair<ctor::opt, std::string> getOptionGcc(const std::string& flag)
+std::vector<std::string> cxx_option(ctor::toolchain toolchain,
+ ctor::cxx_opt opt,
+ const std::string& arg)
{
- if(flag.substr(0, 2) == "-I")
+ switch(toolchain)
{
- std::string path = flag.substr(2);
- path.erase(0, path.find_first_not_of(' '));
- return { ctor::opt::include_path, path };
+ case ctor::toolchain::gcc:
+ case ctor::toolchain::clang:
+ return gcc::cxx_option(opt, arg);
+ case ctor::toolchain::any:
+ {
+ std::ostringstream ss;
+ ss << "{" << opt;
+ if(!arg.empty())
+ {
+ ss << ", \"" << arg << "\"";
+ }
+ ss << "}";
+ return { ss.str() };
+ }
+ case ctor::toolchain::none:
+ break;
}
- if(flag.substr(0, 2) == "-L")
+ std::cerr << "Unsupported tool-chain.\n";
+ return {};
+}
+
+std::vector<std::string> ld_option(ctor::toolchain toolchain,
+ ctor::ld_opt opt,
+ const std::string& arg)
+{
+ switch(toolchain)
{
- std::string path = flag.substr(2);
- path.erase(0, path.find_first_not_of(' '));
- return { ctor::opt::library_path, path };
+ case ctor::toolchain::gcc:
+ case ctor::toolchain::clang:
+ return gcc::ld_option(opt, arg);
+ case ctor::toolchain::any:
+ {
+ std::ostringstream ss;
+ ss << "{" << opt;
+ if(!arg.empty())
+ {
+ ss << ", \"" << arg << "\"";
+ }
+ ss << "}";
+ return { ss.str() };
+ }
+ case ctor::toolchain::none:
+ break;
}
- return { ctor::opt::custom, flag };
+ std::cerr << "Unsupported tool-chain.\n";
+ return {};
}
+
+std::vector<std::string> ar_option(ctor::toolchain toolchain,
+ ctor::ar_opt opt,
+ const std::string& arg)
+{
+ switch(toolchain)
+ {
+ case ctor::toolchain::gcc:
+ case ctor::toolchain::clang:
+ return gcc::ar_option(opt, arg);
+ case ctor::toolchain::any:
+ {
+ std::ostringstream ss;
+ ss << "{" << opt;
+ if(!arg.empty())
+ {
+ ss << ", \"" << arg << "\"";
+ }
+ ss << "}";
+ return { ss.str() };
+ }
+ case ctor::toolchain::none:
+ break;
+ }
+
+ std::cerr << "Unsupported tool-chain.\n";
+ return {};
}
-std::pair<ctor::opt, std::string> getOption(const std::string& flag,
- ctor::toolchain toolchain)
+std::vector<std::string> asm_option(ctor::toolchain toolchain,
+ ctor::asm_opt opt,
+ const std::string& arg)
{
switch(toolchain)
{
case ctor::toolchain::gcc:
case ctor::toolchain::clang:
- return getOptionGcc(flag);
+ return gcc::asm_option(opt, arg);
case ctor::toolchain::any:
+ {
+ std::ostringstream ss;
+ ss << "{" << opt;
+ if(!arg.empty())
+ {
+ ss << ", \"" << arg << "\"";
+ }
+ ss << "}";
+ return { ss.str() };
+ }
case ctor::toolchain::none:
break;
}
std::cerr << "Unsupported tool-chain.\n";
- return { ctor::opt::custom, flag };
+ return {};
+}
+
+
+ctor::c_flag c_option(const std::string& flag, ctor::toolchain toolchain)
+{
+ switch(toolchain)
+ {
+ case ctor::toolchain::gcc:
+ case ctor::toolchain::clang:
+ return gcc::c_option(flag);
+ case ctor::toolchain::any:
+ case ctor::toolchain::none:
+ break;
+ }
+
+ return { ctor::c_opt::custom, flag };
+}
+
+ctor::cxx_flag cxx_option(const std::string& flag, ctor::toolchain toolchain)
+{
+ switch(toolchain)
+ {
+ case ctor::toolchain::gcc:
+ case ctor::toolchain::clang:
+ return gcc::cxx_option(flag);
+ case ctor::toolchain::any:
+ case ctor::toolchain::none:
+ break;
+ }
+
+ return { ctor::cxx_opt::custom, flag };
+}
+
+ctor::ld_flag ld_option(const std::string& flag, ctor::toolchain toolchain)
+{
+ switch(toolchain)
+ {
+ case ctor::toolchain::gcc:
+ case ctor::toolchain::clang:
+ return gcc::ld_option(flag);
+ case ctor::toolchain::any:
+ case ctor::toolchain::none:
+ break;
+ }
+
+ return { ctor::ld_opt::custom, flag };
+}
+
+ctor::ar_flag ar_option(const std::string& flag, ctor::toolchain toolchain)
+{
+ switch(toolchain)
+ {
+ case ctor::toolchain::gcc:
+ case ctor::toolchain::clang:
+ case ctor::toolchain::any:
+ case ctor::toolchain::none:
+ break;
+ }
+
+ return { ctor::ar_opt::custom, flag };
+}
+
+ctor::asm_flag asm_option(const std::string& flag, ctor::toolchain toolchain)
+{
+ switch(toolchain)
+ {
+ case ctor::toolchain::gcc:
+ case ctor::toolchain::clang:
+ case ctor::toolchain::any:
+ case ctor::toolchain::none:
+ break;
+ }
+
+ return { ctor::asm_opt::custom, flag };
+}
+
+// Flag to string coversions
+
+std::vector<std::string> to_strings(ctor::toolchain toolchain,
+ const ctor::c_flag& flag)
+{
+ if(flag.toolchain == ctor::toolchain::any ||
+ flag.toolchain == toolchain)
+ {
+ return c_option(toolchain, flag.opt, flag.arg);
+ }
+
+ return {};
+}
+
+std::vector<std::string> to_strings(ctor::toolchain toolchain,
+ const ctor::cxx_flag& flag)
+{
+ if(flag.toolchain == ctor::toolchain::any ||
+ flag.toolchain == toolchain)
+ {
+ return cxx_option(toolchain, flag.opt, flag.arg);
+ }
+
+ return {};
+}
+
+std::vector<std::string> to_strings(ctor::toolchain toolchain,
+ const ctor::ld_flag& flag)
+{
+ if(flag.toolchain == ctor::toolchain::any ||
+ flag.toolchain == toolchain)
+ {
+ return ld_option(toolchain, flag.opt, flag.arg);
+ }
+
+ return {};
+}
+
+std::vector<std::string> to_strings(ctor::toolchain toolchain,
+ const ctor::ar_flag& flag)
+{
+ if(flag.toolchain == ctor::toolchain::any ||
+ flag.toolchain == toolchain)
+ {
+ return ar_option(toolchain, flag.opt, flag.arg);
+ }
+
+ return {};
+}
+
+std::vector<std::string> to_strings(ctor::toolchain toolchain,
+ const ctor::asm_flag& flag)
+{
+ if(flag.toolchain == ctor::toolchain::any ||
+ flag.toolchain == toolchain)
+ {
+ return asm_option(toolchain, flag.opt, flag.arg);
+ }
+
+ return {};
+}
+
+namespace {
+ctor::toolchain guess_toolchain(const std::string& opt)
+{
+ if(opt.empty())
+ {
+ return ctor::toolchain::any;
+ }
+
+ if(opt[0] == '-')
+ {
+ return ctor::toolchain::gcc;
+ }
+
+ //if(opt[0] == '/')
+ //{
+ // return ctor::toolchain::msvc;
+ //}
+ return ctor::toolchain::any;
+}
+}
+
+template<>
+ctor::flag<ctor::c_opt>::flag(const char* str)
+{
+ *this = c_option(str, guess_toolchain(str));
+}
+
+template<>
+ctor::flag<ctor::cxx_opt>::flag(const char* str)
+{
+ *this = cxx_option(str, guess_toolchain(str));
+}
+
+template<>
+ctor::flag<ctor::ld_opt>::flag(const char* str)
+{
+ *this = ld_option(str, guess_toolchain(str));
+}
+
+template<>
+ctor::flag<ctor::ar_opt>::flag(const char* str)
+{
+ *this = ar_option(str, guess_toolchain(str));
+}
+
+template<>
+ctor::flag<ctor::asm_opt>::flag(const char* str)
+{
+ *this = asm_option(str, guess_toolchain(str));
}
diff --git a/src/tools.h b/src/tools.h
index e6c2264..b1285ec 100644
--- a/src/tools.h
+++ b/src/tools.h
@@ -5,23 +5,92 @@
#include <vector>
#include <string>
+#include <ostream>
#include "ctor.h"
+
+std::ostream& operator<<(std::ostream& stream, const ctor::c_opt& opt);
+std::ostream& operator<<(std::ostream& stream, const ctor::cxx_opt& opt);
+std::ostream& operator<<(std::ostream& stream, const ctor::ld_opt& opt);
+std::ostream& operator<<(std::ostream& stream, const ctor::ar_opt& opt);
+std::ostream& operator<<(std::ostream& stream, const ctor::asm_opt& opt);
+
+
//! Get tool-chain type from compiler path string
ctor::toolchain getToolChain(const std::string& compiler);
//! Get tool-chain type from output system (via configuration)
ctor::toolchain getToolChain(ctor::output_system system);
+
+
+//! Get tool argument(s) for specific option type matching the supplied
+//! tool-chain
+std::vector<std::string> c_option(ctor::toolchain toolchain,
+ ctor::c_opt option,
+ const std::string& arg = {});
+
+//! Get tool argument(s) for specific option type matching the supplied
+//! tool-chain
+std::vector<std::string> cxx_option(ctor::toolchain toolchain,
+ ctor::cxx_opt option,
+ const std::string& arg = {});
+
//! Get tool argument(s) for specific option type matching the supplied
//! tool-chain
-std::vector<std::string> getOption(ctor::toolchain toolchain,
- ctor::opt option,
+std::vector<std::string> ld_option(ctor::toolchain toolchain,
+ ctor::ld_opt option,
const std::string& arg = {});
-//! Get opt enum value and argument from string,
-//! ie. { opt::InludePath, "foo/bar" } from "-Ifoo/bar"
-//! Returns { opt::Custom, flag } if unknown.
-std::pair<ctor::opt, std::string> getOption(const std::string& flag,
- ctor::toolchain toolchain = ctor::toolchain::gcc);
+//! Get tool argument(s) for specific option type matching the supplied
+//! tool-chain
+std::vector<std::string> ar_option(ctor::toolchain toolchain,
+ ctor::ar_opt option,
+ const std::string& arg = {});
+
+//! Get tool argument(s) for specific option type matching the supplied
+//! tool-chain
+std::vector<std::string> asm_option(ctor::toolchain toolchain,
+ ctor::asm_opt option,
+ const std::string& arg = {});
+
+
+
+//! Get ctor::c_opt enum value and argument from string,
+//! ie. { ctor::c_opt::inlude_path, "foo/bar" } from "-Ifoo/bar"
+//! Returns { ctor::c_opt::custom, flag } if unknown.
+ctor::c_flag c_option(const std::string& flag, ctor::toolchain toolchain);
+
+//! Get ctor::cxx_opt enum value and argument from string,
+//! ie. { ctor::cxx_opt::inlude_path, "foo/bar" } from "-Ifoo/bar"
+//! Returns { ctor::cxx_opt::custom, flag } if unknown.
+ctor::cxx_flag cxx_option(const std::string& flag, ctor::toolchain toolchain);
+
+//! Get ctor::ld_opt enum value and argument from string,
+//! ie. { ctor::ld_opt::inlude_path, "foo/bar" } from "-Ifoo/bar"
+//! Returns { ctor::ld_opt::custom, flag } if unknown.
+ctor::ld_flag ld_option(const std::string& flag, ctor::toolchain toolchain);
+
+//! Get ctor::ar_opt enum value and argument from string,
+//! ie. { ctor::ar_opt::inlude_path, "foo/bar" } from "-Ifoo/bar"
+//! Returns { ctor::ar_opt::custom, flag } if unknown.
+ctor::ar_flag ar_option(const std::string& flag, ctor::toolchain toolchain);
+
+//! Get ctor::asm_opt enum value and argument from string,
+//! ie. { ctor::asm_opt::inlude_path, "foo/bar" } from "-Ifoo/bar"
+//! Returns { ctor::asm_opt::custom, flag } if unknown.
+ctor::asm_flag asm_option(const std::string& flag, ctor::toolchain toolchain);
+
+
+
+std::vector<std::string> to_strings(ctor::toolchain toolchain,
+ const ctor::cxx_flag& flag);
+std::vector<std::string> to_strings(ctor::toolchain toolchain,
+ const ctor::c_flag& flag);
+std::vector<std::string> to_strings(ctor::toolchain toolchain,
+ const ctor::ld_flag& flag);
+std::vector<std::string> to_strings(ctor::toolchain toolchain,
+ const ctor::ar_flag& flag);
+std::vector<std::string> to_strings(ctor::toolchain toolchain,
+ const ctor::asm_flag& flag);
diff --git a/src/util.h b/src/util.h
index d5fccc8..c7318aa 100644
--- a/src/util.h
+++ b/src/util.h
@@ -18,3 +18,8 @@ void append(T& a, const T& b)
{
a.insert(a.end(), b.begin(), b.end());
}
+
+//using cxx_flags = std::vector<ctor::cxx_flag>;
+//using c_flags = std::vector<std::string>;
+//using ld_flags= std::vector<std::string>;
+//using asm_flags = std::vector<std::string>;