X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fpackagemanager.cpp;h=9ca11bae94e3b80dd07e94b6509da26b67403561;hb=e4c839cacd8572ade951f4961e8e145d20e0103f;hp=c3d693961dd332d188a7a6e7b93547ed1e486623;hpb=1d687970cc35e54c3335f4aa2fdef23424fe0a06;p=builder.git diff --git a/source/packagemanager.cpp b/source/packagemanager.cpp index c3d6939..9ca11ba 100644 --- a/source/packagemanager.cpp +++ b/source/packagemanager.cpp @@ -1,10 +1,11 @@ +#include #include #include #include #include #include #include -#include +#include #include #include "binarypackage.h" #include "builder.h" @@ -17,11 +18,10 @@ using namespace Msp; PackageManager::PackageManager(Builder &b): builder(b), - no_externals(false) -{ - pkg_path.push_back(builder.get_cwd()/"."); - pkg_path.push_back(builder.get_cwd()/".."); -} + no_externals(false), + main_pkg(0), + env_set(false) +{ } PackageManager::~PackageManager() { @@ -29,6 +29,16 @@ PackageManager::~PackageManager() delete i->second; } +void PackageManager::append_package_path(const FS::Path &p) +{ + pkg_path.push_back(p); +} + +void PackageManager::append_binary_package_path(const FS::Path &p) +{ + binpkg_path.push_back(p); +} + void PackageManager::set_no_externals(bool x) { no_externals = x; @@ -45,87 +55,128 @@ void PackageManager::add_package(Package *pkg) throw logic_error("Package is already managed"); } + if(packages.empty()) + main_pkg = pkg; + packages.insert(PackageMap::value_type(pkg->get_name(), pkg)); } -Package *PackageManager::find_package(const string &name) +Package *PackageManager::get_package(const string &name) const { - PackageMap::iterator i = packages.find(format("%s/%s", name, builder.get_current_arch().get_system())); - if(i==packages.end()) - i = packages.find(name); + PackageMap::const_iterator i = packages.find(name); if(i!=packages.end()) return i->second; + return 0; +} + +Package &PackageManager::get_main_package() const +{ + if(!main_pkg) + throw logic_error("No packages"); + return *main_pkg; +} + +Package *PackageManager::find_package(const string &name) +{ + if(not_found.count(name)) + return 0; + + if(Package *pkg = get_package(name)) + return pkg; + if(!no_externals) { FS::Path path = get_package_location(name); - if(!path.empty() && !builder.load_build_file(path/"Build")) + if(!path.empty()) { - i = packages.find(name); + builder.load_build_file(path/"Build"); + PackageMap::iterator i = packages.find(name); if(i!=packages.end()) return i->second; } } - Package *pkg = 0; + FS::Path path = get_binary_package_file(name); + if(!path.empty()) + { + builder.load_build_file(path); + if(Package *pkg = get_package(name)) + return pkg; + } + try { // Package source not found - create a binary package string flags_str = run_pkgconfig(name, "flags"); - vector flags = split(flags_str); - pkg = BinaryPackage::from_flags(builder, name, flags); + BinaryPackage::Flags flags = split(flags_str); + flags_str = run_pkgconfig(name, "staticflags"); + BinaryPackage::Flags static_flags = split(flags_str); + Package *pkg = BinaryPackage::from_flags(builder, name, flags, static_flags); + packages.insert(PackageMap::value_type(name, pkg)); + return pkg; } catch(...) { - builder.problem(name, "not found"); + not_found.insert(name); + return 0; } - - packages.insert(PackageMap::value_type(name, pkg)); - - return pkg; } string PackageManager::run_pkgconfig(const string &pkg, const string &what) { + if(!env_set) + { + const FS::Path &prefix = builder.get_prefix(); + if(prefix.str()!="/usr") + { + FS::Path pcdir = prefix/"lib/pkgconfig"; + if(const char *pcp = getenv("PKG_CONFIG_PATH")) + { + vector path = split(pcp, ':'); + bool found = false; + for(vector::const_iterator i=path.begin(); (!found && i!=path.end()); ++i) + found = (*i==pcdir.str()); + if(!found) + { + path.push_back(pcdir.str()); + setenv("PKG_CONFIG_PATH", join(path.begin(), path.end(), ":").c_str(), true); + } + } + else + setenv("PKG_CONFIG_PATH", pcdir.str().c_str(), true); + } + } + ExternalTask::Arguments argv; argv.push_back("pkg-config"); if(what=="cflags" || what=="libs") argv.push_back("--"+what); - else if(what=="flags") + else if(what=="flags" || what=="staticflags") { argv.push_back("--cflags"); argv.push_back("--libs"); + if(what=="staticflags") + argv.push_back("--static"); } else argv.push_back("--variable="+what); argv.push_back(pkg); - if(builder.get_verbose()>=4) - IO::print("Running %s\n", join(argv.begin(), argv.end())); + builder.get_logger().log("auxcommands", format("Running %s", join(argv.begin(), argv.end()))); - ExternalTask task(argv); - task.set_stdout(ExternalTask::CAPTURE); - task.set_stderr(ExternalTask::IGNORE); - task.start(); - Task::Status status; - while((status=task.check())==Task::RUNNING) - Time::sleep(10*Time::msec); - if(status==Task::ERROR) - throw runtime_error(format("pkg-config for package %s failed", pkg)); - - return task.get_output(); + return ExternalTask::run_and_capture_output(argv); } FS::Path PackageManager::get_package_location(const string &name) { - if(builder.get_verbose()>=3) - IO::print("Looking for package %s\n", name); + builder.get_logger().log("packagemgr", format("Looking for source package %s", name)); try { // Try to get source directory with pkgconfig string srcdir = strip(run_pkgconfig(name, "source")); - if(!srcdir.empty()) + if(!srcdir.empty() && FS::exists(FS::Path(srcdir)/"Build")) return srcdir; } catch(...) @@ -133,31 +184,72 @@ FS::Path PackageManager::get_package_location(const string &name) if(pkg_dirs.empty()) { - for(list::const_iterator i=pkg_path.begin(); i!=pkg_path.end(); ++i) + for(SearchPath::const_iterator i=pkg_path.begin(); i!=pkg_path.end(); ++i) { + builder.get_logger().log("files", format("Traversing %s", *i)); list files = list_files(*i); + unsigned count = 0; for(list::const_iterator j=files.begin(); j!=files.end(); ++j) { FS::Path full = *i / *j; if(FS::exists(full/"Build")) + { pkg_dirs.push_back(full); + ++count; + } } + + builder.get_logger().log("packagemgr", format("%d source packages found in %s", count, *i)); } - if(builder.get_verbose()>=3) - IO::print("%d packages found in path\n", pkg_dirs.size()); + + builder.get_logger().log("packagemgr", format("%d source packages found", pkg_dirs.size())); } bool msp = !name.compare(0, 3, "msp"); - for(list::const_iterator i=pkg_dirs.begin(); i!=pkg_dirs.end(); ++i) + for(SearchPath::const_iterator i=pkg_dirs.begin(); i!=pkg_dirs.end(); ++i) { - string base = basename(*i); + string base = FS::basename(*i); unsigned dash = base.rfind('-'); if(!base.compare(0, dash, name)) return *i; - else if(msp && !base.compare(0, dash-3, name, 3, string::npos)) + else if(msp && !base.compare(0, dash, name, 3, string::npos)) + return *i; + } + + return FS::Path(); +} + +FS::Path PackageManager::get_binary_package_file(const string &name) +{ + builder.get_logger().log("packagemgr", format("Looking for binary package %s", name)); + + if(binpkg_files.empty()) + { + for(list::const_iterator i=binpkg_path.begin(); i!=binpkg_path.end(); ++i) + { + builder.get_logger().log("files", format("Traversing %s", *i)); + list files = list_filtered(*i, "\\.bpk$"); + for(list::const_iterator j=files.begin(); j!=files.end(); ++j) + binpkg_files.push_back(*i / *j); + builder.get_logger().log("packagemgr", format("%d binary packages found in %s", files.size(), *i)); + } + + builder.get_logger().log("packagemgr", format("%d binary packages found", binpkg_files.size())); + } + + for(SearchPath::const_iterator i=binpkg_files.begin(); i!=binpkg_files.end(); ++i) + { + string base = FS::basepart(FS::basename(*i)); + if(base==name) return *i; } return FS::Path(); } + +void PackageManager::save_all_caches() const +{ + for(PackageMap::const_iterator i=packages.begin(); i!=packages.end(); ++i) + i->second->save_caches(); +}