+ 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 *r: all_reqs)
+ {
+ BuildInfo::UpdateLevel level = BuildInfo::CHAINED;
+ if(any_equals(direct_reqs, r))
+ level = BuildInfo::DEPENDENCY;
+ final_build_info.update_from(r->get_exported_build_info(), level);
+
+ for(Package *q: r->get_required_packages())
+ if(!any_equals(all_reqs, q))
+ all_reqs.push_back(q);
+ }
+
+ final_build_info.update_from(package.get_build_info());
+ final_build_info.update_from(build_info);
+ build_info = final_build_info;
+
+ for(FS::Path &p: build_info.incpath)
+ p = (package.get_source_directory()/p).str();
+ for(FS::Path &p: build_info.libpath)
+ p = (package.get_source_directory()/p).str();
+}
+
+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;
+
+ FS::Path gen_dir = package.get_temp_directory()/"generated";
+ if(FS::descendant_depth(path, gen_dir)>=0)
+ {
+ FS::Path subdir = FS::dirname(FS::relative(path, gen_dir));
+ binfo.local_incpath.push_back(package.get_source_directory()/subdir);
+ }
+ else
+ {
+ FS::Path subdir = FS::dirname(FS::relative(path, package.get_source_directory()));
+ binfo.local_incpath.push_back(gen_dir/subdir);
+ }
+
+ if(!overlays.empty())
+ {
+ FS::Path dir = FS::dirname(path);
+ string last = FS::basename(dir);
+ if(any_equals(overlays, last))
+ dir = FS::dirname(dir);
+
+ if(any_equals(sources, dir))
+ {
+ binfo.local_incpath.push_back(dir);
+ for(const string &o: overlays)
+ binfo.local_incpath.push_back(dir/o);
+ }
+ }
+ return binfo;
+}
+
+Component::SourceList Component::collect_source_files() const
+{
+ SourceList files;
+ for(const FS::Path &p: sources)