diff options
author | Bent Bisballe Nyeng <deva@aasimon.org> | 2024-10-02 21:20:40 +0200 |
---|---|---|
committer | Bent Bisballe Nyeng <deva@aasimon.org> | 2024-10-03 12:06:38 +0200 |
commit | 0008920eed996009068fe9f71512c436577b6220 (patch) | |
tree | 60350de98747a63e1739841b966269f5e312b9ba /src | |
parent | a38c6682e4fb1f45aa1f37d10c2480aa517ea3bc (diff) |
Ensure the initial task order is preserved. Fixes bad ordering during linking.
Diffstat (limited to 'src')
-rw-r--r-- | src/build.cc | 43 | ||||
-rw-r--r-- | src/build.h | 10 | ||||
-rw-r--r-- | src/libctor.cc | 8 | ||||
-rw-r--r-- | src/task.cc | 10 | ||||
-rw-r--r-- | src/task.h | 9 | ||||
-rw-r--r-- | src/task_cc.cc | 8 | ||||
-rw-r--r-- | src/task_cc.h | 2 | ||||
-rw-r--r-- | src/tasks.cc | 43 | ||||
-rw-r--r-- | src/tasks.h | 17 | ||||
-rw-r--r-- | src/unittest.cc | 2 | ||||
-rw-r--r-- | src/unittest.h | 4 |
11 files changed, 86 insertions, 70 deletions
diff --git a/src/build.cc b/src/build.cc index ad30719..ea65656 100644 --- a/src/build.cc +++ b/src/build.cc @@ -4,12 +4,11 @@ #include "build.h" #include <future> -#include <vector> #include <iostream> #include <chrono> -#include <set> #include <thread> #include <list> +#include <algorithm> #include "ctor.h" @@ -17,8 +16,8 @@ using namespace std::chrono_literals; int build(const ctor::settings& settings, const std::string& name, - const std::set<std::shared_ptr<Task>>& tasks, - const std::set<std::shared_ptr<Task>>& all_tasks, + const std::vector<std::shared_ptr<Task>>& tasks, + const std::vector<std::shared_ptr<Task>>& all_tasks, bool dryrun) { if(settings.verbose > 1) @@ -26,12 +25,13 @@ int build(const ctor::settings& settings, std::cout << "Building '" << name << "'\n"; } - std::set<std::shared_ptr<Task>> dirtyTasks; + std::vector<std::shared_ptr<Task>> dirtyTasks; for(auto task : tasks) { - if(task->dirty()) + if(task->dirty() && + std::find(dirtyTasks.begin(), dirtyTasks.end(), task) == dirtyTasks.end()) { - dirtyTasks.insert(task); + dirtyTasks.push_back(task); } } @@ -135,10 +135,10 @@ int build(const ctor::settings& settings, namespace { -std::set<std::shared_ptr<Task>> getDepTasks(std::shared_ptr<Task> task) +std::vector<std::shared_ptr<Task>> getDepTasks(std::shared_ptr<Task> task) { - std::set<std::shared_ptr<Task>> tasks; - tasks.insert(task); + std::vector<std::shared_ptr<Task>> tasks; + tasks.push_back(task); auto deps = task->getDependsTasks(); for(const auto& dep : deps) @@ -146,7 +146,10 @@ std::set<std::shared_ptr<Task>> getDepTasks(std::shared_ptr<Task> task) auto depSet = getDepTasks(dep); for(const auto& dep : depSet) { - tasks.insert(dep); + if(std::find(tasks.begin(), tasks.end(), dep) == tasks.end()) + { + tasks.push_back(dep); + } } } @@ -156,7 +159,7 @@ std::set<std::shared_ptr<Task>> getDepTasks(std::shared_ptr<Task> task) int build(const ctor::settings& settings, const std::string& name, - const std::set<std::shared_ptr<Task>>& all_tasks, + const std::vector<std::shared_ptr<Task>>& all_tasks, bool dryrun) { bool task_found{false}; @@ -167,10 +170,13 @@ int build(const ctor::settings& settings, task_found = true; auto depSet = getDepTasks(task); - std::set<std::shared_ptr<Task>> ts; + std::vector<std::shared_ptr<Task>> ts; for(const auto& task : depSet) { - ts.insert(task); + if(std::find(ts.begin(), ts.end(), task) == ts.end()) + { + ts.push_back(task); + } } auto ret = build(settings, name, ts, all_tasks, dryrun); @@ -195,11 +201,11 @@ int build(const ctor::settings& settings, int build(const ctor::settings& settings, const std::string& name, const std::vector<Target>& targets, - const std::set<std::shared_ptr<Task>>& all_tasks, + const std::vector<std::shared_ptr<Task>>& all_tasks, bool dryrun) { bool task_found{false}; - std::set<std::shared_ptr<Task>> ts; + std::vector<std::shared_ptr<Task>> ts; for(const auto& target : targets) { @@ -213,7 +219,10 @@ int build(const ctor::settings& settings, auto depSet = getDepTasks(task); for(const auto& task : depSet) { - ts.insert(task); + if(std::find(ts.begin(), ts.end(), task) == ts.end()) + { + ts.push_back(task); + } } } } diff --git a/src/build.h b/src/build.h index d74642c..500fb7f 100644 --- a/src/build.h +++ b/src/build.h @@ -4,7 +4,7 @@ #pragma once #include <string> -#include <set> +#include <vector> #include <memory> #include "task.h" @@ -17,19 +17,19 @@ struct settings; //! Dry-run returns number of dirty tasks but otherwise does nothing. int build(const ctor::settings& settings, const std::string& name, - const std::set<std::shared_ptr<Task>>& tasks, - const std::set<std::shared_ptr<Task>>& all_tasks, + const std::vector<std::shared_ptr<Task>>& tasks, + const std::vector<std::shared_ptr<Task>>& all_tasks, bool dryrun = false); //! Dry-run returns number of dirty tasks but otherwise does nothing. int build(const ctor::settings& settings, const std::string& name, - const std::set<std::shared_ptr<Task>>& all_tasks, + const std::vector<std::shared_ptr<Task>>& all_tasks, bool dryrun = false); //! Dry-run returns number of dirty tasks but otherwise does nothing. int build(const ctor::settings& settings, const std::string& name, const std::vector<Target>& targets, - const std::set<std::shared_ptr<Task>>& all_tasks, + const std::vector<std::shared_ptr<Task>>& all_tasks, bool dryrun = false); diff --git a/src/libctor.cc b/src/libctor.cc index 21792e1..3eb6c6f 100644 --- a/src/libctor.cc +++ b/src/libctor.cc @@ -15,7 +15,6 @@ #include <deque> #include <fstream> #include <cstdlib> -#include <set> #include <getoptpp/getoptpp.hpp> @@ -185,17 +184,18 @@ Options: if(list_files) { no_default_build = true; - std::set<std::string> files; + std::vector<std::string> files; for(std::size_t i = 0; i < numConfigFiles; ++i) { - files.insert(configFiles[i].file); + files.push_back(configFiles[i].file); } for(std::size_t i = 0; i < numExternalConfigFiles; ++i) { - files.insert(externalConfigFiles[i].file); + files.push_back(externalConfigFiles[i].file); } + std::sort(files.begin(), files.end()); for(const auto& file : files) { std::cout << file << "\n"; diff --git a/src/task.cc b/src/task.cc index 817ee3a..7813235 100644 --- a/src/task.cc +++ b/src/task.cc @@ -5,6 +5,7 @@ #include <unistd.h> #include <iostream> +#include <algorithm> Task::Task(const ctor::build_configuration& config, const ctor::settings& settings, const std::string& sourceDir) @@ -15,7 +16,7 @@ Task::Task(const ctor::build_configuration& config, const ctor::settings& settin { } -int Task::registerDepTasks(const std::set<std::shared_ptr<Task>>& tasks) +int Task::registerDepTasks(const std::vector<std::shared_ptr<Task>>& tasks) { for(const auto& depStr : depends()) { @@ -24,7 +25,10 @@ int Task::registerDepTasks(const std::set<std::shared_ptr<Task>>& tasks) { if(*task == depStr) { - dependsTasks.insert(task); + if(std::find(dependsTasks.begin(), dependsTasks.end(), task) == dependsTasks.end()) + { + dependsTasks.push_back(task); + } found = true; } } @@ -155,7 +159,7 @@ std::string Task::compiler() const } } -std::set<std::shared_ptr<Task>> Task::getDependsTasks() +std::vector<std::shared_ptr<Task>> Task::getDependsTasks() { return dependsTasks; } @@ -6,7 +6,6 @@ #include <vector> #include <string> #include <atomic> -#include <set> #include <memory> #include <filesystem> @@ -28,8 +27,8 @@ public: const std::string& sourceDir); virtual ~Task() = default; - int registerDepTasks(const std::set<std::shared_ptr<Task>>& tasks); - virtual int registerDepTasksInner(const std::set<std::shared_ptr<Task>>& tasks) { return 0; } + int registerDepTasks(const std::vector<std::shared_ptr<Task>>& tasks); + virtual int registerDepTasksInner(const std::vector<std::shared_ptr<Task>>& tasks) { return 0; } bool operator==(const std::string& dep); @@ -64,7 +63,7 @@ public: ctor::output_system outputSystem() const; std::string compiler() const; - std::set<std::shared_ptr<Task>> getDependsTasks(); + std::vector<std::shared_ptr<Task>> getDependsTasks(); virtual std::string source() const { return {}; } @@ -74,7 +73,7 @@ protected: virtual bool dirtyInner() { return false; } std::vector<std::string> dependsStr; - std::set<std::shared_ptr<Task>> dependsTasks; + std::vector<std::shared_ptr<Task>> dependsTasks; const ctor::build_configuration& config; ctor::target_type target_type{ctor::target_type::automatic}; ctor::language source_language{ctor::language::automatic}; diff --git a/src/task_cc.cc b/src/task_cc.cc index 294c5ea..4eb07ae 100644 --- a/src/task_cc.cc +++ b/src/task_cc.cc @@ -6,6 +6,7 @@ #include <iostream> #include <fstream> #include <cassert> +#include <algorithm> #include "ctor.h" #include "execute.h" @@ -72,13 +73,16 @@ TaskCC::TaskCC(const ctor::build_configuration& config, const ctor::settings& se std::filesystem::create_directories(targetFile().parent_path()); } -int TaskCC::registerDepTasksInner(const std::set<std::shared_ptr<Task>>& tasks) +int TaskCC::registerDepTasksInner(const std::vector<std::shared_ptr<Task>>& tasks) { for(const auto& task : tasks) { if(*task == _source.file) { - dependsTasks.insert(task); + if(std::find(dependsTasks.begin(), dependsTasks.end(), task) == dependsTasks.end()) + { + dependsTasks.push_back(task); + } } } diff --git a/src/task_cc.h b/src/task_cc.h index 70bb13c..6c4683a 100644 --- a/src/task_cc.h +++ b/src/task_cc.h @@ -19,7 +19,7 @@ public: const std::string& sourceDir, const ctor::source& source); virtual ~TaskCC() = default; - int registerDepTasksInner(const std::set<std::shared_ptr<Task>>& tasks) override; + int registerDepTasksInner(const std::vector<std::shared_ptr<Task>>& tasks) override; std::string name() const override; bool dirtyInner() override; diff --git a/src/tasks.cc b/src/tasks.cc index 22ad2d6..61c130b 100644 --- a/src/tasks.cc +++ b/src/tasks.cc @@ -70,11 +70,11 @@ const std::deque<Target>& getTargets(const ctor::settings& settings, return targets; } -std::set<std::shared_ptr<Task>> taskFactory(const ctor::build_configuration& config, - const ctor::settings& settings, - const std::string& sourceDir) +std::vector<std::shared_ptr<Task>> taskFactory(const ctor::build_configuration& config, + const ctor::settings& settings, + const std::string& sourceDir) { - std::set<std::shared_ptr<Task>> tasks; + std::vector<std::shared_ptr<Task>> tasks; std::filesystem::path targetFile(config.target); @@ -97,7 +97,7 @@ std::set<std::shared_ptr<Task>> taskFactory(const ctor::build_configuration& con for(const auto& file : config.sources) { auto task = std::make_shared<TaskCC>(config, settings, sourceDir, file); - tasks.insert(task); + tasks.push_back(task); objects.push_back(task->targetFile().string()); } } @@ -107,7 +107,7 @@ std::set<std::shared_ptr<Task>> taskFactory(const ctor::build_configuration& con for(const auto& file : config.sources) { auto task = std::make_shared<TaskFn>(config, settings, sourceDir, file); - tasks.insert(task); + tasks.push_back(task); objects.push_back(task->target()); } } @@ -127,8 +127,8 @@ std::set<std::shared_ptr<Task>> taskFactory(const ctor::build_configuration& con case ctor::target_type::static_library: case ctor::target_type::unit_test_library: - tasks.insert(std::make_shared<TaskAR>(config, settings, config.target, - objects, sourceDir)); + tasks.push_back(std::make_shared<TaskAR>(config, settings, config.target, + objects, sourceDir)); break; #ifndef BOOTSTRAP case ctor::target_type::dynamic_library: @@ -138,14 +138,14 @@ std::set<std::shared_ptr<Task>> taskFactory(const ctor::build_configuration& con std::cerr << "Dynamic library target must have 'lib' prefix\n"; exit(1); } - tasks.insert(std::make_shared<TaskSO>(config, settings, config.target, - objects, sourceDir)); + tasks.push_back(std::make_shared<TaskSO>(config, settings, config.target, + objects, sourceDir)); break; case ctor::target_type::executable: case ctor::target_type::unit_test: - tasks.insert(std::make_shared<TaskLD>(config, settings, config.target, - objects, sourceDir)); + tasks.push_back(std::make_shared<TaskLD>(config, settings, config.target, + objects, sourceDir)); break; case ctor::target_type::object: @@ -160,18 +160,19 @@ std::set<std::shared_ptr<Task>> taskFactory(const ctor::build_configuration& con return tasks; } -std::shared_ptr<Task> getNextTask(const std::set<std::shared_ptr<Task>>& allTasks, - std::set<std::shared_ptr<Task>>& dirtyTasks) +std::shared_ptr<Task> getNextTask(const std::vector<std::shared_ptr<Task>>& allTasks, + std::vector<std::shared_ptr<Task>>& dirtyTasks) { for(auto dirtyTask = dirtyTasks.begin(); dirtyTask != dirtyTasks.end(); ++dirtyTask) { + auto task = *dirtyTask; //std::cout << "Examining target " << (*dirtyTask)->target() << "\n"; - if((*dirtyTask)->ready()) + if(task->ready()) { dirtyTasks.erase(dirtyTask); - return *dirtyTask; + return task; } } @@ -179,12 +180,12 @@ std::shared_ptr<Task> getNextTask(const std::set<std::shared_ptr<Task>>& allTask return nullptr; } -std::set<std::shared_ptr<Task>> getTasks(const ctor::settings& settings, - const std::vector<std::string> names, - bool resolve_externals) +std::vector<std::shared_ptr<Task>> getTasks(const ctor::settings& settings, + const std::vector<std::string> names, + bool resolve_externals) { auto& targets = getTargets(settings, resolve_externals); - std::set<std::shared_ptr<Task>> tasks; + std::vector<std::shared_ptr<Task>> tasks; for(const auto& target : targets) { if(names.empty() || @@ -192,7 +193,7 @@ std::set<std::shared_ptr<Task>> getTasks(const ctor::settings& settings, { std::vector<std::string> objects; auto t = taskFactory(target.config, settings, target.path); - tasks.insert(t.begin(), t.end()); + tasks.insert(tasks.end(), t.begin(), t.end()); } } diff --git a/src/tasks.h b/src/tasks.h index ed1bf60..cc34f56 100644 --- a/src/tasks.h +++ b/src/tasks.h @@ -4,7 +4,6 @@ #pragma once #include <string> -#include <set> #include <memory> #include <deque> @@ -24,17 +23,17 @@ const std::deque<Target>& getTargets(const ctor::settings& settings, //! fulfilled. //! The returned task is removed from the dirty list. //! Return nullptr if no dirty task is ready. -std::shared_ptr<Task> getNextTask(const std::set<std::shared_ptr<Task>>& allTasks, - std::set<std::shared_ptr<Task>>& dirtyTasks); +std::shared_ptr<Task> getNextTask(const std::vector<std::shared_ptr<Task>>& allTasks, + std::vector<std::shared_ptr<Task>>& dirtyTasks); //! Get list of tasks filtered by name including each of their direct //! dependency tasks (ie. objects tasks from their sources). -std::set<std::shared_ptr<Task>> getTasks(const ctor::settings& settings, - const std::vector<std::string> names = {}, - bool resolve_externals = true); +std::vector<std::shared_ptr<Task>> getTasks(const ctor::settings& settings, + const std::vector<std::string> names = {}, + bool resolve_externals = true); //! Generate list of targets from a single configuration, including the final //! link target and all its objects files (if any). -std::set<std::shared_ptr<Task>> taskFactory(const ctor::build_configuration& config, - const ctor::settings& settings, - const std::string& sourceDir); +std::vector<std::shared_ptr<Task>> taskFactory(const ctor::build_configuration& config, + const ctor::settings& settings, + const std::string& sourceDir); diff --git a/src/unittest.cc b/src/unittest.cc index 1e32878..9e85187 100644 --- a/src/unittest.cc +++ b/src/unittest.cc @@ -8,7 +8,7 @@ #include "execute.h" #include "task.h" -int runUnitTests(std::set<std::shared_ptr<Task>>& tasks, +int runUnitTests(std::vector<std::shared_ptr<Task>>& tasks, const ctor::settings& settings) { bool ok{true}; diff --git a/src/unittest.h b/src/unittest.h index 2880319..6d1385e 100644 --- a/src/unittest.h +++ b/src/unittest.h @@ -3,7 +3,7 @@ // See accompanying file LICENSE for details. #pragma once -#include <set> +#include <vector> #include <memory> class Task; @@ -12,5 +12,5 @@ namespace ctor { struct settings; } // namespace ctor:: -int runUnitTests(std::set<std::shared_ptr<Task>>& tasks, +int runUnitTests(std::vector<std::shared_ptr<Task>>& tasks, const ctor::settings& settings); |