diff options
Diffstat (limited to 'src/tools.cc')
| -rw-r--r-- | src/tools.cc | 136 | 
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 }; +} | 
