X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fbinarypackage.cpp;h=adfca1a273bd4ae86b1296e23225918000f0c6cd;hb=5e00719d0c63e306786ff36df61797cdbc86f3e9;hp=381e792681abfbee7e78163753e397c6f5a68d5a;hpb=ef97eadef58922f45e1ba86a1d009db5ea41dd50;p=builder.git diff --git a/source/binarypackage.cpp b/source/binarypackage.cpp index 381e792..adfca1a 100644 --- a/source/binarypackage.cpp +++ b/source/binarypackage.cpp @@ -1,7 +1,10 @@ +#include #include #include #include "binarypackage.h" #include "builder.h" +#include "filetarget.h" +#include "staticlibrary.h" using namespace std; using namespace Msp; @@ -12,54 +15,155 @@ BinaryPackage::BinaryPackage(Builder &b, const string &n): use_pkgconfig = false; } -void BinaryPackage::create_build_info() +BinaryPackage *BinaryPackage::from_flags(Builder &builder, const string &name, const Flags &flags, const Flags &static_flags) { - for(BuildInfo::PathList::iterator i=export_binfo.incpath.begin(); i!=export_binfo.incpath.end(); ++i) - if((*i)[0]=="@") - *i = builder.get_prefix()/i->subpath(1); + BinaryPackage *pkg = new BinaryPackage(builder, name); + pkg->use_pkgconfig = true; + + process_flags(flags, pkg->export_binfo); - for(BuildInfo::PathList::iterator i=export_binfo.libpath.begin(); i!=export_binfo.libpath.end(); ++i) - if((*i)[0]=="@") - *i = builder.get_prefix()/i->subpath(1); + Flags exclusive_static_flags; + for(const string &f: static_flags) + if(!any_equals(flags, f)) + exclusive_static_flags.push_back(f); + process_flags(exclusive_static_flags, pkg->static_binfo); + + return pkg; } -BinaryPackage *BinaryPackage::from_flags(Builder &builder, const string &name, const vector &flags) +void BinaryPackage::process_flags(const Flags &flags, BuildInfo &binfo) { - BinaryPackage *pkg = new BinaryPackage(builder, name); - pkg->use_pkgconfig = true; - BuildInfo &binfo = pkg->export_binfo; - - for(vector::const_iterator i=flags.begin(); i!=flags.end(); ++i) + for(const string &f: flags) { - if(!i->compare(0, 2, "-I")) - binfo.incpath.push_back(i->substr(2)); - else if(!i->compare(0, 2, "-D")) + if(!f.compare(0, 2, "-I")) + binfo.incpath.push_back(f.substr(2)); + else if(!f.compare(0, 2, "-D")) { - string::size_type equals = i->find('='); + string::size_type equals = f.find('='); if(equals!=string::npos) - binfo.defines[i->substr(2, equals-2)] = i->substr(equals+1); + binfo.defines[f.substr(2, equals-2)] = f.substr(equals+1); else - binfo.defines[i->substr(2)] = string(); + binfo.defines[f.substr(2)] = string(); } - else if(!i->compare(0, 2, "-L")) - binfo.libpath.push_back(i->substr(2)); - else if(!i->compare(0, 2, "-l")) - binfo.libs.push_back(i->substr(2)); - else if(*i=="-pthread") + else if(!f.compare(0, 2, "-L")) + binfo.libpath.push_back(f.substr(2)); + else if(!f.compare(0, 2, "-l")) + binfo.libs.push_back(f.substr(2)); + else if(f=="-pthread") binfo.threads = true; } +} - return pkg; +void BinaryPackage::do_prepare() +{ + auto is_relative = [](const FS::Path &p){ return !p.is_absolute(); }; + bool has_relative_paths = any_of(export_binfo.libpath.begin(), export_binfo.libpath.end(), is_relative) || + any_of(export_binfo.incpath.begin(), export_binfo.incpath.end(), is_relative); + + vector bases; + + /* If we have any relative paths that need resolving, or we have no paths at + all and are not using pkg-config, look for files in prefix */ + if(has_relative_paths || (!use_pkgconfig && export_binfo.libpath.empty() && export_binfo.incpath.empty())) + bases.push_back(builder.get_prefix()); + + // Always look in system locations + bases.push_back(FS::Path()); + + bool system = false; + for(const FS::Path &b: bases) + { + FS::Path prefix = b; + system = prefix.empty(); + if(system) + { + prefix = "/usr"; + const Architecture &arch = builder.get_current_arch(); + if(arch.is_cross()) + prefix /= arch.get_cross_prefix(); + } + + VirtualFileSystem::SearchPath libpath = export_binfo.libpath; + if(!system && libpath.empty()) + libpath.push_back("lib"); + for(FS::Path &p: libpath) + p = prefix/p; + + bool all_found = true; + for(const string &l: export_binfo.libs) + all_found &= (builder.get_vfs().find_library(l, libpath, export_binfo.libmode, system)!=0); + + VirtualFileSystem::SearchPath incpath = export_binfo.incpath; + if(!system && incpath.empty()) + incpath.push_back("include"); + for(FS::Path &p: incpath) + p = prefix/p; + + for(const string &h: headers) + all_found &= (builder.get_vfs().find_header(h, 0, incpath, system)!=0); + + if(all_found) + { + base_path = prefix; + builder.get_logger().log("configure", "%s found in %s", name, ((system && use_pkgconfig) ? "system" : base_path.str())); + break; + } + } + + if(base_path.empty()) + { + // TODO report which files were not found + builder.get_logger().log("problems", "Cannot locate files for %s", name); + problems.push_back("Cannot locate files"); + return; + } + + /* Add default entries to paths if they're empty and the package was found + in a non-system location */ + if(!system && export_binfo.incpath.empty()) + export_binfo.incpath.push_back(base_path/"include"); + if(!system && export_binfo.libpath.empty()) + export_binfo.libpath.push_back(base_path/"lib"); + + if(has_relative_paths) + { + for(FS::Path &p: export_binfo.incpath) + p = base_path/p; + for(FS::Path &p: export_binfo.libpath) + p = base_path/p; + } + + if(!static_binfo.libs.empty()) + { + VirtualFileSystem::SearchPath combined_libpath = static_binfo.libpath; + combined_libpath.insert(combined_libpath.end(), export_binfo.libpath.begin(), export_binfo.libpath.end()); + + for(const string &l: export_binfo.libs) + if(Target *lib = builder.get_vfs().find_library(l, export_binfo.libpath, BuildInfo::FORCE_STATIC, system)) + if(StaticLibrary *stlib = dynamic_cast(lib)) + { + for(const string &s: static_binfo.libs) + stlib->add_required_library(s); + for(const FS::Path &p: combined_libpath) + stlib->add_library_path(p); + } + } } BinaryPackage::Loader::Loader(BinaryPackage &p): - DataFile::DerivedObjectLoader(p) + DataFile::DerivedObjectLoader(p) { add("build_info", &Loader::build_info); + add("header", &Loader::header); } void BinaryPackage::Loader::build_info() { load_sub(obj.export_binfo); } + +void BinaryPackage::Loader::header(const string &h) +{ + obj.headers.push_back(h); +}