+ BuildInfo final_build_info;
+
+ const Package::Requirements &pkg_reqs = package.get_required_packages();
+ Package::Requirements direct_reqs = requires;
+ direct_reqs.insert(direct_reqs.end(), pkg_reqs.begin(), pkg_reqs.end());
+
+ Package::Requirements all_reqs = direct_reqs;
+ for(Package::Requirements::iterator i=all_reqs.begin(); i!=all_reqs.end(); ++i)
+ {
+ BuildInfo::UpdateLevel level = BuildInfo::CHAINED;
+ if(find(direct_reqs.begin(), direct_reqs.end(), *i)!=direct_reqs.end())
+ level = BuildInfo::DEPENDENCY;
+ final_build_info.update_from((*i)->get_exported_build_info(), level);
+
+ const Package::Requirements &reqs = (*i)->get_required_packages();
+ for(Package::Requirements::const_iterator j=reqs.begin(); j!=reqs.end(); ++j)
+ if(find(all_reqs.begin(), all_reqs.end(), *j)==all_reqs.end())
+ all_reqs.push_back(*j);
+ }
+
+ final_build_info.update_from(package.get_build_info());
+ final_build_info.update_from(build_info);
+ build_info = final_build_info;
+
+ for(BuildInfo::PathList::iterator i=build_info.incpath.begin(); i!=build_info.incpath.end(); ++i)
+ *i = (package.get_source_directory() / *i).str();
+ for(BuildInfo::PathList::iterator i=build_info.libpath.begin(); i!=build_info.libpath.end(); ++i)
+ *i = (package.get_source_directory() / *i).str();
+
+ for(UseList::const_iterator i=uses.begin(); i!=uses.end(); ++i)
+ {
+ /* Select an include path that contains all the sources for this and the
+ used component. This should produce a sensible result in most cases. */
+ FS::Path base;
+ for(SourceList::const_iterator j=sources.begin(); j!=sources.end(); ++j)
+ base = base.empty() ? *j : FS::common_ancestor(base, *j);
+ const SourceList &use_sources = (*i)->get_sources();
+ for(SourceList::const_iterator j=use_sources.begin(); j!=use_sources.end(); ++j)
+ base = FS::common_ancestor(base, *j);
+ build_info.incpath.push_back(base);
+ build_info.libs.push_back((*i)->get_name());
+ if(!(*i)->get_install())
+ {
+ build_info.libmodes[(*i)->get_name()] = BuildInfo::STATIC;
+ build_info.libpath.push_back((*i)->get_package().get_source_directory());
+ }
+ }
+
+ if(type==LIBRARY || type==MODULE)
+ if(build_info.libmode<BuildInfo::DYNAMIC)
+ build_info.libmode = BuildInfo::DYNAMIC;
+
+ if(build_info.libmode<BuildInfo::DYNAMIC)
+ {
+ for(Package::Requirements::iterator i=all_reqs.begin(); i!=all_reqs.end(); ++i)
+ {
+ const BuildInfo &ebi = (*i)->get_exported_build_info();
+ build_info.libpath.insert(build_info.libpath.end(), ebi.libpath.begin(), ebi.libpath.end());
+ }
+ }
+}
+
+BuildInfo Component::get_build_info_for_path(const FS::Path &path) const
+{
+ // XXX Cache these and check that the directories actually exist before adding them
+ BuildInfo binfo = build_info;
+ if(!overlays.empty())
+ {
+ FS::Path dir = FS::dirname(path);
+ string last = FS::basename(dir);
+ for(OverlayList::const_iterator i=overlays.begin(); i!=overlays.end(); ++i)
+ if(last==*i)
+ {
+ dir = FS::dirname(dir);
+ break;
+ }
+
+ for(SourceList::const_iterator i=sources.begin(); i!=sources.end(); ++i)
+ if(dir==*i)
+ {
+ binfo.local_incpath.push_back(dir);
+ for(OverlayList::const_iterator j=overlays.begin(); j!=overlays.end(); ++j)
+ binfo.local_incpath.push_back(*i/ *j);
+ }
+ }
+ return binfo;
+}
+
+void Component::create_targets() const
+{
+ Builder &builder = package.get_builder();
+ BuildGraph &build_graph = builder.get_build_graph();
+ const Toolchain &toolchain = builder.get_toolchain();
+
+ SourceList source_filenames = collect_source_files();