diff options
Diffstat (limited to 'src/task_fn.cc')
| -rw-r--r-- | src/task_fn.cc | 187 |
1 files changed, 160 insertions, 27 deletions
diff --git a/src/task_fn.cc b/src/task_fn.cc index ebfdac6..69e36ac 100644 --- a/src/task_fn.cc +++ b/src/task_fn.cc @@ -11,46 +11,129 @@ #include "execute.h" #include "util.h" -TaskFn::TaskFn(const ctor::build_configuration& config_, const ctor::settings& settings_, - const std::string& sourceDir_, const ctor::source& source) +TaskFn::TaskFn(const ctor::build_configuration& config_, + const ctor::settings& settings_, + const std::string& sourceDir_, + const ctor::source& source) : Task(config_, settings_, sourceDir_) - , sourceFile(sourceDir_) , config(config_) , settings(settings_) { - sourceFile /= source.file; - - std::filesystem::create_directories(std::filesystem::path(settings.builddir) / sourceFile.parent_path()); - + std::filesystem::create_directories(std::filesystem::path(settings.builddir) / + sourceDir.parent_path()); target_type = config.type; source_language = source.language; - std::filesystem::path base = sourceFile.parent_path(); - if(source.output.empty()) + if(std::holds_alternative<ctor::GeneratorOneToOne>(config.function)) { - std::cerr << "Missing output file for functional target\n"; - exit(1); + if(source.source_type == ctor::source_type::generated) + { + sourceFile = std::filesystem::path(settings.builddir); + } + sourceFile /= sourceDir / source.file; + + std::filesystem::path base = sourceFile.parent_path(); + + if(source.output.empty()) + { + std::cerr << "Missing target/output file for functional target.\n"; + exit(1); + } + _targetFile = base / source.output; } + else if(std::holds_alternative<ctor::GeneratorManyToOne>(config.function)) + { + for(const auto& src : config.sources) + { + std::filesystem::path _src; + if(src.source_type == ctor::source_type::generated) + { + _src = std::filesystem::path(settings.builddir); + } + _src /= sourceDir / src.file; + sources.push_back(_src.string()); + } - _targetFile = base / source.output; + std::filesystem::path base = sourceDir; + if(config.target.empty()) + { + std::cerr << "Missing target file for functional target\n"; + exit(1); + } + _targetFile = base / config.target; + sourceListFile = targetFile().parent_path() / targetFile().filename(); + sourceListFile += ".sources"; + } } bool TaskFn::dirtyInner() { - if(!std::filesystem::exists(sourceFile)) + if(!std::filesystem::exists(targetFile())) { - //std::cout << "Missing source file: " << std::string(sourceFile) << "\n"; + //std::cout << "Missing targetFile\n"; return true; } - if(!std::filesystem::exists(targetFile())) + if(std::holds_alternative<ctor::GeneratorManyToOne>(config.function)) + { + if(!std::filesystem::exists(sourceListFile)) + { + //std::cout << "Missing sourceListFile\n"; + return true; + } + + { + auto lastSourceList = readFile(sourceListFile.string()); + if(sourceListString() != lastSourceList) + { + //std::cout << "The compiler sourceList changed\n"; + return true; + } + } + } + + std::filesystem::file_time_type last_changed{}; + bool missing{false}; + if(std::holds_alternative<ctor::GeneratorOneToOne>(config.function)) + { + if(!std::filesystem::exists(sourceFile)) + { + missing = true; + } + last_changed = std::filesystem::last_write_time(sourceFile); + } + else if(std::holds_alternative<ctor::GeneratorManyToOne>(config.function)) + { + bool first{true}; + for(const auto& source : sources) + { + if(!std::filesystem::exists(source)) + { + missing |= true; + } + else + { + if(first) + { + last_changed = std::filesystem::last_write_time(source); + } + else + { + last_changed = + std::max(last_changed, + std::filesystem::last_write_time(source)); + } + } + first = false; + } + } + + if(missing) { - //std::cout << "Missing targetFile\n"; return true; } - if(std::filesystem::last_write_time(sourceFile) > - std::filesystem::last_write_time(targetFile())) + if(last_changed > std::filesystem::last_write_time(targetFile())) { //std::cout << "The targetFile older than sourceFile\n"; return true; @@ -61,10 +144,11 @@ bool TaskFn::dirtyInner() int TaskFn::runInner() { - if(!std::filesystem::exists(sourceFile)) + if(std::holds_alternative<ctor::GeneratorManyToOne>(config.function)) { - std::cout << "Missing source file: " << sourceFile.string() << "\n"; - return 1; + // Write sourceList to file. + std::ofstream sourceListStream(sourceListFile.string()); + sourceListStream << sourceListString(); } if(settings.verbose >= 0) @@ -75,10 +159,27 @@ int TaskFn::runInner() std::cout << output << std::flush; } - auto res = config.function(sourceFile.string(), - targetFile().string(), - config, - settings); + int res{}; + if(std::holds_alternative<std::monostate>(config.function)) + { + } + else if(std::holds_alternative<ctor::GeneratorOneToOne>(config.function)) + { + auto func = std::get<ctor::GeneratorOneToOne>(config.function); + res = func(sourceFile.string(), + targetFile().string(), + config, + settings); + } + else if(std::holds_alternative<ctor::GeneratorManyToOne>(config.function)) + { + auto func = std::get<ctor::GeneratorManyToOne>(config.function); + res = func(sources, + targetFile().string(), + config, + settings); + } + if(res != 0) { std::filesystem::remove(targetFile()); @@ -95,12 +196,34 @@ int TaskFn::clean() std::filesystem::remove(targetFile()); } + if(std::holds_alternative<ctor::GeneratorManyToOne>(config.function)) + { + if(std::filesystem::exists(sourceListFile)) + { + std::cout << "Removing " << sourceListFile.string() << "\n"; + std::filesystem::remove(sourceListFile); + } + } + return 0; } std::vector<std::string> TaskFn::depends() const { - return {}; + std::vector<std::string> deps; + if(std::holds_alternative<ctor::GeneratorManyToOne>(config.function)) + { + for(const auto& src : config.sources) + { + if(src.source_type == ctor::source_type::generated) + { + std::filesystem::path _src = std::filesystem::path(settings.builddir); + _src /= src.file; + deps.push_back(_src.string()); + } + } + } + return deps; } std::string TaskFn::target() const @@ -110,7 +233,17 @@ std::string TaskFn::target() const std::filesystem::path TaskFn::targetFile() const { - return std::filesystem::path(settings.builddir) / sourceDir / _targetFile; + return std::filesystem::path(settings.builddir) / _targetFile; +} + +std::string TaskFn::sourceListString() const +{ + std::string sourceListStr; + for(const auto& source : config.sources) + { + sourceListStr += " " + source.file; + } + return sourceListStr; } bool TaskFn::derived() const |
