#include "task.h" #include #include #include "libcppbuild.h" #include "settings.h" namespace { std::string readFile(const std::string &fileName) { std::ifstream ifs(fileName.c_str(), std::ios::in | std::ios::binary | std::ios::ate); std::ifstream::pos_type fileSize = ifs.tellg(); ifs.seekg(0, std::ios::beg); std::vector bytes(fileSize); ifs.read(bytes.data(), fileSize); return std::string(bytes.data(), fileSize); } std::vector readDeps(const std::string& depFile) { if(!std::filesystem::exists(depFile)) { return {}; } auto str = readFile(depFile); std::vector output; std::string tmp; bool start{false}; bool in_whitespace{false}; for(const auto& c : str) { if(c == '\\' || c == '\n') { continue; } if(c == ':') { start = true; continue; } if(!start) { continue; } if(c == ' ' || c == '\t') { if(in_whitespace) { continue; } if(!tmp.empty()) { output.push_back(tmp); } tmp.clear(); in_whitespace = true; } else { in_whitespace = false; tmp += c; } } if(!tmp.empty()) { output.push_back(tmp); } return output; } } // namespace :: Task::Task(const BuildConfiguration& config, const Settings& settings, const std::string& source) { sourceFile = source; targetFile = settings.builddir / sourceFile.stem(); targetFile += ".o"; depsFile = settings.builddir / sourceFile.stem(); depsFile += ".d"; } void Task::start() { 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 cmd = "g++ -MMD -c " + std::string(sourceFile) + " -o " + std::string(targetFile); std::cout << cmd << "\n"; if(system(cmd.data())) { return 1; } return 0; } return 0; }); } int Task::wait() { future.wait(); return future.get(); } int Task::clean() { if(std::filesystem::exists(targetFile)) { std::cout << "Removing " << std::string(targetFile) << "\n"; std::filesystem::remove(targetFile); } if(std::filesystem::exists(depsFile)) { std::cout << "Removing " << std::string(depsFile) << "\n"; std::filesystem::remove(depsFile); } return 0; } std::vector Task::depends() { return {}; }