summaryrefslogtreecommitdiff
path: root/src/tasks.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/tasks.cc')
-rw-r--r--src/tasks.cc130
1 files changed, 130 insertions, 0 deletions
diff --git a/src/tasks.cc b/src/tasks.cc
new file mode 100644
index 0000000..93e5a8b
--- /dev/null
+++ b/src/tasks.cc
@@ -0,0 +1,130 @@
+#include "tasks.h"
+
+#include <filesystem>
+#include <deque>
+#include <iostream>
+
+#include "settings.h"
+#include "libcppbuild.h"
+#include "task.h"
+#include "task_cc.h"
+#include "task_ld.h"
+#include "task_ar.h"
+#include "task_so.h"
+#include "rebuild.h"
+
+std::list<std::shared_ptr<Task>> taskFactory(const BuildConfiguration& config,
+ const Settings& settings,
+ const std::string& sourceDir)
+{
+ std::filesystem::path targetFile(config.target);
+
+ TargetType target_type{config.type};
+ if(target_type == TargetType::Auto)
+ {
+ if(targetFile.extension() == ".a")
+ {
+ target_type = TargetType::StaticLibrary;
+ }
+ else if(targetFile.extension() == ".so")
+ {
+ target_type = TargetType::DynamicLibrary;
+ }
+ else if(targetFile.extension() == "")
+ {
+ target_type = TargetType::Executable;
+ }
+ else
+ {
+ std::cerr << "Could not deduce target type from target " <<
+ targetFile.string() << " please specify.\n";
+ exit(1);
+ }
+ }
+
+ std::vector<std::string> objects;
+ std::list<std::shared_ptr<Task>> tasks;
+ for(const auto& file : config.sources)
+ {
+ tasks.emplace_back(std::make_shared<TaskCC>(config, settings,
+ sourceDir, file));
+ objects.push_back(tasks.back()->target());
+ }
+
+ switch(target_type)
+ {
+ case TargetType::Auto:
+ // The target_type cannot be Auto
+ break;
+
+ case TargetType::StaticLibrary:
+ tasks.emplace_back(std::make_shared<TaskAR>(config, settings, config.target,
+ objects));
+ break;
+
+ case TargetType::DynamicLibrary:
+ if(targetFile.stem().string().substr(0, 3) != "lib")
+ {
+ std::cerr << "Dynamic library target must have 'lib' prefix\n";
+ exit(1);
+ }
+ tasks.emplace_back(std::make_shared<TaskSO>(config, settings, config.target,
+ objects));
+ break;
+
+ case TargetType::Executable:
+ tasks.emplace_back(std::make_shared<TaskLD>(config, settings, config.target,
+ objects));
+ break;
+
+ case TargetType::Object:
+ break;
+ }
+
+ return tasks;
+}
+
+std::shared_ptr<Task> getNextTask(const std::list<std::shared_ptr<Task>>& allTasks,
+ std::list<std::shared_ptr<Task>>& dirtyTasks)
+{
+ for(auto dirtyTask = dirtyTasks.begin();
+ dirtyTask != dirtyTasks.end();
+ ++dirtyTask)
+ {
+ //std::cout << "Examining target " << (*dirtyTask)->target() << "\n";
+ if((*dirtyTask)->ready())
+ {
+ dirtyTasks.erase(dirtyTask);
+ return *dirtyTask;
+ }
+ }
+
+ //std::cout << "No task ready ... \n";
+ return nullptr;
+}
+
+std::list<std::shared_ptr<Task>> getTasks(const Settings& settings)
+{
+ static std::deque<BuildConfiguration> build_configs;
+ std::list<std::shared_ptr<Task>> tasks;
+ for(std::size_t i = 0; i < numConfigFiles; ++i)
+ {
+ std::string path =
+ std::filesystem::path(configFiles[i].file).parent_path().string();
+ if(settings.verbose > 1)
+ {
+ std::cout << configFiles[i].file << " in path " << path << "\n";
+ }
+ auto configs = configFiles[i].cb();
+ for(const auto& config : configs)
+ {
+ build_configs.push_back(config);
+ const auto& build_config = build_configs.back();
+ std::vector<std::string> objects;
+ auto t = taskFactory(build_config, settings, path);
+ tasks.insert(tasks.end(), t.begin(), t.end());
+ }
+ }
+
+ return tasks;
+}