X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fbinarypackage.cpp;h=aa1aed3c2fce4a0ecbfc7214299621724df27fdf;hb=92d81529ec8f3b84f5471162d0b27914eff7adb5;hp=bc3e5c929ec41af7d6a5b515f2ac2a17501c50b1;hpb=45c778b1976de1a3093e0c6fb5e2a94c42073dcb;p=builder.git diff --git a/source/binarypackage.cpp b/source/binarypackage.cpp index bc3e5c9..aa1aed3 100644 --- a/source/binarypackage.cpp +++ b/source/binarypackage.cpp @@ -1,44 +1,137 @@ +#include #include #include #include "binarypackage.h" #include "builder.h" +#include "filetarget.h" +#include "staticlibrary.h" using namespace std; using namespace Msp; BinaryPackage::BinaryPackage(Builder &b, const string &n): - Package(b, n), - need_path(false) + Package(b, n) { use_pkgconfig = false; } -void BinaryPackage::set_path(const FS::Path &p) +void BinaryPackage::do_prepare() { - path = builder.get_cwd()/p; -} + bool has_relative_paths = false; + for(BuildInfo::PathList::const_iterator i=export_binfo.libpath.begin(); (!has_relative_paths && i!=export_binfo.libpath.end()); ++i) + has_relative_paths = !i->is_absolute(); + for(BuildInfo::PathList::const_iterator i=export_binfo.incpath.begin(); (!has_relative_paths && i!=export_binfo.incpath.end()); ++i) + has_relative_paths = !i->is_absolute(); -void BinaryPackage::create_build_info() -{ - for(StringList::iterator i=export_binfo.incpath.begin(); i!=export_binfo.incpath.end(); ++i) - if((*i)[0]=='@') - *i = (path/i->substr(1)).str(); + list 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(list::const_iterator i=bases.begin(); i!=bases.end(); ++i) + { + FS::Path prefix = *i; + system = prefix.empty(); + if(system) + { + prefix = "/usr"; + const Architecture &arch = builder.get_current_arch(); + if(arch.is_cross()) + prefix /= arch.get_cross_prefix(); + } + + BuildInfo::PathList libpath = export_binfo.libpath; + if(!system && libpath.empty()) + libpath.push_back("lib"); + for(BuildInfo::PathList::iterator j=libpath.begin(); j!=libpath.end(); ++j) + *j = prefix/ *j; + + bool all_found = true; + for(BuildInfo::WordList::const_iterator j=export_binfo.libs.begin(); j!=export_binfo.libs.end(); ++j) + all_found &= (builder.get_vfs().find_library(*j, libpath, export_binfo.libmode, system)!=0); + + BuildInfo::PathList incpath = export_binfo.incpath; + if(!system && incpath.empty()) + incpath.push_back("include"); + for(BuildInfo::PathList::iterator j=incpath.begin(); j!=incpath.end(); ++j) + *j = prefix/ *j; + + for(HeaderList::const_iterator j=headers.begin(); j!=headers.end(); ++j) + all_found &= (builder.get_vfs().find_header(*j, 0, incpath, system)!=0); + + if(all_found) + { + base_path = prefix; + builder.get_logger().log("configure", format("%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", format("Cannot locate files for %s", name)); + problems.push_back("Cannot locate files"); + return; + } - for(StringList::iterator i=export_binfo.libpath.begin(); i!=export_binfo.libpath.end(); ++i) - if((*i)[0]=='@') - *i = (path/i->substr(1)).str(); + /* 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(BuildInfo::PathList::iterator i=export_binfo.incpath.begin(); i!=export_binfo.incpath.end(); ++i) + *i = base_path/ *i; + for(BuildInfo::PathList::iterator i=export_binfo.libpath.begin(); i!=export_binfo.libpath.end(); ++i) + *i = base_path/ *i; + } + + 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()); + + 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)) + 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); + for(BuildInfo::PathList::const_iterator j=combined_libpath.begin(); j!=combined_libpath.end(); ++j) + stlib->add_library_path(*j); + } + } } -BinaryPackage *BinaryPackage::from_pkgconfig(Builder &builder, const string &name) +BinaryPackage *BinaryPackage::from_flags(Builder &builder, const string &name, const Flags &flags, const Flags &static_flags) { - string info = builder.run_pkgconfig(name, "flags"); - BinaryPackage *pkg = new BinaryPackage(builder, name); pkg->use_pkgconfig = true; - BuildInfo &binfo = pkg->export_binfo; - vector flags = split(info); - for(vector::const_iterator i=flags.begin(); i!=flags.end(); ++i) + process_flags(flags, pkg->export_binfo); + + Flags exclusive_static_flags; + for(Flags::const_iterator i=static_flags.begin(); i!=static_flags.end(); ++i) + if(find(flags.begin(), flags.end(), *i)==flags.end()) + exclusive_static_flags.push_back(*i); + process_flags(exclusive_static_flags, pkg->static_binfo); + + return pkg; +} + +void BinaryPackage::process_flags(const Flags &flags, BuildInfo &binfo) +{ + for(Flags::const_iterator i=flags.begin(); i!=flags.end(); ++i) { if(!i->compare(0, 2, "-I")) binfo.incpath.push_back(i->substr(2)); @@ -57,19 +150,22 @@ BinaryPackage *BinaryPackage::from_pkgconfig(Builder &builder, const string &nam else if(*i=="-pthread") binfo.threads = true; } - - return pkg; } BinaryPackage::Loader::Loader(BinaryPackage &p): - Package::Loader(p) + DataFile::DerivedObjectLoader(p) { - add("need_path", &BinaryPackage::need_path); add("build_info", &Loader::build_info); + add("header", &Loader::header); } void BinaryPackage::Loader::build_info() { - load_sub(static_cast(pkg).export_binfo); + load_sub(obj.export_binfo); +} + +void BinaryPackage::Loader::header(const string &h) +{ + obj.headers.push_back(h); }