X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fbinarypackage.cpp;h=aa1aed3c2fce4a0ecbfc7214299621724df27fdf;hb=92d81529ec8f3b84f5471162d0b27914eff7adb5;hp=c2c18867018abc32d8dd9f81c2e53e38c0d18fea;hpb=654de39b62a9a58fd8e1b5a557361d628345788b;p=builder.git diff --git a/source/binarypackage.cpp b/source/binarypackage.cpp index c2c1886..aa1aed3 100644 --- a/source/binarypackage.cpp +++ b/source/binarypackage.cpp @@ -1,87 +1,171 @@ -/* $Id$ - -This file is part of builder -Copyright © 2007 Mikko Rasa, Mikkosoft Productions -Distributed under the LGPL -*/ - +#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; + use_pkgconfig = false; } -/** -Sets the path where the package files were installed. This is only useful if -the package doesn't use pkg-config. -*/ -void BinaryPackage::set_path(const Msp::Path::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; + } + + /* 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"); - for(StringList::iterator i=export_binfo.libpath.begin(); i!=export_binfo.libpath.end(); ++i) - if((*i)[0]=='@') - *i=(path/i->substr(1)).str(); + 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) { - list argv; - argv.push_back("pkg-config"); - argv.push_back("--silence-errors"); - argv.push_back("--cflags"); - argv.push_back("--libs"); - argv.push_back(name); - string info=run_command(argv); + BinaryPackage *pkg = new BinaryPackage(builder, name); + pkg->use_pkgconfig = true; - if(info.empty()) - return 0; + 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); - BinaryPackage *pkg=new BinaryPackage(builder, name); - pkg->use_pkgconfig=true; - BuildInfo &binfo=pkg->export_binfo; + return pkg; +} - vector flags=split(info); - for(vector::const_iterator i=flags.begin(); i!=flags.end(); ++i) +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)); else if(!i->compare(0, 2, "-D")) - binfo.defines.push_back(i->substr(2)); + { + string::size_type equals = i->find('='); + if(equals!=string::npos) + binfo.defines[i->substr(2, equals-2)] = i->substr(equals+1); + else + binfo.defines[i->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") + 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); }