]> git.tdb.fi Git - builder.git/commitdiff
Have the linker specify symlinks for installed libraries
authorMikko Rasa <tdb@tdb.fi>
Thu, 6 Sep 2012 15:02:04 +0000 (18:02 +0300)
committerMikko Rasa <tdb@tdb.fi>
Fri, 7 Sep 2012 17:49:12 +0000 (20:49 +0300)
source/gnulinker.cpp
source/gnulinker.h
source/installedfile.cpp
source/installedfile.h

index d2ea51e96c9a3e36387f0f64198aa2c4242443f9..92971da7b15a6de11c0e7cc0060cc0daefdcb08b 100644 (file)
@@ -10,6 +10,7 @@
 #include "externaltask.h"
 #include "gnucompiler.h"
 #include "gnulinker.h"
+#include "installedfile.h"
 #include "objectfile.h"
 #include "sharedlibrary.h"
 #include "sourcepackage.h"
@@ -74,6 +75,20 @@ Target *GnuLinker::create_target(const list<Target *> &sources, const string &ar
        return bin;
 }
 
+Target *GnuLinker::create_install(Target &target) const
+{
+       if(SharedLibrary *shlib = dynamic_cast<SharedLibrary *>(&target))
+       {
+               const Tool &copy = builder.get_toolchain().get_tool("CP");
+               InstalledFile *inst_tgt = dynamic_cast<InstalledFile *>(copy.create_target(target));
+               const Pattern &pattern = architecture->get_shared_library_patterns().front();
+               inst_tgt->set_symlink(pattern.apply(shlib->get_libname()));
+               return inst_tgt;
+       }
+       else
+               return 0;
+}
+
 Task *GnuLinker::run(const Target &) const
 {
        throw logic_error("GnuLinker should not be run directly");
@@ -106,6 +121,11 @@ Target *GnuLinker::Linker::create_target(const list<Target *> &sources, const st
        return parent.create_target(sources, arg);
 }
 
+Target *GnuLinker::Linker::create_install(Target &target) const
+{
+       return parent.create_install(target);
+}
+
 string GnuLinker::Linker::create_build_signature(const BuildInfo &binfo) const
 {
        string result = FS::basename(executable->get_path());
index 8c380c85ae9beb95c02c1c68645a1b580458c85d..07e6a0ca0c322fb3ee6deb711b968cffbc019c2a 100644 (file)
@@ -19,6 +19,7 @@ private:
                Linker(GnuLinker &, const std::string &);
 
                virtual Target *create_target(const std::list<Target *> &, const std::string &) const;
+               virtual Target *create_install(Target &) const;
                virtual std::string create_build_signature(const BuildInfo &) const;
                virtual Task *run(const Target &) const;
        };
@@ -31,6 +32,7 @@ public:
        ~GnuLinker();
 
        virtual Target *create_target(const std::list<Target *> &, const std::string &) const;
+       virtual Target *create_install(Target &) const;
        virtual Task *run(const Target &) const;
 };
 
index b2487537369076f705b136a1023371f9a9cf7356..35742bb0daf8e383f90418f621b438c14eb9e223 100644 (file)
@@ -12,17 +12,6 @@ InstalledFile::InstalledFile(Builder &b, const SourcePackage &p, FileTarget &s,
        source(s)
 {
        add_dependency(source);
-
-       /* XXX Ideally, the tool should handle this (symlinks are not necessary for
-       windows dlls).  However, the tool that created the target being installed
-       knows nothing about the InstalledFile. */
-       string base_fn = FS::basename(source.get_path());
-       const string &inst_fn = source.get_install_filename();
-       if(!inst_fn.empty() && inst_fn!=base_fn)
-       {
-               link = FS::dirname(path)/base_fn;
-               builder.get_vfs().register_path(link, this);
-       }
 }
 
 FS::Path InstalledFile::generate_target_path(const FS::Path &prefix, const FileTarget &tgt, const string &loc)
@@ -45,6 +34,12 @@ FS::Path InstalledFile::generate_target_path(const FS::Path &prefix, const FileT
        return prefix/mid/fn;
 }
 
+void InstalledFile::set_symlink(const FS::Path &l)
+{
+       link = FS::dirname(path)/l;
+       builder.get_vfs().register_path(link, this);
+}
+
 Target *InstalledFile::get_real_target()
 {
        return source.get_real_target();
index 1ce5f1e3851475f65b4eea3ab3fa212a5043f5bc..9e886d580a00976672dcd125742adb5234643380 100644 (file)
@@ -21,7 +21,13 @@ private:
 public:
        virtual const char *get_type() const { return "InstalledFile"; }
        FileTarget &get_source() const { return source; }
+
+       /** Sets a symlink for the file.  A relative path will be rooted at the
+       directory the file resides in. */
+       void set_symlink(const Msp::FS::Path &);
+
        const Msp::FS::Path &get_symlink() const { return link; }
+
        virtual Target *get_real_target();
 private:
        virtual void check_rebuild();