summaryrefslogtreecommitdiff
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
parenta257c2f4d333969c73d8b27124e658db6430645a (diff)
Make file extensions abstract based on tool-chain type.
-rw-r--r--src/task_ar.cc4
-rw-r--r--src/task_cc.cc4
-rw-r--r--src/task_ld.cc8
-rw-r--r--src/task_so.cc4
-rw-r--r--src/tasks.cc3
-rw-r--r--src/tools.cc123
-rw-r--r--src/tools.h25
-rw-r--r--src/util.cc38
-rw-r--r--src/util.h2
-rw-r--r--test/ctor.cc1
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<Target>& getTargets(const ctor::settings& settings,
bool resolve_externals)
@@ -95,7 +96,7 @@ std::set<std::shared_ptr<Task>> 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 <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;
+}
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 <vector>
#include <string>
#include <ostream>
+#include <filesystem>
#include "ctor.h"
@@ -94,3 +95,27 @@ std::vector<std::string> to_strings(ctor::toolchain toolchain,
const ctor::ar_flag& flag);
std::vector<std::string> 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 <iostream>
#include <fstream>
#include <algorithm>
-#include <cctype>
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" },