summaryrefslogtreecommitdiff
path: root/src/tools.cc
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2023-01-16 17:51:57 +0100
committerBent Bisballe Nyeng <deva@aasimon.org>2023-01-16 17:51:57 +0100
commit9da7f08eb0f34f52561a62d7cf1004621b7d83c2 (patch)
tree012a9620b5a52f7a1098d04a1cb6c45404e41e1b /src/tools.cc
parenta257c2f4d333969c73d8b27124e658db6430645a (diff)
Make file extensions abstract based on tool-chain type.
Diffstat (limited to 'src/tools.cc')
-rw-r--r--src/tools.cc123
1 files changed, 123 insertions, 0 deletions
diff --git a/src/tools.cc b/src/tools.cc
index 28d3903..6d4c34b 100644
--- a/src/tools.cc
+++ b/src/tools.cc
@@ -9,6 +9,8 @@
#include <cassert>
+#include "util.h"
+
std::ostream& operator<<(std::ostream& stream, const ctor::c_opt& opt)
{
// Adding to this enum should also imply adding to the unit-tests below
@@ -316,6 +318,32 @@ std::vector<std::string> asm_option(ctor::asm_opt opt, const std::string& arg)
std::cerr << "Unsupported compiler option.\n";
return {};
}
+
+std::string extension(ctor::target_type target_type)
+{
+ switch(target_type)
+ {
+ 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:
+ break;
+ }
+ return {};
+}
} // gcc::
@@ -646,3 +674,98 @@ ctor::flag<ctor::asm_opt>::flag(const char* str)
{
*this = asm_option(str, guess_toolchain(str));
}
+
+
+ctor::target_type target_type_from_extension(ctor::toolchain toolchain,
+ const std::filesystem::path& file)
+{
+ auto ext = to_lower(file.extension().string());
+ // Loosely based on:
+ // https://en.wikipedia.org/wiki/List_of_file_formats#Object_code,_executable_files,_shared_and_dynamically_linked_libraries
+ if(toolchain == ctor::toolchain::any ||
+ toolchain == ctor::toolchain::gcc ||
+ toolchain == ctor::toolchain::clang)
+ {
+ if(ext == ".a")
+ {
+ return ctor::target_type::static_library;
+ }
+
+ if(ext == ".so" ||
+ ext == ".dylib")
+ {
+ return ctor::target_type::dynamic_library;
+ }
+
+ if(ext == ".o")
+ {
+ return ctor::target_type::object;
+ }
+
+ if(ext == "" ||
+ ext == ".bin" ||
+ ext == ".run" ||
+ ext == ".out")
+ {
+ return ctor::target_type::executable;
+ }
+ }
+
+ if(toolchain == ctor::toolchain::any// ||
+ //toolchain == ctor::toolchain::msvc ||
+ //toolchain == ctor::toolchain::mingw ||
+ )
+ {
+ if(ext == ".lib")
+ {
+ return ctor::target_type::static_library;
+ }
+
+ if(ext == ".dll")
+ {
+ return ctor::target_type::dynamic_library;
+ }
+
+ if(ext == ".obj")
+ {
+ return ctor::target_type::object;
+ }
+
+ if(ext == ".exe" ||
+ ext == ".com")
+ {
+ return ctor::target_type::executable;
+ }
+ }
+
+ return ctor::target_type::unknown;
+}
+
+
+std::filesystem::path extension(ctor::toolchain toolchain,
+ ctor::target_type target_type,
+ const std::filesystem::path& file)
+{
+ auto type = target_type_from_extension(toolchain, file);
+ if(type == target_type)
+ {
+ // File already has the correct extension
+ return file;
+ }
+
+ std::string ext{file.extension().string()};
+ switch(toolchain)
+ {
+ case ctor::toolchain::gcc:
+ case ctor::toolchain::clang:
+ ext = gcc::extension(target_type);
+ break;
+ case ctor::toolchain::any:
+ case ctor::toolchain::none:
+ return file;
+ }
+
+ auto output{file};
+ output.replace_extension(ext);
+ return output;
+}