summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cppbuild.cc3
-rw-r--r--libcppbuild.cc54
-rw-r--r--settings.h3
-rw-r--r--task.cc165
-rw-r--r--task.h7
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;
}
diff --git a/settings.h b/settings.h
index 302c6d7..f60a53b 100644
--- a/settings.h
+++ b/settings.h
@@ -1,7 +1,10 @@
// -*- c++ -*-
#pragma once
+#include <cstddef>
+
struct Settings
{
std::string builddir;
+ std::size_t parallel_processes;
};
diff --git a/task.cc b/task.cc
index 4dcbbd8..4728a1c 100644
--- a/task.cc
+++ b/task.cc
@@ -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()
diff --git a/task.h b/task.h
index ac56e8a..ee67b5c 100644
--- a/task.h
+++ b/task.h
@@ -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;
};