#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) : config(config) , settings(settings) { sourceFile = source; targetFile = settings.builddir / sourceFile.stem(); targetFile += ".o"; depsFile = settings.builddir / sourceFile.stem(); depsFile += ".d"; } bool Task::dirty() { if(!std::filesystem::exists(sourceFile)) { //std::cout << "Missing source file: " << std::string(sourceFile) << "\n"; return true; } if(!std::filesystem::exists(targetFile)) { //std::cout << "Missing targetFile\n"; return true; } if(!std::filesystem::exists(depsFile)) { //std::cout << "Missing depsFile\n"; return true; } if(std::filesystem::last_write_time(sourceFile) > std::filesystem::last_write_time(depsFile)) { //std::cout << "The sourceFile newer than depsFile\n"; return true; } 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)) { //std::cout << "The targetFile older than " << std::string(dep) << "\n"; return true; } } if(std::filesystem::last_write_time(sourceFile) > std::filesystem::last_write_time(targetFile)) { //std::cout << "The targetFile older than sourceFile\n"; return true; } return false; } int Task::run() { if(!std::filesystem::exists(sourceFile)) { std::cout << "Missing source file: " << std::string(sourceFile) << "\n"; return 1; } 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; } 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() const { return {}; } std::string Task::target() const { return targetFile; }