From c009620591a7e80c457eabe3a2dbfc2dcfbdf5cf Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Thu, 6 Sep 2012 18:02:04 +0300 Subject: [PATCH] Have the linker specify symlinks for installed libraries --- source/gnulinker.cpp | 20 ++++++++++++++++++++ source/gnulinker.h | 2 ++ source/installedfile.cpp | 17 ++++++----------- source/installedfile.h | 6 ++++++ 4 files changed, 34 insertions(+), 11 deletions(-) diff --git a/source/gnulinker.cpp b/source/gnulinker.cpp index d2ea51e..92971da 100644 --- a/source/gnulinker.cpp +++ b/source/gnulinker.cpp @@ -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 &sources, const string &ar return bin; } +Target *GnuLinker::create_install(Target &target) const +{ + if(SharedLibrary *shlib = dynamic_cast(&target)) + { + const Tool © = builder.get_toolchain().get_tool("CP"); + InstalledFile *inst_tgt = dynamic_cast(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 &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()); diff --git a/source/gnulinker.h b/source/gnulinker.h index 8c380c8..07e6a0c 100644 --- a/source/gnulinker.h +++ b/source/gnulinker.h @@ -19,6 +19,7 @@ private: Linker(GnuLinker &, const std::string &); virtual Target *create_target(const std::list &, 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 &, const std::string &) const; + virtual Target *create_install(Target &) const; virtual Task *run(const Target &) const; }; diff --git a/source/installedfile.cpp b/source/installedfile.cpp index b248753..35742bb 100644 --- a/source/installedfile.cpp +++ b/source/installedfile.cpp @@ -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(); diff --git a/source/installedfile.h b/source/installedfile.h index 1ce5f1e..9e886d5 100644 --- a/source/installedfile.h +++ b/source/installedfile.h @@ -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(); -- 2.45.2