diff options
-rw-r--r-- | cppbuild.cc | 3 | ||||
-rw-r--r-- | libcppbuild.cc | 54 | ||||
-rw-r--r-- | settings.h | 3 | ||||
-rw-r--r-- | task.cc | 165 | ||||
-rw-r--r-- | task.h | 7 |
5 files changed, 132 insertions, 100 deletions
diff --git a/cppbuild.cc b/cppbuild.cc index d7c0537..77ed1f3 100644 --- a/cppbuild.cc +++ b/cppbuild.cc @@ -1,5 +1,6 @@ #if 0 -if [ "cppbuild" -ot "$0" ]; then +if [ "cppbuild" -ot "$0" ] +then echo "Rebuilding cppbuild" g++ -std=c++17 -pthread $0 libcppbuild.a -o cppbuild [ $? != 0 ] && exit 1 diff --git a/libcppbuild.cc b/libcppbuild.cc index 35eff8f..3cba49f 100644 --- a/libcppbuild.cc +++ b/libcppbuild.cc @@ -3,11 +3,18 @@ #include <filesystem> #include <iostream> #include <utility> +#include <list> +#include <chrono> +#include <thread> #include "libcppbuild.h" #include "task.h" #include "settings.h" +#include <unistd.h> + +using namespace std::chrono_literals; + int main(int argc, const char* argv[]) { Settings settings; @@ -15,6 +22,9 @@ int main(int argc, const char* argv[]) // TODO: Set from commandline settings.builddir = "build/foo"; + settings.parallel_processes = + std::max(1u, std::thread::hardware_concurrency() * 3); + std::filesystem::path builddir(settings.builddir); std::filesystem::create_directories(builddir); @@ -49,16 +59,50 @@ int main(int argc, const char* argv[]) } std::cout << "Building\n"; + + std::list<std::future<int>> processes; + // Start all tasks - for(auto& task : tasks) + auto task = tasks.begin(); + while(task != tasks.end()) { - task.start(); + while(processes.size() < settings.parallel_processes && + task != tasks.end()) + { + processes.emplace_back( + std::async(std::launch::async, + [task]() + { + return task->run(); + })); + ++task; + std::this_thread::sleep_for(10ms); + } + + for(auto process = processes.begin(); + process != processes.end(); + ++process) + { + if(process->valid()) + { + if(process->get() != 0) + { + return 1; + } + processes.erase(process); + break; + } + } + + std::this_thread::sleep_for(10ms); } - // Wait for all tasks - for(auto& task : tasks) + for(auto process = processes.begin(); + process != processes.end(); + ++process) { - if(task.wait() != 0) + process->wait(); + if(process->get() != 0) { return 1; } @@ -1,7 +1,10 @@ // -*- c++ -*- #pragma once +#include <cstddef> + struct Settings { std::string builddir; + std::size_t parallel_processes; }; @@ -94,96 +94,85 @@ Task::Task(const BuildConfiguration& config, const Settings& settings, depsFile += ".d"; } -void Task::start() +int Task::run() { - future = - std::async(std::launch::async, - [&]() - { - if(!std::filesystem::exists(sourceFile)) - { - std::cout << "Missing source file: " << std::string(sourceFile) << "\n"; - return 1; - } - - bool recompile{false}; - - if(!recompile && - !std::filesystem::exists(targetFile)) - { - recompile = true; - std::cout << "Missing targetFile\n"; - } - - if(!recompile && - !std::filesystem::exists(depsFile)) - { - recompile = true; - std::cout << "Missing depsFile\n"; - } - - if(!recompile && - std::filesystem::last_write_time(sourceFile) > - std::filesystem::last_write_time(depsFile)) - { - recompile = true; - std::cout << "The sourceFile newer than depsFile\n"; - } - - if(!recompile) - { - auto depList = readDeps(depsFile); - for(const auto& dep : depList) - { - if(!std::filesystem::exists(dep) || - std::filesystem::last_write_time(targetFile) < - std::filesystem::last_write_time(dep)) - { - recompile = true; - std::cout << "The targetFile older than dep\n"; - break; - } - } - } - - if(!recompile && - std::filesystem::last_write_time(sourceFile) > - std::filesystem::last_write_time(targetFile)) - { - recompile = true; - std::cout << "The targetFile older than sourceFile\n"; - } - - if(recompile) - { - std::string comp = "g++"; - std::string flags = config.cxxflags; - if(std::string(sourceFile.extension()) == ".c") - { - comp = "gcc"; - flags = config.cflags; - } - std::string cmd = comp + - " -MMD -c " + std::string(sourceFile) + " " + - flags + " " + - "-o " + std::string(targetFile); - std::cout << cmd << "\n"; - - if(system(cmd.data())) - { - return 1; - } - return 0; - } - - return 0; - }); -} + if(!std::filesystem::exists(sourceFile)) + { + std::cout << "Missing source file: " << std::string(sourceFile) << "\n"; + return 1; + } -int Task::wait() -{ - future.wait(); - return future.get(); + bool recompile{false}; + + if(!recompile && + !std::filesystem::exists(targetFile)) + { + recompile = true; + //std::cout << "Missing targetFile\n"; + } + + if(!recompile && + !std::filesystem::exists(depsFile)) + { + recompile = true; + //std::cout << "Missing depsFile\n"; + } + + if(!recompile && + std::filesystem::last_write_time(sourceFile) > + std::filesystem::last_write_time(depsFile)) + { + recompile = true; + //std::cout << "The sourceFile newer than depsFile\n"; + } + + if(!recompile) + { + auto depList = readDeps(depsFile); + for(const auto& dep : depList) + { + if(!std::filesystem::exists(dep) || + std::filesystem::last_write_time(targetFile) < + std::filesystem::last_write_time(dep)) + { + recompile = true; + //std::cout << "The targetFile older than dep\n"; + break; + } + } + } + + if(!recompile && + std::filesystem::last_write_time(sourceFile) > + std::filesystem::last_write_time(targetFile)) + { + recompile = true; + //std::cout << "The targetFile older than sourceFile\n"; + } + + if(recompile) + { + std::string comp = "g++"; + std::string flags = config.cxxflags; + if(std::string(sourceFile.extension()) == ".c") + { + comp = "gcc"; + flags = config.cflags; + } + std::string cmd = comp + + " -MMD -c " + std::string(sourceFile) + " " + + flags + " " + + "-o " + std::string(targetFile); + std::cout << cmd << "\n"; + + if(system(cmd.data())) + { + return 1; + } + return 0; + } + + return 0; } int Task::clean() @@ -16,10 +16,7 @@ public: const Settings& settings, const std::string& source); - void start(); - - int wait(); - + int run(); int clean(); std::vector<std::string> depends(); @@ -28,8 +25,6 @@ public: std::filesystem::path targetFile; std::filesystem::path depsFile; - std::future<int> future; - const BuildConfiguration& config; const Settings& settings; }; |