diff options
Diffstat (limited to 'libcppbuild.cc')
-rw-r--r-- | libcppbuild.cc | 184 |
1 files changed, 124 insertions, 60 deletions
diff --git a/libcppbuild.cc b/libcppbuild.cc index bf1a7fa..7f0a355 100644 --- a/libcppbuild.cc +++ b/libcppbuild.cc @@ -7,16 +7,67 @@ #include <chrono> #include <thread> #include <memory> +#include <algorithm> +#include <list> #include "libcppbuild.h" #include "task_cc.h" #include "task_ld.h" +#include "task_ar.h" #include "settings.h" #include <unistd.h> using namespace std::chrono_literals; +std::list<std::shared_ptr<Task>> taskFactory(const BuildConfiguration& config, + const Settings& settings) +{ + 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, file)); + objects.push_back(tasks.back()->target()); + } + + std::filesystem::path targetFile(config.target); + if(targetFile.extension() == ".a") + { + // static lib + tasks.emplace_back(std::make_shared<TaskAR>(config, settings, config.target, + objects)); + } + else + { + // binary + tasks.emplace_back(std::make_shared<TaskLD>(config, settings, config.target, + objects)); + + } + + 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; +} + int main(int argc, const char* argv[]) { Settings settings; @@ -27,84 +78,79 @@ int main(int argc, const char* argv[]) settings.parallel_processes = std::max(1u, std::thread::hardware_concurrency() * 2 - 1); + settings.verbose = 0; + std::filesystem::path builddir(settings.builddir); std::filesystem::create_directories(builddir); auto build_configs = configs(); + std::list<std::shared_ptr<Task>> tasks; for(const auto& build_config : build_configs) { std::vector<std::string> objects; - std::vector<std::unique_ptr<Task>> tasks; - for(const auto& file : build_config.sources) - { - tasks.emplace_back(std::make_unique<TaskCC>(build_config, settings, file)); - objects.push_back(tasks.back()->target()); - } + auto t = taskFactory(build_config, settings); + tasks.insert(tasks.end(), t.begin(), t.end()); + } - TaskLD task_ld(build_config, settings, build_config.target, objects); + for(auto task : tasks) + { + task->registerDepTasks(tasks); + } - if(argc == 2 && std::string(argv[1]) == "clean") + std::list<std::shared_ptr<Task>> dirtyTasks; + for(auto task : tasks) + { + if(task->dirty()) { - std::cout << "Cleaning\n"; - //std::filesystem::remove_all(builddir); - for(auto& task : tasks) - { - if(task->clean() != 0) - { - return 1; - } - } + dirtyTasks.push_back(task); + } + } - if(task_ld.clean() != 0) + if(argc == 2 && std::string(argv[1]) == "clean") + { + std::cout << "Cleaning\n"; + //std::filesystem::remove_all(builddir); + for(auto& task : tasks) + { + if(task->clean() != 0) { return 1; } - - return 0; } - std::cout << "Building\n"; + return 0; + } - std::list<std::future<int>> processes; + std::cout << "Building\n"; + std::list<std::future<int>> processes; - // Start all tasks - auto task = tasks.begin(); - while(task != tasks.end()) + // Start all tasks + bool done{false}; + while(!done) + { + bool started_one{false}; + while(processes.size() < settings.parallel_processes) { - while(processes.size() < settings.parallel_processes && - task != tasks.end()) + if(dirtyTasks.empty()) { - if(!(*task)->dirty()) - { - ++task; - continue; - } - - processes.emplace_back( - std::async(std::launch::async, - [&t = *task]() - { - return t->run(); - })); - ++task; - std::this_thread::sleep_for(2ms); + done = true; + break; } - for(auto process = processes.begin(); - process != processes.end(); - ++process) + auto task = getNextTask(tasks, dirtyTasks); + if(task == nullptr) { - if(process->valid()) - { - if(process->get() != 0) - { - return 1; - } - processes.erase(process); - break; - } + break; + //return 1; } + processes.emplace_back( + std::async(std::launch::async, + [task]() + { + return task->run(); + })); + started_one = true; std::this_thread::sleep_for(2ms); } @@ -112,18 +158,36 @@ int main(int argc, const char* argv[]) process != processes.end(); ++process) { - process->wait(); - auto ret = process->get(); - if(ret != 0) + if(process->valid()) { - return 1; + if(process->get() != 0) + { + return 1; + } + processes.erase(process); + break; } } - std::cout << "Linking\n"; - if(task_ld.dirty()) + if(started_one) + { + std::this_thread::sleep_for(2ms); + } + else + { + std::this_thread::sleep_for(200ms); + } + } + + for(auto process = processes.begin(); + process != processes.end(); + ++process) + { + process->wait(); + auto ret = process->get(); + if(ret != 0) { - return task_ld.run(); + return 1; } } |