diff options
Diffstat (limited to 'src/tools.cc')
-rw-r--r-- | src/tools.cc | 409 |
1 files changed, 400 insertions, 9 deletions
diff --git a/src/tools.cc b/src/tools.cc index eb98265..7f16a0e 100644 --- a/src/tools.cc +++ b/src/tools.cc @@ -6,6 +6,7 @@ #include <filesystem> #include <iostream> #include <sstream> +#include <algorithm> #include <cassert> #include <cstdio> @@ -20,6 +21,9 @@ std::ostream& operator<<(std::ostream& stream, const ctor::c_opt& 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::warn_conversion: stream << "ctor::c_opt::warn_conversion"; break; + case ctor::c_opt::warn_shadow: stream << "ctor::c_opt::warn_shadow"; break; + case ctor::c_opt::warn_extra: stream << "ctor::c_opt::warn_extra"; 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; @@ -43,6 +47,9 @@ std::ostream& operator<<(std::ostream& stream, const ctor::cxx_opt& 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::warn_conversion: stream << "ctor::cxx_opt::warn_conversion"; break; + case ctor::cxx_opt::warn_shadow: stream << "ctor::cxx_opt::warn_shadow"; break; + case ctor::cxx_opt::warn_extra: stream << "ctor::cxx_opt::warn_extra"; 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; @@ -111,18 +118,27 @@ ctor::toolchain getToolChain(const std::string& compiler) std::filesystem::path cc(compiler); auto cc_cmd = cc.stem().string(); + std::cout << "getToolChain: [" << cc_cmd << "] => "; + // Note: "g++" is a substring of "clang++" so "clang++" must be tested first. if(cc_cmd.find("clang++") != std::string::npos || cc_cmd.find("clang") != std::string::npos) { + std::cout << "clang" << std::endl; return ctor::toolchain::clang; } else if(cc_cmd.find("g++") != std::string::npos || cc_cmd.find("gcc") != std::string::npos || cc_cmd.find("mingw") != std::string::npos) { + std::cout << "gcc" << std::endl; return ctor::toolchain::gcc; } + else if(to_lower(cc_cmd).find("cl") != std::string::npos) + { + std::cout << "msvc" << std::endl; + return ctor::toolchain::msvc; + } std::cerr << "Unsupported output system.\n"; return ctor::toolchain::gcc; @@ -148,12 +164,262 @@ ctor::toolchain getToolChain(ctor::output_system system) return getToolChain(cfg.get(ctor::cfg::build_cxx, "g++")); } } +namespace msvc { +std::string get_arch([[maybe_unused]] ctor::output_system system) +{ + std::string arch; + // TODO + return arch; +} + +ctor::arch get_arch([[maybe_unused]] const std::string& str) +{ + return ctor::arch::windows; +} + +ctor::c_flag c_option(const std::string& flag) +{ + if(flag.starts_with("/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.starts_with("/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.starts_with("/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 }; +} + +ctor::ar_flag ar_option(const std::string& flag) +{ + return { ctor::ar_opt::custom, flag }; +} + +std::vector<std::string> cxx_option(ctor::cxx_opt opt, const std::string& arg, + const std::string& arg2) +{ + switch(opt) + { + case ctor::cxx_opt::output: + return {"/Fo\"" + arg + "\""}; + case ctor::cxx_opt::debug: + return {"/DEBUG"}; + case ctor::cxx_opt::warn_all: + return {"/W4"}; + case ctor::cxx_opt::warn_conversion: + return {"/W4"}; // TODO: This is incorrect + case ctor::cxx_opt::warn_shadow: + return {"/W4"}; // TODO: This is incorrect + case ctor::cxx_opt::warn_extra: + return {"/W4"}; // TODO: This is incorrect + case ctor::cxx_opt::warnings_as_errors: + return {"/WX"}; + case ctor::cxx_opt::generate_dep_tree: + return {"/sourceDependencies", arg}; + case ctor::cxx_opt::no_link: + return {"/c"}; + case ctor::cxx_opt::include_path: + return {"/I" + arg}; + case ctor::cxx_opt::cpp_std: + return {"/std:" + arg}; + case ctor::cxx_opt::optimization: + { + int o{0}; + try + { + o = std::stoi(arg); + o = std::clamp(o, 0, 2); + } + catch(...) + { + // bad number? + } + return {"/O" + std::to_string(o)}; + } + case ctor::cxx_opt::position_independent_code: + return {}; // TODO? + case ctor::cxx_opt::position_independent_executable: + return {}; // TODO? + case ctor::cxx_opt::define: + if(!arg2.empty()) + { + return {"/D" + arg + "=" + esc(arg2)}; + } + else + { + return {"/D" + arg}; + } + 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, + const std::string& arg2) +{ + switch(opt) + { + case ctor::c_opt::output: + return {"/Fo\"" + arg + "\""}; + case ctor::c_opt::debug: + return {"/DEBUG"}; + case ctor::c_opt::warn_all: + return {"/W4"}; + case ctor::c_opt::warn_conversion: + return {"/W4"}; // TODO: This is incorrect + case ctor::c_opt::warn_shadow: + return {"/W4"}; // TODO: This is incorrect + case ctor::c_opt::warn_extra: + return {"/W4"}; // TODO: This is incorrect + case ctor::c_opt::warnings_as_errors: + return {"/WX"}; + case ctor::c_opt::generate_dep_tree: + return {"/sourceDependencies", arg}; + 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: + { + int o{0}; + try + { + o = std::stoi(arg); + o = std::clamp(o, 0, 2); + } + catch(...) + { + // bad number? + } + return {"/O" + std::to_string(o)}; + } + case ctor::c_opt::position_independent_code: + return {}; // TODO? + case ctor::c_opt::position_independent_executable: + return {}; // TODO? + case ctor::c_opt::define: + if(!arg2.empty()) + { + return {"/D" + arg + "=" + esc(arg2)}; + } + else + { + return {"/D" + arg}; + } + 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, + [[maybe_unused]]const std::string& arg2) +{ + switch(opt) + { + case ctor::ld_opt::output: + return {"/out:" + arg + ""}; + case ctor::ld_opt::strip: + return {}; // TODO? + case ctor::ld_opt::warn_all: + return {"/Wall"}; + case ctor::ld_opt::warnings_as_errors: + return {"/WX"}; + case ctor::ld_opt::library_path: + return {"/LIBPATH:\""+arg+"\""}; + case ctor::ld_opt::link: + return {arg}; // TODO? + case ctor::ld_opt::cpp_std: + return {"/std:" + arg}; + case ctor::ld_opt::build_shared: + return {}; // TODO? + case ctor::ld_opt::threads: + return {}; // TODO? + case ctor::ld_opt::position_independent_code: + return {}; // TODO? + case ctor::ld_opt::position_independent_executable: + return {}; // TODO? + 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, + [[maybe_unused]]const std::string& arg2) +{ + switch(opt) + { + case ctor::ar_opt::replace: + return {}; + case ctor::ar_opt::add_index: + return {}; + case ctor::ar_opt::create: + return {}; + case ctor::ar_opt::output: + return {"/out:" + arg}; + case ctor::ar_opt::custom: + return {arg}; + } + + std::cerr << "Unsupported compiler option.\n"; + return {}; +} + +std::vector<std::string> asm_option(ctor::asm_opt opt, const std::string& arg, + [[maybe_unused]]const std::string& arg2) +{ + switch(opt) + { + case ctor::asm_opt::custom: + return {arg}; + } + + std::cerr << "Unsupported compiler option.\n"; + return {}; +} +} // msvc:: + namespace gcc { -std::string get_arch(ctor::output_system system) +std::string get_arch([[maybe_unused]] ctor::output_system system) { + std::string arch; + // TODO popen on windows +#if !defined(_WIN32) std::string cmd; - const auto& c = ctor::get_configuration(); switch(system) { @@ -174,7 +440,6 @@ std::string get_arch(ctor::output_system system) return {};//ctor::arch::unknown; } - std::string arch; while(!feof(pipe)) { constexpr auto buffer_size{1024}; @@ -200,6 +465,7 @@ std::string get_arch(ctor::output_system system) // Remove 'Target: ' prefix constexpr auto prefix_length{8}; arch = arch.substr(prefix_length); +#endif // _WIN32 return arch; } @@ -247,6 +513,48 @@ ctor::c_flag c_option(const std::string& flag) return { ctor::c_opt::include_path, path }; } + if(flag.starts_with("-std=")) + { + std::string std = flag.substr(5); + return { ctor::c_opt::c_std, std }; + } + + if(flag.starts_with("-O")) + { + std::string opt = flag.substr(2, 1); + return { ctor::c_opt::optimization, opt }; + } + + if(flag.starts_with("-Wall")) + { + return { ctor::c_opt::warn_all }; + } + + if(flag.starts_with("-Wconversion")) + { + return { ctor::c_opt::warn_conversion}; + } + + if(flag.starts_with("-Wshadow")) + { + return { ctor::c_opt::warn_shadow}; + } + + if(flag.starts_with("-Wextra")) + { + return { ctor::c_opt::warn_extra}; + } + + if(flag.starts_with("-Werror")) + { + return { ctor::c_opt::warnings_as_errors }; + } + + if(flag.starts_with("-g")) + { + return { ctor::c_opt::debug }; + } + if(flag.starts_with("-D")) { std::string def = flag.substr(2); @@ -272,6 +580,48 @@ ctor::cxx_flag cxx_option(const std::string& flag) return { ctor::cxx_opt::include_path, path }; } + if(flag.starts_with("-std=")) + { + std::string std = flag.substr(5); + return { ctor::cxx_opt::cpp_std, std }; + } + + if(flag.starts_with("-O")) + { + std::string opt = flag.substr(2, 1); + return { ctor::cxx_opt::optimization, opt }; + } + + if(flag.starts_with("-Wall")) + { + return { ctor::cxx_opt::warn_all }; + } + + if(flag.starts_with("-Werror")) + { + return { ctor::cxx_opt::warnings_as_errors }; + } + + if(flag.starts_with("-Wconversion")) + { + return { ctor::cxx_opt::warn_conversion}; + } + + if(flag.starts_with("-Wshadow")) + { + return { ctor::cxx_opt::warn_shadow}; + } + + if(flag.starts_with("-Wextra")) + { + return { ctor::cxx_opt::warn_extra}; + } + + if(flag.starts_with("-g")) + { + return { ctor::cxx_opt::debug }; + } + if(flag.starts_with("-D")) { std::string def = flag.substr(2); @@ -298,6 +648,11 @@ ctor::ld_flag ld_option(const std::string& flag) return { ctor::ld_opt::library_path, path }; } + if(flag.starts_with("-pthread")) + { + return { ctor::ld_opt::threads }; + } + return { ctor::ld_opt::custom, flag }; } @@ -317,6 +672,12 @@ std::vector<std::string> cxx_option(ctor::cxx_opt opt, const std::string& arg, return {"-g"}; case ctor::cxx_opt::warn_all: return {"-Wall"}; + case ctor::cxx_opt::warn_conversion: + return {"-Wconversion"}; + case ctor::cxx_opt::warn_shadow: + return {"-Wshadow"}; + case ctor::cxx_opt::warn_extra: + return {"-Wextra"}; case ctor::cxx_opt::warnings_as_errors: return {"-Werror"}; case ctor::cxx_opt::generate_dep_tree: @@ -358,6 +719,12 @@ std::vector<std::string> c_option(ctor::c_opt opt, const std::string& arg, return {"-g"}; case ctor::c_opt::warn_all: return {"-Wall"}; + case ctor::c_opt::warn_conversion: + return {"-Wconversion"}; + case ctor::c_opt::warn_shadow: + return {"-Wshadow"}; + case ctor::c_opt::warn_extra: + return {"-Wextra"}; case ctor::c_opt::warnings_as_errors: return {"-Werror"}; case ctor::c_opt::generate_dep_tree: @@ -466,6 +833,8 @@ std::string get_arch(ctor::output_system system) case ctor::toolchain::clang: case ctor::toolchain::gcc: return gcc::get_arch(system); + case ctor::toolchain::msvc: + return msvc::get_arch(system); case ctor::toolchain::any: case ctor::toolchain::none: break; @@ -481,6 +850,8 @@ ctor::arch get_arch(ctor::output_system system, const std::string& str) case ctor::toolchain::clang: case ctor::toolchain::gcc: return gcc::get_arch(str); + case ctor::toolchain::msvc: + return msvc::get_arch(str); case ctor::toolchain::any: case ctor::toolchain::none: break; @@ -498,6 +869,8 @@ std::vector<std::string> c_option(ctor::toolchain toolchain, case ctor::toolchain::gcc: case ctor::toolchain::clang: return gcc::c_option(opt, arg, arg2); + case ctor::toolchain::msvc: + return msvc::c_option(opt, arg, arg2); case ctor::toolchain::any: { std::ostringstream ss; @@ -531,6 +904,8 @@ std::vector<std::string> cxx_option(ctor::toolchain toolchain, case ctor::toolchain::gcc: case ctor::toolchain::clang: return gcc::cxx_option(opt, arg, arg2); + case ctor::toolchain::msvc: + return msvc::cxx_option(opt, arg, arg2); case ctor::toolchain::any: { std::ostringstream ss; @@ -564,6 +939,8 @@ std::vector<std::string> ld_option(ctor::toolchain toolchain, case ctor::toolchain::gcc: case ctor::toolchain::clang: return gcc::ld_option(opt, arg, arg2); + case ctor::toolchain::msvc: + return msvc::ld_option(opt, arg, arg2); case ctor::toolchain::any: { std::ostringstream ss; @@ -597,6 +974,8 @@ std::vector<std::string> ar_option(ctor::toolchain toolchain, case ctor::toolchain::gcc: case ctor::toolchain::clang: return gcc::ar_option(opt, arg, arg2); + case ctor::toolchain::msvc: + return msvc::ar_option(opt, arg, arg2); case ctor::toolchain::any: { std::ostringstream ss; @@ -630,6 +1009,8 @@ std::vector<std::string> asm_option(ctor::toolchain toolchain, case ctor::toolchain::gcc: case ctor::toolchain::clang: return gcc::asm_option(opt, arg, arg2); + case ctor::toolchain::msvc: + return msvc::asm_option(opt, arg, arg2); case ctor::toolchain::any: { std::ostringstream ss; @@ -661,6 +1042,8 @@ ctor::c_flag c_option(const std::string& flag, ctor::toolchain toolchain) case ctor::toolchain::gcc: case ctor::toolchain::clang: return gcc::c_option(flag); + case ctor::toolchain::msvc: + return msvc::c_option(flag); case ctor::toolchain::any: case ctor::toolchain::none: break; @@ -676,6 +1059,8 @@ ctor::cxx_flag cxx_option(const std::string& flag, ctor::toolchain toolchain) case ctor::toolchain::gcc: case ctor::toolchain::clang: return gcc::cxx_option(flag); + case ctor::toolchain::msvc: + return msvc::cxx_option(flag); case ctor::toolchain::any: case ctor::toolchain::none: break; @@ -691,6 +1076,8 @@ ctor::ld_flag ld_option(const std::string& flag, ctor::toolchain toolchain) case ctor::toolchain::gcc: case ctor::toolchain::clang: return gcc::ld_option(flag); + case ctor::toolchain::msvc: + return msvc::ld_option(flag); case ctor::toolchain::any: case ctor::toolchain::none: break; @@ -706,6 +1093,8 @@ ctor::ar_flag ar_option(const std::string& flag, ctor::toolchain toolchain) case ctor::toolchain::gcc: case ctor::toolchain::clang: return gcc::ar_option(flag); + case ctor::toolchain::msvc: + return msvc::ar_option(flag); case ctor::toolchain::any: case ctor::toolchain::none: break; @@ -720,6 +1109,7 @@ ctor::asm_flag asm_option(const std::string& flag, ctor::toolchain toolchain) { case ctor::toolchain::gcc: case ctor::toolchain::clang: + case ctor::toolchain::msvc: case ctor::toolchain::any: case ctor::toolchain::none: break; @@ -803,10 +1193,11 @@ ctor::toolchain guess_toolchain(const std::string& opt) return ctor::toolchain::gcc; } - //if(opt[0] == '/') - //{ - // return ctor::toolchain::msvc; - //} + if(opt[0] == '/') + { + return ctor::toolchain::msvc; + } + return ctor::toolchain::any; } } @@ -877,8 +1268,8 @@ ctor::target_type target_type_from_extension(ctor::toolchain toolchain, } } - if(toolchain == ctor::toolchain::any// || - //toolchain == ctor::toolchain::msvc || + if(toolchain == ctor::toolchain::any || + toolchain == ctor::toolchain::msvc// || //toolchain == ctor::toolchain::mingw || ) { |