]> git.tdb.fi Git - builder.git/blobdiff - source/lib/binarycomponent.cpp
Install headers of non-installed components in a staging directory
[builder.git] / source / lib / binarycomponent.cpp
index 3209ccc185438f721d0892053564724c17fb87fa..c626536a2317622a1ebffdac3a3b6633921f7a0a 100644 (file)
@@ -48,76 +48,78 @@ void BinaryComponent::create_targets() const
        const Toolchain &toolchain = builder.get_toolchain();
        const Toolchain &pkg_tools = package.get_toolchain();
 
+       Tool &linker = toolchain.get_tool("LINK");
+
+       vector<FileTarget *> pending = create_sources();
+
        vector<Target *> objs;
-       vector<FS::Path> source_filenames = collect_source_files();
-       objs.reserve(source_filenames.size());
-       for(auto i=source_filenames.begin(); i!=source_filenames.end(); ++i)
+       while(!pending.empty())
        {
-               string ext = FS::extpart(FS::basename(*i));
-               Target *src = 0;
-
-               Tool *gen = pkg_tools.get_tool_for_suffix(ext);
-               if(gen)
+               Tool *tool = 0;
+               for(auto i=pending.begin(); i!=pending.end(); )
                {
-                       vector<Target *> templates;
-                       templates.push_back(gen->create_source(*this, *i));
+                       string ext = FS::extpart(FS::basename((*i)->get_path()));
+                       if(linker.accepts_suffix(ext))
+                       {
+                               /* Targets accepted by the linker should not be processed further
+                               before feeding them to the linker */
+                               objs.push_back(*i);
+                               i = pending.erase(i);
+                               continue;
+                       }
 
-                       Tool::ProcessingUnit processing_unit = gen->get_processing_unit();
-                       if(processing_unit!=Tool::ONE_FILE)
+                       // Pick the tool with the smallest processing unit
+                       Tool *tgt_tool = pkg_tools.get_tool_for_suffix(ext);
+                       if(!tgt_tool)
+                               tgt_tool = toolchain.get_tool_for_suffix(ext);
+                       if(tgt_tool && (!tool || tgt_tool->get_processing_unit()<tool->get_processing_unit()))
                        {
-                               FS::Path source_dir = FS::dirname(*i);
-                               for(auto j=next(i); 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
-                                               j = source_filenames.erase(j);
-                                       }
-                                       else
-                                               ++j;
-                               }
+                               tool = tgt_tool;
+                               if(tool->get_processing_unit()==Tool::ONE_FILE)
+                                       break;
                        }
 
-                       src = gen->create_target(templates);
-                       ext = FS::extpart(FS::basename(dynamic_cast<FileTarget &>(*src).get_path()));
+                       ++i;
                }
 
-               Tool *tool = toolchain.get_tool_for_suffix(ext, true);
-               if(tool)
-               {
-                       if(!src)
-                               src = tool->create_source(*this, *i);
-                       if(!src)
-                               continue;
-
-                       if(tool->accepts_suffix(ext))
-                       {
-                               Target *obj = tool->create_target(*src);
-                               objs.push_back(obj);
-                       }
+               if(!tool)
+                       break;
 
-                       if(type==LIBRARY && install)
+               Tool::ProcessingUnit processing_unit = tool->get_processing_unit();
+               if(processing_unit==Tool::ONE_FILE)
+               {
+                       // Process all pending accepted by the tool
+                       for(FileTarget *&t: pending)
                        {
-                               if(dynamic_cast<FileTarget *>(src)->is_installable())
-                                       build_graph.add_installed_target(*src);
-
-                               for(Target *s: src->get_side_effects())
-                                       if(dynamic_cast<FileTarget *>(s)->is_installable())
-                                               build_graph.add_installed_target(*s);
+                               string ext = FS::extpart(FS::basename(t->get_path()));
+                               if(tool->accepts_suffix(ext))
+                               {
+                                       t = &dynamic_cast<FileTarget &>(*tool->create_target(*t));
+                                       if(type==LIBRARY)
+                                               create_install(*t);
+                               }
                        }
                }
+               else
+               {
+                       // Process one group of pending accepted by the tool
+                       vector<Target *> group = extract_group(pending, *tool);
+                       FileTarget &tgt = dynamic_cast<FileTarget &>(*tool->create_target(group));
+                       pending.push_back(&tgt);
+                       if(type==LIBRARY)
+                               create_install(tgt);
+               }
        }
 
-       Tool &linker = toolchain.get_tool("LINK");
-
        vector<Target *> results;
-       results.reserve(2);
+       results.reserve(3);
        if(type==LIBRARY)
        {
                Tool &archiver = toolchain.get_tool("AR");
-               results.push_back(linker.create_target(objs, "shared"));
+               Target *shlib = linker.create_target(objs, "shared");
+               results.push_back(shlib);
+               if(Target *imp = linker.create_target(*shlib, "import"))
+                       results.push_back(imp);
                results.push_back(archiver.create_target(objs));
        }
        else if(type==MODULE)
@@ -133,6 +135,75 @@ void BinaryComponent::create_targets() const
        }
 }
 
+vector<FileTarget *> BinaryComponent::create_sources() const
+{
+       const Toolchain &toolchain = package.get_builder().get_toolchain();
+       const Toolchain &pkg_tools = package.get_toolchain();
+
+       vector<FileTarget *> targets;
+       for(const FS::Path &s: collect_source_files())
+       {
+               string ext = FS::extpart(FS::basename(s));
+               Target *src = 0;
+
+               Tool *tool = pkg_tools.get_tool_for_suffix(ext, true);
+               if(tool)
+                       src = tool->create_source(*this, s);
+               if(!src)
+               {
+                       tool = toolchain.get_tool_for_suffix(ext, true);
+                       if(tool)
+                               src = tool->create_source(*this, s);
+               }
+
+               if(FileTarget *file = dynamic_cast<FileTarget *>(src))
+               {
+                       targets.push_back(file);
+                       if(type==LIBRARY)
+                               create_install(*file);
+               }
+       }
+
+       return targets;
+}
+
+vector<Target *> BinaryComponent::extract_group(vector<FileTarget *> &targets, const Tool &tool)
+{
+       Tool::ProcessingUnit processing_unit = tool.get_processing_unit();
+       vector<Target *> group;
+       FS::Path group_dir;
+       for(auto i=targets.begin(); i!=targets.end(); )
+       {
+               const FS::Path &path = (*i)->get_path();
+               string ext = FS::extpart(FS::basename(path));
+               FS::Path dir = FS::dirname(path);
+               if(tool.accepts_suffix(ext) && (processing_unit!=Tool::DIRECTORY || group.empty() || dir==group_dir))
+               {
+                       group.push_back(*i);
+                       group_dir = dir;
+                       i = targets.erase(i);
+               }
+               else
+                       ++i;
+       }
+
+       return group;
+}
+
+void BinaryComponent::create_install(FileTarget &target) const
+{
+       BuildGraph &build_graph = package.get_builder().get_build_graph();
+       auto add_func = (install ? &BuildGraph::add_installed_target : &BuildGraph::add_staged_target);
+
+       if(target.is_installable())
+               (build_graph.*add_func)(target);
+
+       for(Target *s: target.get_side_effects())
+               if(dynamic_cast<FileTarget &>(*s).is_installable())
+                       (build_graph.*add_func)(*s);
+}
+
+
 BinaryComponent::Loader::Loader(BinaryComponent &c):
        DataFile::DerivedObjectLoader<BinaryComponent, Component::Loader>(c)
 {