From 9da7f08eb0f34f52561a62d7cf1004621b7d83c2 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Mon, 16 Jan 2023 17:51:57 +0100 Subject: Make file extensions abstract based on tool-chain type. --- src/task_ar.cc | 4 +- src/task_cc.cc | 4 +- src/task_ld.cc | 8 +++- src/task_so.cc | 4 +- src/tasks.cc | 3 +- src/tools.cc | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/tools.h | 25 ++++++++++++ src/util.cc | 38 ------------------ src/util.h | 2 - test/ctor.cc | 1 + 10 files changed, 166 insertions(+), 46 deletions(-) diff --git a/src/task_ar.cc b/src/task_ar.cc index 88c78c6..b73c6ac 100644 --- a/src/task_ar.cc +++ b/src/task_ar.cc @@ -23,7 +23,10 @@ TaskAR::TaskAR(const ctor::build_configuration& config, { std::filesystem::create_directories(std::filesystem::path(settings.builddir) / sourceDir); + target_type = ctor::target_type::static_library; _targetFile = target; + auto toolchain = getToolChain(config.system); + _targetFile = extension(toolchain, target_type, _targetFile); for(const auto& object : objects) { std::filesystem::path objectFile = object; @@ -39,7 +42,6 @@ TaskAR::TaskAR(const ctor::build_configuration& config, flagsFile = std::filesystem::path(settings.builddir) / cleanUp(sourceDir) / targetFile().stem(); flagsFile += ".flags"; - target_type = ctor::target_type::static_library; source_language = ctor::language::c; for(const auto& source : config.sources) { diff --git a/src/task_cc.cc b/src/task_cc.cc index 56915f5..f16a07f 100644 --- a/src/task_cc.cc +++ b/src/task_cc.cc @@ -56,12 +56,14 @@ TaskCC::TaskCC(const ctor::build_configuration& config, const ctor::settings& se if(source.output.empty()) { _targetFile = base; - _targetFile += ".o"; } else { _targetFile = source.output; } + auto toolchain = getToolChain(config.system); + _targetFile = extension(toolchain, target_type, _targetFile); + depsFile = targetFile().parent_path() / targetFile().stem(); depsFile += ".d"; flagsFile = targetFile().parent_path() / targetFile().stem(); diff --git a/src/task_ld.cc b/src/task_ld.cc index 3d917e4..e619dfd 100644 --- a/src/task_ld.cc +++ b/src/task_ld.cc @@ -30,6 +30,8 @@ TaskLD::TaskLD(const ctor::build_configuration& config, std::filesystem::create_directories(std::filesystem::path(settings.builddir) / sourceDir); _targetFile = target; + auto toolchain = getToolChain(config.system); + _targetFile = extension(toolchain, target_type, _targetFile); for(const auto& object : objects) { std::filesystem::path objectFile = object; @@ -88,14 +90,16 @@ int TaskLD::runInner() for(const auto& dep : getDependsTasks()) { auto depFile = dep->targetFile(); - if(depFile.extension() == ".so") + auto dep_type = target_type_from_extension(toolchain, depFile); + if(dep_type == ctor::target_type::dynamic_library) { append(args, ld_option(toolchain, ctor::ld_opt::library_path, targetFile().parent_path().string())); auto lib = depFile.stem().string().substr(3); // strip 'lib' prefix append(args, ld_option(toolchain, ctor::ld_opt::link, lib)); } - else if(depFile.extension() == ".a" || depFile.extension() == ".o") + else if(dep_type == ctor::target_type::static_library || + dep_type == ctor::target_type::object) { args.push_back(depFile.string()); } diff --git a/src/task_so.cc b/src/task_so.cc index 9061591..9aae7ff 100644 --- a/src/task_so.cc +++ b/src/task_so.cc @@ -24,7 +24,10 @@ TaskSO::TaskSO(const ctor::build_configuration& config, std::filesystem::path base = sourceDir; std::filesystem::create_directories(std::filesystem::path(settings.builddir) / base); + target_type = ctor::target_type::dynamic_library; _targetFile = base / target; + auto toolchain = getToolChain(config.system); + _targetFile = extension(toolchain, target_type, _targetFile); for(const auto& object : objects) { std::filesystem::path objectFile = object; @@ -40,7 +43,6 @@ TaskSO::TaskSO(const ctor::build_configuration& config, flagsFile = std::filesystem::path(settings.builddir) / cleanUp(sourceDir) / targetFile().stem(); flagsFile += ".flags"; - target_type = ctor::target_type::dynamic_library; source_language = ctor::language::c; for(const auto& source : config.sources) { diff --git a/src/tasks.cc b/src/tasks.cc index b44fce8..9c64fb4 100644 --- a/src/tasks.cc +++ b/src/tasks.cc @@ -19,6 +19,7 @@ #include "rebuild.h" #include "configure.h" #include "util.h" +#include "tools.h" const std::deque& getTargets(const ctor::settings& settings, bool resolve_externals) @@ -95,7 +96,7 @@ std::set> taskFactory(const ctor::build_configuration& con } else { - target_type = target_type_from_extension(targetFile); + target_type = target_type_from_extension(ctor::toolchain::any, targetFile); } } 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 +#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 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::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; +} diff --git a/src/tools.h b/src/tools.h index b1285ec..4fb6302 100644 --- a/src/tools.h +++ b/src/tools.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "ctor.h" @@ -94,3 +95,27 @@ std::vector to_strings(ctor::toolchain toolchain, const ctor::ar_flag& flag); std::vector to_strings(ctor::toolchain toolchain, const ctor::asm_flag& flag); + + +// Get target type from file extension +// If toolchain is not ::any only extensions for that toolchain will be accepted +// If no match is found ::unknown will be returned. +ctor::target_type target_type_from_extension(ctor::toolchain toolchain, + const std::filesystem::path& file); + + +// Get appropriate extension from original extension and target type using +// the toolchain. +// ie. { gcc, static_lib, ".lib" } will return ".a" +// { msvc, dynamic_lib, ".dylib" } will return ".dll" +// ... +// If the supplied extension is normal for the supplied type and toolchain, then this is used, otherwise a conversion to the default extension to the given toolchain and type is given. +// The defaults for the toolchains are as follows: +// toolchain executable static-lib dynamic-lib +// gcc (none) .a .so(.dylib on macos) +// clang (none) .a .so(.dylib on macos) +// msvc .exe .lib .dll +// mingw .exe .lib .dll +std::filesystem::path extension(ctor::toolchain toolchain, + ctor::target_type target_type, + const std::filesystem::path& file); diff --git a/src/util.cc b/src/util.cc index 08a135f..fe16471 100644 --- a/src/util.cc +++ b/src/util.cc @@ -6,7 +6,6 @@ #include #include #include -#include std::string to_lower(const std::string& str) { @@ -152,43 +151,6 @@ std::string cleanUp(const std::string& path) return cleaned; } -ctor::target_type target_type_from_extension(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(ext == ".a" || - ext == ".lib") - { - return ctor::target_type::static_library; - } - - if(ext == ".so" || - ext == ".dll" || - ext == ".dylib") - { - return ctor::target_type::dynamic_library; - } - - if(ext == ".o" || - ext == ".obj") - { - return ctor::target_type::object; - } - - if(ext == "" || - ext == ".exe" || - ext == ".com" || - ext == ".bin" || - ext == ".run" || - ext == ".out") - { - return ctor::target_type::executable; - } - - return ctor::target_type::unknown; -} - std::string esc(const std::string& in) { std::string out; diff --git a/src/util.h b/src/util.h index 3ebef41..9fa6be2 100644 --- a/src/util.h +++ b/src/util.h @@ -21,6 +21,4 @@ void append(T& a, const T& b) a.insert(a.end(), b.begin(), b.end()); } -ctor::target_type target_type_from_extension(const std::filesystem::path& file); - std::string esc(const std::string& in); diff --git a/test/ctor.cc b/test/ctor.cc index a2ad64d..3649a10 100644 --- a/test/ctor.cc +++ b/test/ctor.cc @@ -66,6 +66,7 @@ ctor::build_configurations ctorTestConfigs(const ctor::settings& settings) .sources = { "tools_test.cc", "testmain.cc", + "../src/util.cc", "../src/tools.cc", }, //.depends = { "libctor_nomain.a" }, -- cgit v1.2.3