summaryrefslogtreecommitdiff
path: root/src/tools.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools.cc')
-rw-r--r--src/tools.cc231
1 files changed, 200 insertions, 31 deletions
diff --git a/src/tools.cc b/src/tools.cc
index a83f115..be94794 100644
--- a/src/tools.cc
+++ b/src/tools.cc
@@ -8,6 +8,7 @@
#include <sstream>
#include <cassert>
+#include <cstdio>
#include "util.h"
@@ -115,7 +116,8 @@ ctor::toolchain getToolChain(const std::string& compiler)
return ctor::toolchain::clang;
}
else if(cc_cmd.find("g++") != std::string::npos ||
- cc_cmd.find("gcc") != std::string::npos)
+ cc_cmd.find("gcc") != std::string::npos ||
+ cc_cmd.find("mingw") != std::string::npos)
{
return ctor::toolchain::gcc;
}
@@ -146,9 +148,95 @@ ctor::toolchain getToolChain(ctor::output_system system)
}
namespace gcc {
+std::string get_arch(ctor::output_system system)
+{
+ std::string cmd;
+
+ const auto& c = ctor::get_configuration();
+ switch(system)
+ {
+ case ctor::output_system::host:
+ cmd = c.get(ctor::cfg::host_cxx, "/usr/bin/g++");
+ break;
+ case ctor::output_system::build:
+ cmd = c.get(ctor::cfg::build_cxx, "/usr/bin/g++");
+ break;
+ }
+
+ cmd += " -v";
+ cmd += " 2>&1";
+ auto pipe = popen(cmd.data(), "r");
+ if(!pipe)
+ {
+ std::cerr << "Could not run compiler " << cmd << "\n";
+ return {};//ctor::arch::unknown;
+ }
+
+ std::string arch;
+ while(!feof(pipe))
+ {
+ char buf[1024];
+ if(fgets(buf, sizeof(buf), pipe) != nullptr)
+ {
+ arch = buf;
+ if(arch.starts_with("Target:"))
+ {
+ break;
+ }
+ }
+ }
+
+ pclose(pipe);
+
+ // Remove trailing newline
+ if(arch.ends_with("\n"))
+ {
+ arch = arch.substr(0, arch.length() - 1);
+ }
+
+ // Remove 'Target: ' prefix
+ arch = arch.substr(8);
+ return arch;
+}
+
+ctor::arch get_arch(const std::string& str)
+{
+ // gcc -v 2>&1 | grep Target
+ // Target: x86_64-apple-darwin19.6.0
+ // Target: x86_64-pc-linux-gnu
+ // Target: arm-linux-gnueabihf
+ // Target: x86_64-linux-gnu
+ // Target: x86_64-unknown-freebsd13.1
+ // # x86_64-w64-mingw32-c++-win32 -v 2>&1 | grep Target
+ // Target: x86_64-w64-mingw32
+ // # i686-w64-mingw32-c++-win32 -v 2>&1 | grep Target
+ // Target: i686-w64-mingw32
+
+ if(str.find("apple") != std::string::npos ||
+ str.find("darwin") != std::string::npos)
+ {
+ return ctor::arch::apple;
+ }
+
+ if(str.find("linux") != std::string::npos ||
+ str.find("bsd") != std::string::npos)
+ {
+ return ctor::arch::unix;
+ }
+
+ if(str.find("mingw") != std::string::npos)
+ {
+ return ctor::arch::windows;
+ }
+
+ std::cerr << "Could not deduce gcc arch from '" << str << "'" << std::endl;
+
+ return ctor::arch::unknown;
+}
+
ctor::c_flag c_option(const std::string& flag)
{
- if(flag.substr(0, 2) == "-I")
+ if(flag.starts_with("-I"))
{
std::string path = flag.substr(2);
path.erase(0, path.find_first_not_of(' '));
@@ -160,7 +248,7 @@ ctor::c_flag c_option(const std::string& flag)
ctor::cxx_flag cxx_option(const std::string& flag)
{
- if(flag.substr(0, 2) == "-I")
+ if(flag.starts_with("-I"))
{
std::string path = flag.substr(2);
path.erase(0, path.find_first_not_of(' '));
@@ -172,7 +260,7 @@ ctor::cxx_flag cxx_option(const std::string& flag)
ctor::ld_flag ld_option(const std::string& flag)
{
- if(flag.substr(0, 2) == "-L")
+ if(flag.starts_with("-L"))
{
std::string path = flag.substr(2);
path.erase(0, path.find_first_not_of(' '));
@@ -320,34 +408,37 @@ std::vector<std::string> asm_option(ctor::asm_opt opt, const std::string& arg)
std::cerr << "Unsupported compiler option.\n";
return {};
}
+} // gcc::
-std::string extension(ctor::target_type target_type)
+std::string get_arch(ctor::output_system system)
{
- switch(target_type)
+ auto toolchain = getToolChain(system);
+ switch(toolchain)
{
- case ctor::target_type::automatic:
- break;
- case ctor::target_type::executable:
- return "";
- case ctor::target_type::static_library:
- return ".a";
- case ctor::target_type::dynamic_library:
- return ".so";
- case ctor::target_type::object:
- return ".o";
- case ctor::target_type::unit_test:
- return "";
- case ctor::target_type::unit_test_library:
- return ".a";
- case ctor::target_type::function:
- break;
- case ctor::target_type::unknown:
+ case ctor::toolchain::clang:
+ case ctor::toolchain::gcc:
+ return gcc::get_arch(system);
+ case ctor::toolchain::any:
+ case ctor::toolchain::none:
break;
}
return {};
}
-} // gcc::
+ctor::arch get_arch(ctor::output_system system, const std::string& str)
+{
+ auto toolchain = getToolChain(system);
+ switch(toolchain)
+ {
+ case ctor::toolchain::clang:
+ case ctor::toolchain::gcc:
+ return gcc::get_arch(str);
+ case ctor::toolchain::any:
+ case ctor::toolchain::none:
+ break;
+ }
+ return ctor::arch::unknown;
+}
std::vector<std::string> c_option(ctor::toolchain toolchain,
ctor::c_opt opt,
@@ -746,6 +837,7 @@ ctor::target_type target_type_from_extension(ctor::toolchain toolchain,
std::filesystem::path extension(ctor::toolchain toolchain,
ctor::target_type target_type,
+ ctor::output_system system,
const std::filesystem::path& file)
{
auto type = target_type_from_extension(toolchain, file);
@@ -755,16 +847,93 @@ std::filesystem::path extension(ctor::toolchain toolchain,
return file;
}
+ const auto& c = ctor::get_configuration();
+ ctor::arch arch{};
+ switch(system)
+ {
+ case ctor::output_system::host:
+ arch = c.host_arch;
+ break;
+ case ctor::output_system::build:
+ arch = c.build_arch;
+ break;
+ }
+
+ // This might be before configure - so detection is needed for boostrap
+ if(arch == ctor::arch::unknown)
+ {
+ arch = get_arch(system, get_arch(system));
+ }
+
std::string ext{file.extension().string()};
- switch(toolchain)
+ switch(target_type)
{
- case ctor::toolchain::gcc:
- case ctor::toolchain::clang:
- ext = gcc::extension(target_type);
+ case ctor::target_type::automatic:
+ break;
+ case ctor::target_type::executable:
+ case ctor::target_type::unit_test:
+ switch(arch)
+ {
+ case ctor::arch::unix:
+ case ctor::arch::apple:
+ ext = "";
+ break;
+ case ctor::arch::windows:
+ ext = ".exe";
+ break;
+ case ctor::arch::unknown:
+ break;
+ }
+ break;
+ case ctor::target_type::static_library:
+ case ctor::target_type::unit_test_library:
+ switch(arch)
+ {
+ case ctor::arch::unix:
+ case ctor::arch::apple:
+ ext = ".a";
+ break;
+ case ctor::arch::windows:
+ ext = ".lib";
+ break;
+ case ctor::arch::unknown:
+ break;
+ }
+ break;
+ case ctor::target_type::dynamic_library:
+ switch(arch)
+ {
+ case ctor::arch::unix:
+ ext = ".so";
+ break;
+ case ctor::arch::apple:
+ ext = ".dylib";
+ break;
+ case ctor::arch::windows:
+ ext = ".dll";
+ break;
+ case ctor::arch::unknown:
+ break;
+ }
+ break;
+ case ctor::target_type::object:
+ switch(arch)
+ {
+ case ctor::arch::unix:
+ case ctor::arch::apple:
+ ext = ".o";
+ break;
+ case ctor::arch::windows:
+ ext = ".obj";
+ break;
+ case ctor::arch::unknown:
+ break;
+ }
+ break;
+ case ctor::target_type::function:
+ break;
+ case ctor::target_type::unknown:
break;
- case ctor::toolchain::any:
- case ctor::toolchain::none:
- return file;
}
auto output{file};