summaryrefslogtreecommitdiff
path: root/src/tools.cc
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2025-02-01 20:37:32 +0100
committerBent Bisballe Nyeng <deva@aasimon.org>2025-02-21 18:11:26 +0100
commit7b2a17216ec5cb97eeb517863d7336cc04852b43 (patch)
tree36f90d6f2cdbe8b893c9b5138460ffbdc9a129d8 /src/tools.cc
parentdbacf0029104780556af5791f2c6a45edc7a5ec4 (diff)
WIP
Diffstat (limited to 'src/tools.cc')
-rw-r--r--src/tools.cc295
1 files changed, 286 insertions, 9 deletions
diff --git a/src/tools.cc b/src/tools.cc
index dfabdff..1a539be 100644
--- a/src/tools.cc
+++ b/src/tools.cc
@@ -6,6 +6,7 @@
#include <filesystem>
#include <iostream>
#include <sstream>
+#include <algorithm>
#include <array>
#include <cassert>
@@ -13,6 +14,11 @@
#include "util.h"
+#if defined(_WIN32)
+#define popen _popen
+#define pclose _pclose
+#endif
+
std::ostream& operator<<(std::ostream& stream, const ctor::c_opt& opt)
{
// Adding to this enum should also imply adding to the unit-tests below
@@ -129,6 +135,10 @@ ctor::toolchain getToolChain(const std::string& compiler)
{
return ctor::toolchain::gcc;
}
+ else if(to_lower(cc_cmd).find("cl") != std::string::npos)
+ {
+ return ctor::toolchain::msvc;
+ }
std::cerr << "Unsupported output system.\n";
return ctor::toolchain::gcc;
@@ -154,12 +164,256 @@ 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)
+{
+ return "windows";
+}
+
+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::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;
std::string cmd;
-
const auto& c = ctor::get_configuration();
switch(system)
{
@@ -180,7 +434,6 @@ std::string get_arch(ctor::output_system system)
return {};//ctor::arch::unknown;
}
- std::string arch;
while(!feof(pipe))
{
constexpr auto buffer_size{1024};
@@ -571,6 +824,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;
@@ -586,6 +841,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;
@@ -603,6 +860,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;
@@ -636,6 +895,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;
@@ -669,6 +930,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;
@@ -702,6 +965,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;
@@ -735,6 +1000,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;
@@ -766,6 +1033,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;
@@ -781,6 +1050,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;
@@ -796,6 +1067,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;
@@ -811,6 +1084,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;
@@ -825,6 +1100,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;
@@ -908,10 +1184,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;
}
}
@@ -982,8 +1259,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 ||
)
{