X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Flib%2Fsourcegenerator.cpp;fp=source%2Flib%2Fsourcegenerator.cpp;h=d30a2bc67fdefa3687e6c18193b0c9eaae504c7c;hb=c8e829c219c65ff8e93b6c7b66212ff0876441c5;hp=0000000000000000000000000000000000000000;hpb=e2c9c3fffcc61a0c102ccf6a7924e2de709092ad;p=builder.git diff --git a/source/lib/sourcegenerator.cpp b/source/lib/sourcegenerator.cpp new file mode 100644 index 0000000..d30a2bc --- /dev/null +++ b/source/lib/sourcegenerator.cpp @@ -0,0 +1,132 @@ +#include +#include +#include "builder.h" +#include "executable.h" +#include "sourcegenerator.h" +#include "sourcepackage.h" +#include "templatefile.h" + +using namespace std; +using namespace Msp; + +SourceGenerator::SourceGenerator(Builder &b, const SourcePackage &p, const string &t): + Tool(b, t), + package(p) +{ + set_run_external(&_run); +} + +Target *SourceGenerator::create_source(const Component &comp, const FS::Path &path) const +{ + return new TemplateFile(builder, comp, path); +} + +Target *SourceGenerator::create_target(const vector &sources, const string &) +{ + if(sources.empty()) + throw invalid_argument("SourceGenerator::create_target"); + if(out_suffixes.empty()) + throw logic_error("No output suffixes"); + + TemplateFile &tmpl = dynamic_cast(*sources.front()); + const Component *comp = tmpl.get_component(); + const SourcePackage *pkg = tmpl.get_package(); + FS::Path subdir; + string base; + if(processing_unit==COMPONENT) + base = comp->get_name(); + else + { + subdir = FS::dirname(FS::relative(tmpl.get_path(), pkg->get_source_directory())); + if(processing_unit==ONE_FILE) + base = FS::basepart(FS::basename(tmpl.get_path())); + else if(processing_unit==DIRECTORY) + { + base = FS::basename(subdir); + subdir = FS::dirname(subdir); + } + } + + Target *primary = 0; + for(const string &s: out_suffixes) + { + Tool *tool = builder.get_toolchain().get_tool_for_suffix(s, true); + if(tool) + { + FS::Path fn = pkg->get_temp_directory()/"generated"/subdir/(base+s); + Target *target = tool->create_source(*comp, fn); + target->set_tool(*this); + for(Target *t: sources) + target->add_dependency(*t); + if(primary) + primary->add_side_effect(*target); + else + primary = target; + } + else + throw runtime_error("No tool found for suffix "+s); + } + + return primary; +} + +ExternalTask::Arguments SourceGenerator::_run(const SourceFile &out_src, FS::Path &work_dir) +{ + const SourceGenerator &tool = dynamic_cast(*out_src.get_tool()); + + vector args; + args.push_back(tool.get_executable()->get_path().str()); + args.insert(args.end(), tool.arguments.begin(), tool.arguments.end()); + + for(const Target *d: out_src.get_dependencies()) + if(const TemplateFile *tmpl = dynamic_cast(d)) + args.push_back(FS::relative(tmpl->get_path(), work_dir).str()); + + if(!tool.out_argument.empty()) + args.push_back(tool.out_argument); + args.push_back(FS::relative(out_src.get_path(), work_dir).str()); + + return args; +} + + +SourceGenerator::Loader::Loader(SourceGenerator &sg): + DataFile::ObjectLoader(sg), + ConditionalLoader(sg.package, format("%s/%s", sg.package.get_name(), sg.tag)) +{ + add("argument", &Loader::argument); + add("arguments", &Loader::arguments); + add("command", &Loader::command); + add("in_suffix", &Loader::in_suffix); + add("out_argument", &SourceGenerator::out_argument); + add("out_suffix", &Loader::out_suffix); + add("processing_unit", static_cast(&SourceGenerator::processing_unit)); +} + +void SourceGenerator::Loader::argument(const string &a) +{ + obj.arguments.push_back(a); +} + +void SourceGenerator::Loader::arguments(const vector &a) +{ + obj.arguments.insert(obj.arguments.end(), a.begin(), a.end()); +} + +void SourceGenerator::Loader::command(const string &c) +{ + if(c.find('/')!=string::npos) + obj.set_command((obj.package.get_source_directory()/c).str()); + else + obj.set_command(c); +} + +void SourceGenerator::Loader::in_suffix(const string &s) +{ + obj.input_suffixes.push_back(s); +} + +void SourceGenerator::Loader::out_suffix(const string &s) +{ + obj.out_suffixes.push_back(s); +}