X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Flib%2Fbinarycomponent.cpp;h=0b5d3cf84d067c63b554af9c05f063415ca17074;hb=6ce67e1469bf62156ddf64e33644851f9064c6ed;hp=3209ccc185438f721d0892053564724c17fb87fa;hpb=c8e829c219c65ff8e93b6c7b66212ff0876441c5;p=builder.git diff --git a/source/lib/binarycomponent.cpp b/source/lib/binarycomponent.cpp index 3209ccc..0b5d3cf 100644 --- a/source/lib/binarycomponent.cpp +++ b/source/lib/binarycomponent.cpp @@ -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 pending = create_sources(); + vector objs; - vector 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 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()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(*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) + break; - if(tool->accepts_suffix(ext)) + 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) { - Target *obj = tool->create_target(*src); - objs.push_back(obj); + string ext = FS::extpart(FS::basename(t->get_path())); + if(tool->accepts_suffix(ext)) + { + t = &dynamic_cast(*tool->create_target(*t)); + if(type==LIBRARY && install) + create_install(*t); + } } - + } + else + { + // Process one group of pending accepted by the tool + vector group = extract_group(pending, *tool); + FileTarget &tgt = dynamic_cast(*tool->create_target(group)); + pending.push_back(&tgt); if(type==LIBRARY && install) - { - if(dynamic_cast(src)->is_installable()) - build_graph.add_installed_target(*src); - - for(Target *s: src->get_side_effects()) - if(dynamic_cast(s)->is_installable()) - build_graph.add_installed_target(*s); - } + create_install(tgt); } } - Tool &linker = toolchain.get_tool("LINK"); - vector 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,74 @@ void BinaryComponent::create_targets() const } } +vector BinaryComponent::create_sources() const +{ + const Toolchain &toolchain = package.get_builder().get_toolchain(); + const Toolchain &pkg_tools = package.get_toolchain(); + + vector 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(src)) + { + targets.push_back(file); + if(type==LIBRARY && install) + create_install(*file); + } + } + + return targets; +} + +vector BinaryComponent::extract_group(vector &targets, const Tool &tool) +{ + Tool::ProcessingUnit processing_unit = tool.get_processing_unit(); + vector 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(); + + if(target.is_installable()) + build_graph.add_installed_target(target); + + for(Target *s: target.get_side_effects()) + if(dynamic_cast(*s).is_installable()) + build_graph.add_installed_target(*s); +} + + BinaryComponent::Loader::Loader(BinaryComponent &c): DataFile::DerivedObjectLoader(c) {