]> git.tdb.fi Git - builder.git/blobdiff - source/lib/filetarget.cpp
Refactor transitive dependencies to work on all targets
[builder.git] / source / lib / filetarget.cpp
index 7ab13c3d5bf93833580a687982d7dd2acbdcc2ce..570f5f499ec22b1e957c526515f3ad4dfd1fe3ef 100644 (file)
@@ -64,6 +64,39 @@ void FileTarget::touch()
        signal_bubble_rebuild.emit();
 }
 
+Target *FileTarget::resolve_transitive_dependency(Target &from, Target &dep) const
+{
+       FileTarget *from_file = dynamic_cast<FileTarget *>(&from);
+       FileTarget *dep_file = dynamic_cast<FileTarget *>(&dep);
+       if(!from_file || !dep_file)
+               return &dep;
+
+       const SourcePackage *from_pkg = from.get_package();
+       if(dep_file->get_package()!=from_pkg || FS::descendant_depth(dep_file->get_path(), from_pkg->get_source_directory())<0)
+               return &dep;
+
+       /* Adjust the path of the dependency to account for the install location
+       of the dependent target. */
+       const Component *from_comp = from_file->get_real_target()->get_component();
+       const Component *dep_comp = dep_file->get_component();
+       FS::Path from_inst = from_comp->get_install_map().get_install_location(*from_file->get_real_target());
+       FS::Path dep_inst = dep_comp->get_install_map().get_install_location(*dep_file);
+       FS::Path displaced = FS::dirname(from_file->get_path())/FS::relative(dep_inst, from_inst)/FS::basename(dep_file->get_path());
+       if(Target *result = builder.get_vfs().get_target(displaced))
+               return result;
+
+       /* If the target was in an overlay directory and the displaced
+       dependency is not found, try removing the overlay from the path. */
+       string last_dir = FS::basename(FS::dirname(displaced));
+       if(any_equals(dep_comp->get_overlays(), last_dir))
+       {
+               displaced = displaced.subpath(0, displaced.size()-2)/FS::basename(dep_file->get_path());
+               return builder.get_vfs().get_target(displaced);
+       }
+
+       return nullptr;
+}
+
 void FileTarget::check_rebuild()
 {
        if(!tool || needs_rebuild())