From 42d80b43a463627e0e7edf6df3be9bd4b976d74c Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sun, 8 Jul 2018 17:47:49 +0300 Subject: [PATCH] Use build info to store static library dependencies In some cases it's desirable to link a particular library statically but use dynamic linking for its dependencies. In particular, libpng and libvorbis depend on libm, which is considered a part of libc and must be linked in the same way. Now all libraries are looked up according to libmode, making such linking possible. --- source/binary.cpp | 28 +++++++++------------------- source/binarypackage.cpp | 18 ++++++------------ source/staticlibrary.cpp | 11 +++++++++++ source/staticlibrary.h | 9 +++++++++ 4 files changed, 35 insertions(+), 31 deletions(-) diff --git a/source/binary.cpp b/source/binary.cpp index 753ddbc..fcf30f1 100644 --- a/source/binary.cpp +++ b/source/binary.cpp @@ -63,7 +63,8 @@ void Binary::find_dependencies() static_binfo.threads = true; } - list libs_to_process; + list::iterator insert_pos = j; + ++insert_pos; for(BuildInfo::WordList::const_iterator i=binfo.libs.begin(); i!=binfo.libs.end(); ++i) { if(i->size()>10 && !i->compare(i->size()-10, 10, ".framework")) @@ -72,27 +73,16 @@ void Binary::find_dependencies() BuildInfo::LibraryMode libmode = component->get_build_info().get_libmode_for(*i); Target *lib = builder.get_vfs().find_library(*i, binfo.libpath, libmode); if(lib) - libs_to_process.push_back(lib); + { + Target *real = lib->get_real_target(); + if(StaticLibrary *stlib = dynamic_cast(real)) + queue.insert(insert_pos, stlib); + else + dep_libs.push_back(lib); + } else if(missing_libs.insert(*i).second) problems.push_back(format("Required library %s not found", *i)); } - - if(tgt!=this) - { - const Target::Dependencies &tdeps = tgt->get_transitive_dependencies(); - libs_to_process.insert(libs_to_process.end(), tdeps.begin(), tdeps.end()); - } - - list::iterator insert_pos = j; - ++insert_pos; - for(list::const_iterator i=libs_to_process.begin(); i!=libs_to_process.end(); ++i) - { - Target *real = (*i)->get_real_target(); - if(StaticLibrary *stlib = dynamic_cast(real)) - queue.insert(insert_pos, stlib); - else - dep_libs.push_back(*i); - } } queue.pop_front(); diff --git a/source/binarypackage.cpp b/source/binarypackage.cpp index 679fb63..bed4c90 100644 --- a/source/binarypackage.cpp +++ b/source/binarypackage.cpp @@ -4,6 +4,7 @@ #include "binarypackage.h" #include "builder.h" #include "filetarget.h" +#include "staticlibrary.h" using namespace std; using namespace Msp; @@ -96,20 +97,13 @@ void BinaryPackage::do_prepare() if(!static_binfo.libs.empty()) { - BuildInfo::PathList combined_libpath = static_binfo.libpath; - combined_libpath.insert(combined_libpath.end(), export_binfo.libpath.begin(), export_binfo.libpath.end()); - - Target::Dependencies static_dep_libs; - for(BuildInfo::WordList::const_iterator i=static_binfo.libs.begin(); i!=static_binfo.libs.end(); ++i) - if(Target *lib = builder.get_vfs().find_library(*i, combined_libpath, BuildInfo::STATIC, system)) - static_dep_libs.push_back(lib); - for(BuildInfo::WordList::const_iterator i=export_binfo.libs.begin(); i!=export_binfo.libs.end(); ++i) if(Target *lib = builder.get_vfs().find_library(*i, export_binfo.libpath, BuildInfo::FORCE_STATIC, system)) - { - for(Target::Dependencies::const_iterator j=static_dep_libs.begin(); j!=static_dep_libs.end(); ++j) - lib->add_transitive_dependency(**j); - } + if(StaticLibrary *stlib = dynamic_cast(lib)) + { + for(BuildInfo::WordList::const_iterator j=static_binfo.libs.begin(); j!=static_binfo.libs.end(); ++j) + stlib->add_required_library(*j); + } } } diff --git a/source/staticlibrary.cpp b/source/staticlibrary.cpp index 9ee4a9a..5ff8477 100644 --- a/source/staticlibrary.cpp +++ b/source/staticlibrary.cpp @@ -28,3 +28,14 @@ string StaticLibrary::generate_filename(const Component &comp) const Architecture &arch = comp.get_package().get_builder().get_current_arch(); return arch.get_static_library_patterns().front().apply(comp.get_name()); } + +void StaticLibrary::add_required_library(const string &lib) +{ + build_info.libs.push_back(lib); +} + +void StaticLibrary::collect_build_info(BuildInfo &binfo) const +{ + Target::collect_build_info(binfo); + binfo.update_from(build_info); +} diff --git a/source/staticlibrary.h b/source/staticlibrary.h index 033e98a..c76b314 100644 --- a/source/staticlibrary.h +++ b/source/staticlibrary.h @@ -11,6 +11,12 @@ A static library target. */ class StaticLibrary: public FileTarget { +private: + /* TODO this really belongs in a Component, but some refactoring is required + to allow non-builder packages to have components. Rename BinaryPackage to + ExternalPackage, add BuildableComponent and ExternalComponent classes. */ + BuildInfo build_info; + public: StaticLibrary(Builder &, const Msp::FS::Path &); StaticLibrary(Builder &, const Component &, const std::list &); @@ -19,6 +25,9 @@ private: public: virtual const char *get_type() const { return "StaticLibrary"; } + + void add_required_library(const std::string &); + virtual void collect_build_info(BuildInfo &) const; }; #endif -- 2.45.2