diff options
Diffstat (limited to 'task.cc')
-rw-r--r-- | task.cc | 199 |
1 files changed, 199 insertions, 0 deletions
@@ -0,0 +1,199 @@ +#include "task.h" + +#include <iostream> +#include <fstream> + +#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<char> bytes(fileSize); + ifs.read(bytes.data(), fileSize); + + return std::string(bytes.data(), fileSize); +} + +std::vector<std::string> readDeps(const std::string& depFile) +{ + if(!std::filesystem::exists(depFile)) + { + return {}; + } + + auto str = readFile(depFile); + + std::vector<std::string> 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<std::string> Task::depends() +{ + return {}; +} |