#include #include #include #include #include #include #include #include #include #include "libcppbuild.h" #include "task_cc.h" #include "task_ld.h" #include "settings.h" #include using namespace std::chrono_literals; int main(int argc, const char* argv[]) { Settings settings; // TODO: Set from commandline settings.builddir = "build/foo"; settings.parallel_processes = std::max(1u, std::thread::hardware_concurrency() * 2 - 1); std::filesystem::path builddir(settings.builddir); std::filesystem::create_directories(builddir); auto build_configs = configs(); for(const auto& build_config : build_configs) { std::vector objects; std::vector> tasks; for(const auto& file : build_config.sources) { tasks.emplace_back(std::make_unique(build_config, settings, file)); objects.push_back(tasks.back()->target()); } TaskLD task_ld(build_config, settings, build_config.target, objects); 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; } } if(task_ld.clean() != 0) { return 1; } return 0; } std::cout << "Building\n"; std::list> processes; // Start all tasks auto task = tasks.begin(); while(task != tasks.end()) { while(processes.size() < settings.parallel_processes && task != tasks.end()) { 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); } 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(2ms); } for(auto process = processes.begin(); process != processes.end(); ++process) { process->wait(); auto ret = process->get(); if(ret != 0) { return 1; } } std::cout << "Linking\n"; if(task_ld.dirty()) { return task_ld.run(); } } return 0; }