]> 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 a2d4ea47defd77395d62d020730327a55da3c5c5..570f5f499ec22b1e957c526515f3ad4dfd1fe3ef 100644 (file)
 using namespace std;
 using namespace Msp;
 
+FileTarget::FileTarget(Builder &b, const FS::Path &a):
+       FileTarget(b, 0, a)
+{ }
+
+FileTarget::FileTarget(Builder &b, const SourcePackage &p, const FS::Path &a):
+       FileTarget(b, &p, a)
+{ }
+
 FileTarget::FileTarget(Builder &b, const SourcePackage *p, const FS::Path &a):
        Target(b, generate_name(b, p, a)),
        path(a)
@@ -56,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())
@@ -139,7 +180,7 @@ string FileTarget::create_build_signature() const
 
 void FileTarget::build(Task &task)
 {
-       task.add_file(path);
+       task.add_target(*this);
        task.set_unlink(true);
 }