]> git.tdb.fi Git - builder.git/commitdiff
Support source generators that combine multiple files into one
authorMikko Rasa <tdb@tdb.fi>
Fri, 18 Nov 2016 21:06:20 +0000 (23:06 +0200)
committerMikko Rasa <tdb@tdb.fi>
Fri, 18 Nov 2016 21:06:20 +0000 (23:06 +0200)
Some existing tools have processing unit annotations too, but for some of
them it's not clear what the unit should be.

source/binarycomponent.cpp
source/gnuarchiver.cpp
source/gnulinker.cpp
source/sourcegenerator.cpp
source/tar.cpp
source/tool.cpp
source/tool.h

index 565e8bc1759ad6fb3bffdda89e3626fbde021012..74ac0baf5c550ce3a349581da8a730d52a64d054 100644 (file)
@@ -64,12 +64,30 @@ void BinaryComponent::create_targets() const
                Tool *gen = pkg_tools.get_tool_for_suffix(ext);
                if(gen)
                {
-                       Target *tmpl = gen->create_source(*this, *i);
-                       if(tmpl)
+                       list<Target *> templates;
+                       templates.push_back(gen->create_source(*this, *i));
+
+                       Tool::ProcessingUnit processing_unit = gen->get_processing_unit();
+                       if(processing_unit!=Tool::ONE_FILE)
                        {
-                               src = gen->create_target(*tmpl);
-                               ext = FS::extpart(FS::basename(dynamic_cast<FileTarget &>(*src).get_path()));
+                               FS::Path source_dir = FS::dirname(*i);
+                               SourceList::const_iterator j = i;
+                               for(++j; j!=source_filenames.end(); )
+                               {
+                                       if((processing_unit!=Tool::DIRECTORY || FS::dirname(*j)==source_dir) &&
+                                               pkg_tools.get_tool_for_suffix(FS::extpart(FS::basename(*j)))==gen)
+                                       {
+                                               templates.push_back(gen->create_source(*this, *j));
+                                               // Remove additional files so they won't get processed again
+                                               source_filenames.erase(j++);
+                                       }
+                                       else
+                                               ++j;
+                               }
                        }
+
+                       src = gen->create_target(templates);
+                       ext = FS::extpart(FS::basename(dynamic_cast<FileTarget &>(*src).get_path()));
                }
 
                Tool *tool = toolchain.get_tool_for_suffix(ext, true);
index 158a4d4fee9f70c359d4e22ea1c6255aa82c098f..170007028a5201f26bf64160402a2bab3f8bebd7 100644 (file)
@@ -18,6 +18,7 @@ GnuArchiver::GnuArchiver(Builder &b, const Architecture &a):
 {
        set_command("ar", true);
        input_suffixes.push_back(".o");
+       processing_unit = COMPONENT;
 }
 
 Target *GnuArchiver::create_target(const list<Target *> &sources, const string &)
index 1b969b4c06882755926da76c57ec83e73144fddf..cc0a50d3ace1ef23db89835b4ad240bce64e4956 100644 (file)
@@ -27,6 +27,8 @@ GnuLinker::GnuLinker(Builder &b, const Architecture &a, const FS::Path &sysroot)
        input_suffixes.push_back(".o");
        input_suffixes.push_back(".a");
 
+       processing_unit = COMPONENT;
+
        if(!sysroot.empty())
        {
                build_info.sysroot = sysroot;
index f00b26bc8a5dc06bf1dddf2d0e79ac89ed171389..192ae289584b186461bd1442cbe1ce800391c7af 100644 (file)
@@ -22,7 +22,7 @@ Target *SourceGenerator::create_source(const Component &comp, const FS::Path &pa
 
 Target *SourceGenerator::create_target(const list<Target *> &sources, const string &)
 {
-       if(sources.size()!=1)
+       if(sources.empty())
                throw invalid_argument("SourceGenerator::create_target");
        if(out_suffixes.empty())
                throw logic_error("No output suffixes");
@@ -30,7 +30,13 @@ Target *SourceGenerator::create_target(const list<Target *> &sources, const stri
        TemplateFile &tmpl = dynamic_cast<TemplateFile &>(*sources.front());
        const Component *comp = tmpl.get_component();
        const SourcePackage *pkg = tmpl.get_package();
-       string base = FS::basepart(FS::basename(tmpl.get_path()));
+       string base;
+       if(processing_unit==ONE_FILE)
+               base = FS::basepart(FS::basename(tmpl.get_path()));
+       else if(processing_unit==DIRECTORY)
+               base = FS::basename(FS::dirname(tmpl.get_path()));
+       else
+               base = comp->get_name();
 
        Target *primary = 0;
        for(list<string>::const_iterator i=out_suffixes.begin(); i!=out_suffixes.end(); ++i)
@@ -41,7 +47,8 @@ Target *SourceGenerator::create_target(const list<Target *> &sources, const stri
                        FS::Path fn = pkg->get_temp_directory()/comp->get_name()/(base+*i);
                        Target *target = tool->create_source(*comp, fn);
                        target->set_tool(*this);
-                       target->add_dependency(tmpl);
+                       for(list<Target *>::const_iterator j=sources.begin(); j!=sources.end(); ++j)
+                               target->add_dependency(**j);
                        if(primary)
                                primary->add_side_effect(*target);
                        else
@@ -82,6 +89,7 @@ SourceGenerator::Loader::Loader(SourceGenerator &sg):
        add("command",    &Loader::command);
        add("in_suffix",  &Loader::in_suffix);
        add("out_suffix", &Loader::out_suffix);
+       add("processing_unit", static_cast<ProcessingUnit SourceGenerator::*>(&SourceGenerator::processing_unit));
 }
 
 void SourceGenerator::Loader::argument(const string &a)
index bcaa85272c5a7e6c24c97249e65fa29162a6a426..6dee843df7ef4de8bee1baae45509a7fb2f34699 100644 (file)
@@ -13,7 +13,9 @@ using namespace Msp;
 
 Tar::Tar(Builder &b):
        Tool(b, "TAR")
-{ }
+{
+       processing_unit = COMPONENT;
+}
 
 Target *Tar::create_target(const list<Target *> &sources, const string &arg)
 {
index 3aa2db3c713716ba7d90bcafa715afe368a37302..e2afe79a204ccea8aebda5294c0dc8a0fd3f583e 100644 (file)
@@ -12,6 +12,7 @@ Tool::Tool(Builder &b, const string &t):
        architecture(0),
        tag(t),
        executable(0),
+       processing_unit(ONE_FILE),
        prepared(false)
 { }
 
@@ -20,6 +21,7 @@ Tool::Tool(Builder &b, const Architecture &a, const string &t):
        architecture(&a),
        tag(t),
        executable(0),
+       processing_unit(ONE_FILE),
        prepared(false)
 { }
 
@@ -71,3 +73,17 @@ SubTool::SubTool(Tool &p):
        Tool(p),
        parent(p)
 { }
+
+
+void operator>>(const LexicalConverter &conv, Tool::ProcessingUnit &unit)
+{
+       const string &str = conv.get();
+       if(str=="FILE")
+               unit = Tool::ONE_FILE;
+       else if(str=="DIRECTORY")
+               unit = Tool::DIRECTORY;
+       else if(str=="COMPONENT")
+               unit = Tool::COMPONENT;
+       else
+               throw lexical_error(format("conversion of '%s' to ProcessingUnit", str));
+}
index ad89e47431b3b47eee53c8d7a747ef98cce2707c..2f8c25b4f56aedc10a45090215995c64f5ba7410 100644 (file)
@@ -21,6 +21,13 @@ Examples include compilers and linkers.
 class Tool
 {
 public:
+       enum ProcessingUnit
+       {
+               ONE_FILE,
+               DIRECTORY,
+               COMPONENT
+       };
+
        typedef std::list<Msp::FS::Path> SearchPath;
        typedef std::list<std::string> SuffixList;
 
@@ -32,6 +39,7 @@ protected:
        FileTarget *executable;
        SuffixList input_suffixes;
        SuffixList aux_suffixes;
+       ProcessingUnit processing_unit;
        SearchPath system_path;
        BuildInfo build_info;
        bool prepared;
@@ -70,6 +78,9 @@ public:
        auxiliary suffixes are considered as well */
        bool accepts_suffix(const std::string &, bool aux = false) const;
 
+       /** Returns the grouping unit this tool prefers to process. */
+       ProcessingUnit get_processing_unit() const { return processing_unit; }
+
        /// Returns the systemwide search path for source files.
        const SearchPath &get_system_path() const { return system_path; }
 
@@ -125,4 +136,7 @@ protected:
        SubTool(Tool &);
 };
 
+
+void operator>>(const Msp::LexicalConverter &, Tool::ProcessingUnit &);
+
 #endif