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