Example #1
0
    def __init__(self):
        """ Allows us to do look ups on all packages """
        self.idb = InstallDB()
        self.pdb = PackageDB()
        self.fdb = FilesDB()

        # Cache the pkgconfigs known in the pdb
        self.pkgConfigs, self.pkgConfigs32 = self.pdb.get_pkgconfig_providers()
Example #2
0
class DependencyResolver:

    idb = None
    pdb = None
    fdb = None

    global_rpaths = set()
    global_rpaths32 = set()
    global_sonames = dict()
    global_sonames32 = dict()
    global_pkgconfigs = dict()
    global_pkgconfig32s = dict()
    global_kernels = dict()
    gene = None

    bindeps_cache = dict()
    bindeps_emul32 = dict()

    pkgconfig_cache = dict()
    pkgconfig32_cache = dict()

    files_cache = dict()

    kernel_cache = dict()

    deadends = dict()

    # Cached from packagedb
    pkgConfigs = None
    pkgConfigs32 = None

    def search_file(self, fname):
        if fname[0] == '/':
            fname = fname[1:]
        if fname in self.deadends:
            return None
        if self.fdb.has_file(fname):
            return self.fdb.get_file(fname)
        # Nasty file conflict crap happened on update and the filesdb
        # is now inconsistent ..
        ret = self.fdb.search_file(fname)
        if len(ret) == 1:
            return ret[0]
        # Just blacklist further lookups here
        self.deadends[fname] = 0
        return None

    def __init__(self):
        """ Allows us to do look ups on all packages """
        self.idb = InstallDB()
        self.pdb = PackageDB()
        self.fdb = FilesDB()

        # Cache the pkgconfigs known in the pdb
        self.pkgConfigs, self.pkgConfigs32 = self.pdb.get_pkgconfig_providers()

    def get_symbol_provider(self, info, symbol):
        """ Grab the symbol from the local packages """
        if info.emul32:
            tgtMap = self.global_sonames32
            rPaths = self.global_rpaths32
        else:
            tgtMap = self.global_sonames
            rPaths = self.global_rpaths

        if symbol in tgtMap:
            pkgname = tgtMap[symbol]
            return self.ctx.spec.get_package_name(pkgname)

        # Check if its in any rpath
        for rpath in rPaths:
            fpath = os.path.join(rpath, symbol)
            pkg = self.gene.get_file_owner(fpath)
            if pkg:
                return self.ctx.spec.get_package_name(pkg.name)
        return None

    def get_symbol_external(self, info, symbol, paths=None):
        """ Get the provider of the required symbol from the files database,
            i.e. installed binary dependencies
        """
        # Try a cached approach first.
        if info.emul32:
            if symbol in self.bindeps_emul32:
                return self.bindeps_emul32[symbol]
        else:
            if symbol in self.bindeps_cache:
                return self.bindeps_cache[symbol]

        if symbol in ExceptionRules:
            if info.emul32:
                return "libglvnd-32bit"
            else:
                return "libglvnd"

        if not paths:
            paths = ["/usr/lib64", "/usr/lib"]
            if info.emul32:
                paths = ["/usr/lib32", "/usr/lib", "/usr/lib64"]

            if info.rpaths:
                paths.extend(info.rpaths)

        pkg = None
        for path in paths:
            fpath = os.path.join(path, symbol)
            if not os.path.exists(fpath):
                continue
            lpkg = None
            if fpath in self.files_cache:
                lpkg = self.files_cache[fpath]
            else:
                pkg = self.search_file(fpath)
                if pkg:
                    lpkg = pkg[0]
            if lpkg:
                if info.emul32:
                    self.bindeps_emul32[symbol] = lpkg
                else:
                    self.bindeps_cache[symbol] = lpkg
                console_ui.emit_info(
                    "Dependency", "{} adds dependency on {} from {}".format(
                        info.pretty, symbol, lpkg))

                # Populate a global files cache, basically there is a high
                # chance that each package depends on multiple things in a
                # single package.
                for file in self.idb.get_files(lpkg).list:
                    self.files_cache["/" + file.path] = lpkg
                return lpkg
        return None

    def get_pkgconfig_provider(self, info, name):
        """ Get the internal provider for a pkgconfig name """
        if info.emul32:
            if name in self.global_pkgconfig32s:
                pkg = self.global_pkgconfig32s[name]
                return self.ctx.spec.get_package_name(pkg)
        if name in self.global_pkgconfigs:
            pkg = self.global_pkgconfigs[name]
            return self.ctx.spec.get_package_name(pkg)
        return None

    def get_pkgconfig_external(self, info, name):
        """ Get the external provider of a pkgconfig name """
        pkg = None

        if info.emul32:
            if name in self.pkgconfig32_cache:
                return self.pkgconfig32_cache[name]
        else:
            if name in self.pkgconfig_cache:
                return self.pkgconfig_cache[name]

        if info.emul32:
            # InstallDB set
            nom = self.fdb.get_pkgconfig32_provider(name)
            if nom:
                pkg = self.idb.get_package(nom[0])
            if not pkg:
                nom = self.fdb.get_pkgconfig_provider(name)
                if nom:
                    pkg = self.idb.get_package(nom[0])

            # PackageDB set
            if not pkg:
                if name in self.pkgConfigs32:
                    pkg = self.pdb.get_package(self.pkgConfigs32[name])
            if not pkg:
                if name in self.pkgConfigs:
                    pkg = self.pdb.get_package(self.pkgConfigs[name])
        else:
            nom = self.fdb.get_pkgconfig_provider(name)
            if nom:
                pkg = self.idb.get_package(nom[0])
            if not pkg:
                if name in self.pkgConfigs:
                    pkg = self.pdb.get_package(self.pkgConfigs[name])

        if not pkg:
            return None
        if info.emul32:
            self.pkgconfig32_cache[name] = pkg.name
        else:
            self.pkgconfig_cache[name] = pkg.name
        return pkg.name

    def handle_binary_deps(self, packageName, info):
        """ Handle direct binary dependencies """
        pkgName = self.ctx.spec.get_package_name(packageName)

        for sym in info.symbol_deps:
            r = self.get_symbol_provider(info, sym)
            if not r:
                r = self.get_symbol_external(info, sym)
                if not r:
                    print("Fatal: Unknown symbol: {}".format(sym))
                    continue
            # Don't self depend
            if pkgName == r:
                continue
            self.gene.packages[packageName].depend_packages.add(r)

    def handle_pkgconfig_deps(self, packageName, info):
        """ Handle pkgconfig dependencies """
        pkgName = self.ctx.spec.get_package_name(packageName)

        for item in info.pkgconfig_deps:

            prov = self.get_pkgconfig_provider(info, item)
            if not prov:
                prov = self.get_pkgconfig_external(info, item)

            if not prov:
                console_ui.emit_warning(
                    "PKGCONFIG", "Not adding unknown"
                    " dependency {} to {}".format(item, pkgName))
                continue
            tgtPkg = self.gene.packages[packageName]

            # Yes, it's a set, but i  dont want the ui emission spam
            if prov in tgtPkg.depend_packages:
                continue
            # Forbid circular dependencies
            if pkgName == prov:
                continue
            tgtPkg.depend_packages.add(prov)

            console_ui.emit_info(
                "PKGCONFIG", "{} adds dependency on {}".format(pkgName, prov))

    def handle_pkgconfig_provides(self, packageName, info):
        adder = None
        if info.emul32:
            adder = "pkgconfig32({})".format(info.pkgconfig_name)
        else:
            adder = "pkgconfig({})".format(info.pkgconfig_name)
        # TODO: Add versioning in examine.py .. ?
        self.gene.packages[packageName].provided_symbols.add(adder)
        pass

    def handle_soname_links(self, packageName, info):
        """ Add dependencies between packages due to a .so splitting """
        ourName = self.ctx.spec.get_package_name(packageName)

        for link in info.soname_links:
            fi = self.gene.get_file_owner(link)
            if not fi:
                console_ui.emit_warning(
                    "SOLINK", "{} depends on non existing "
                    "soname link: {}".format(packageName, link))
                continue
            pkgName = self.ctx.spec.get_package_name(fi.name)
            if pkgName == ourName:
                continue
            self.gene.packages[packageName].depend_packages.add(pkgName)
            console_ui.emit_info(
                "SOLINK",
                "{} depends on {} through .so link".format(ourName, pkgName))

    def get_kernel_provider(self, info, version):
        """ i.e. self dependency situation """
        if version in self.global_kernels:
            pkg = self.global_kernels[version]
            return self.ctx.spec.get_package_name(pkg)
        return None

    def get_kernel_external(self, info, version):
        """ Try to find the owning kernel for a version """
        if version in self.kernel_cache:
            return self.kernel_cache[version]

        paths = ["/usr/lib/kernel", "/usr/lib64/kernel"]

        pkg = None
        for path in paths:
            # Special file in the main kernel package
            fpath = "{}/System.map-{}".format(path, version)
            if not os.path.exists(fpath):
                continue
            lpkg = None
            if fpath in self.files_cache:
                lpkg = self.files_cache[fpath]
            else:
                pkg = self.search_file(fpath)
                if pkg:
                    lpkg = pkg[0]
            if lpkg:
                self.kernel_cache[version] = lpkg
                console_ui.emit_info(
                    "Kernel", "{} adds module dependency on {} from {}".format(
                        info.pretty, version, lpkg))

                # Populate a global files cache, basically there is a high
                # chance that each package depends on multiple things in a
                # single package.
                for file in self.idb.get_files(lpkg).list:
                    self.files_cache["/" + file.path] = lpkg
                return lpkg
        return None

    def handle_kernel_deps(self, packageName, info):
        """ Add dependency between packages due to kernel version """
        pkgName = self.ctx.spec.get_package_name(packageName)

        r = self.get_kernel_provider(info, info.dep_kernel)
        if not r:
            r = self.get_kernel_external(info, info.dep_kernel)
            if not r:
                print("Fatal: Unknown kernel: {}".format(sym))
                return
        # Don't self depend
        if pkgName == r:
            return
        self.gene.packages[packageName].depend_packages.add(r)

    def compute_for_packages(self, context, gene, packageSet):
        """ packageSet is a dict mapping here. """
        self.gene = gene
        self.packageSet = packageSet
        self.ctx = context

        # First iteration, collect the globals
        for packageName in packageSet:
            for info in packageSet[packageName]:
                if info.rpaths:
                    if info.emul32:
                        self.global_rpaths32.update(info.rpaths)
                    else:
                        self.global_rpaths.update(info.rpaths)
                if info.soname:
                    if info.emul32:
                        self.global_sonames32[info.soname] = packageName
                    else:
                        self.global_sonames[info.soname] = packageName
                if info.pkgconfig_name:
                    pcName = info.pkgconfig_name
                    if info.emul32:
                        self.global_pkgconfig32s[pcName] = packageName
                    else:
                        self.global_pkgconfigs[pcName] = packageName
                if info.prov_kernel:
                    self.global_kernels[info.prov_kernel] = packageName

        # Ok now find the dependencies
        for packageName in packageSet:
            for info in packageSet[packageName]:
                if info.symbol_deps:
                    self.handle_binary_deps(packageName, info)

                if info.pkgconfig_deps:
                    self.handle_pkgconfig_deps(packageName, info)

                if info.pkgconfig_name:
                    self.handle_pkgconfig_provides(packageName, info)

                if info.soname_links:
                    self.handle_soname_links(packageName, info)

                if info.dep_kernel:
                    self.handle_kernel_deps(packageName, info)
        return True
Example #3
0
 def __init__(self):
     """ Allows us to do look ups on all packages """
     self.idb = InstallDB()
     self.pdb = PackageDB()
     self.fdb = FilesDB()
Example #4
0
#!/usr/bin/env python
#-*- coding: utf-8 -*-

# Kutuphaneler import ediliyor
from pisi.db.filesdb import FilesDB
import re
import sys

# files_db sinifi ornekleniyor
files_db = FilesDB()
dosyalar = files_db.search_file(".pc")

#listeler tanımlanıyor-----------------------------------------
dep_list = []
dep_list_duzenli = []
dep_tam_list = []
bulunanlar = []
sirala = []

#kümeler tanımlanıyor------------------------------------------
piside_nedir = {}
version = {}

#dosya okunuyor------------------------------------------------

pkg_dep = sys.argv[1]
pkg_dep_oku = open(pkg_dep, "r")
parcala = pkg_dep_oku.readlines()
pkg_dep_oku.close()

#fonksiyonlar tanımlanıyor-------------------------------------
Example #5
0
#!/usr/bin/env python
#-*- coding: utf-8 -*-

# Kutuphaneler import ediliyor
from pisi.db.filesdb import FilesDB
import re
import sys

# files_db sinifi ornekleniyor
files_db = FilesDB()
dosyalar = files_db.search_file("Config.cmake") + files_db.search_file(".pc")

# kullanilacak listeler tanimlaniyor

deb_liste = []
deb_liste_parcali = []
bagimliliklar = []
arama_list = []
bulunanlar = []
yazdirilacak = []
set_list = []
pspec_listele = []
bulunanlar_pc = []

# kullanilacak kumeler tanimlaniyor

#sozlukler tanimlaniyor

version_hepsi = {}
karsilik_version_isim = {}
piside_nedir = {}
Example #6
0
with open(cmake_file) as file_cmake:
	# dosya satır satır okunuyor ve istenilen veriler ayıklanıyor.
	for line in file_cmake.readlines():
		compile = re.compile(r"^find_package\((.*) +[0-9][A-Z]\)")
		obje = compile.search(line)
		if obje:
			# istenilen veri varsa listeye ekliyoruz.
			package_list.append(obje.groups()[0].split(" ")[0])

		compile = re.compile(r"^find_package\((.*)\)\n")
		obje = compile.search(line)
		if obje:
			# istenilen veri varsa listeye ekliyoruz.
			package_list.append(obje.groups()[0].split(" ")[0])

files_db = FilesDB()

print package_list # Aranacak verileri yazdırıyoruz.

counter = 0
packages = []
for package in package_list:
	liste = files_db.search_file(package)

	#aranan veri değer döndürürse döngü başlar
	if liste:
		# liste içinde liste.
		for li in liste:
			# ilk liste ögesi(li[0]) paket adı, ikincisi de(li[-1]) liste halinde aranan kelimenin geçtiği dosyalar.
			for l in li[-1]:
				# dosyaların uzantısı *.cmake olanları ayıklayıp çıktı veriyoruz.
Example #7
0
    for line in file_cmake.readlines():
        compile = re.compile(r"^find_package\((.*) +[0-9][A-Z]\)")
        obje = compile.search(line)

        if obje:
            # istenilen veri varsa listeye ekliyoruz.
            package_list.append(obje.groups()[0].split(" ")[0])

        compile = re.compile(r"^find_package\((.*)\)\n")
        obje = compile.search(line)

        if obje:
            # istenilen veri varsa listeye ekliyoruz.
            package_list.append(obje.groups()[0].split(" ")[0])

files_db = FilesDB()

print package_list # Aranacak verileri yazdırıyoruz.

counter = 0
packages = []

for package in package_list:
    liste = files_db.search_file(package)

    # aranan veri değer döndürürse döngü başlar
    if liste:
        for li in liste:
            for l in li[-1]:
                # dosyaların uzantısı *.cmake olanları ayıklayıp çıktı veriyoruz.
                if (l.startswith("usr/share/%s/" % package) or l.startswith("usr/lib/cmake/%s/" % package)) and l.endswith("cmake"):