From 6282695a77af21bd60a31d182575c5a12a1a359b Mon Sep 17 00:00:00 2001 From: slis Date: Mon, 30 Sep 2013 07:36:25 +0200 Subject: Fixed multilib support --- pym/gentoolkit/revdep_rebuild/analyse.py | 136 +++++++++++++++++++++++-------- pym/gentoolkit/revdep_rebuild/rebuild.py | 2 +- 2 files changed, 105 insertions(+), 33 deletions(-) diff --git a/pym/gentoolkit/revdep_rebuild/analyse.py b/pym/gentoolkit/revdep_rebuild/analyse.py index 1b7372c..e630bc9 100644 --- a/pym/gentoolkit/revdep_rebuild/analyse.py +++ b/pym/gentoolkit/revdep_rebuild/analyse.py @@ -20,13 +20,14 @@ def prepare_checks(files_to_check, libraries, bits, cmd_max_args): libs = [] # libs found by scanelf dependencies = [] # list of lists of files (from file_to_check) that uses # library (for dependencies[id] and libs[id] => id==id) + bits = [] # from runner import ScanRunner # sr = ScanRunner(['-M', str(bits), '-nBF', '%F %n'], files_to_check, cmd_max_args) # sr.wait() - for line in scan(['-M', str(bits), '-nBF', '%F %n'], files_to_check, cmd_max_args): + for line in scan(['-M', str(bits), '-nBF', '%F %n %M'], files_to_check, cmd_max_args): #call_program(['scanelf', '-M', str(bits), '-nBF', '%F %n',]+files_to_check).strip().split('\n'): r = line.strip().split(' ') if len(r) < 2: # no dependencies? @@ -38,12 +39,34 @@ def prepare_checks(files_to_check, libraries, bits, cmd_max_args): i = libs.index(d) dependencies[i].append(r[0]) else: + #print d, 'bits:', r[2][8:] # 8: -> strlen('ELFCLASS') libs.append(d) dependencies.append([r[0],]) return (libs, dependencies) +def scan_files(libs_and_bins, cmd_max_args): + import os + + scanned_files = {} # {bits: {soname: (filename, needed), ...}, ...} + for line in scan(['-nBF', '%F %f %S %n %M'], libs_and_bins, cmd_max_args): + filename, sfilename, soname, needed, bits = line.split(' ') + filename = os.path.realpath(filename) + needed = needed.split(',') + bits = bits[8:] # 8: -> strlen('ELFCLASS') + if not soname: + soname = sfilename + + try: + scanned_files[bits][soname] = (filename, needed) + except KeyError: + scanned_files[bits] = {} + scanned_files[bits][soname] = (filename, needed) + return scanned_files + + + def extract_dependencies_from_la(la, libraries, to_check, logger): broken = [] @@ -98,7 +121,7 @@ def find_broken(found_libs, system_libraries, to_check): # join libraries and looking at it as string is way too faster than for-jumping broken = [] - sl = '|'.join(system_libraries) + sl = '|'.join(system_libraries) + '|' if not to_check: for f in found_libs: @@ -113,6 +136,25 @@ def find_broken(found_libs, system_libraries, to_check): return broken +def find_broken2(scanned_files, logger): + broken_libs = {} + for bits, libs in scanned_files.items(): + logger.debug('Checking for bits: %s' % bits) + alllibs = '|'.join(libs.keys()) + '|' + for soname, needed in libs.items(): + for l in needed[1]: + if not l+'|' in alllibs: + try: + broken_libs[bits][l].add(soname) + except KeyError: + try: + broken_libs[bits][l] = set([soname]) + except KeyError: + broken_libs = {bits: {l: set([soname])}} + + return broken_libs + + def main_checks(found_libs, broken, dependencies, logger): ''' Checks for broken dependencies. found_libs have to be the same as returned by prepare_checks @@ -131,6 +173,18 @@ def main_checks(found_libs, broken, dependencies, logger): return broken_pathes +def main_checks2(broken, scanned_files, logger): + broken_pathes = [] + for bits, _broken in broken.items(): + for soname, needed in _broken.items(): + logger.info('Broken files that requires: %s (%s bits)' % (bold(soname), bits)) + for n in needed: + fp = scanned_files[bits][n][0] + logger.info(yellow(' * ') + n + ' (' + fp + ')') + broken_pathes.append(fp) + return broken_pathes + + def analyse(settings, logger, libraries=None, la_libraries=None, libraries_links=None, binaries=None, _libs_to_check=set()): """Main program body. It will collect all info and determine the @@ -169,56 +223,74 @@ def analyse(settings, logger, libraries=None, la_libraries=None, logger.debug('Found '+ str(len(libraries)) + ' libraries (+' + str(len(libraries_links)) + ' symlinks) and ' + str(len(binaries)) + ' binaries') + logger.info(green(' * ') + bold('Scanning files')) + + libs_and_bins = libraries+binaries + scanned_files = scan_files(libs_and_bins, settings['CMD_MAX_ARGS']) + logger.warn(green(' * ') + bold('Checking dynamic linking consistency')) logger.debug('Search for ' + str(len(binaries)+len(libraries)) + ' within ' + str(len(libraries)+len(libraries_links))) - libs_and_bins = libraries+binaries + + broken = find_broken2(scanned_files, logger) + broken_pathes = main_checks2(broken, scanned_files, logger) + + broken_la = extract_dependencies_from_la(la_libraries, libraries+libraries_links, _libs_to_check, logger) + broken_pathes += broken_la + + logger.warn(green(' * ') + bold('Assign files to packages')) + + return assign_packages(broken_pathes, logger, settings) + import sys + sys.exit() + #l = [] #for line in call_program(['scanelf', '-M', '64', '-BF', '%F',] + libraries).strip().split('\n'): #l.append(line) #libraries = l - found_libs = [] - dependencies = [] + ## old version from here + #found_libs = [] + #dependencies = [] - if _libs_to_check: - nltc = [] - for ltc in _libs_to_check: - if os.path.isfile(ltc): - ltc = scan(['-nBSF', '%S'], [ltc,], settings['CMD_MAX_ARGS'])[0].split()[0] - nltc += [ltc,] - _libs_to_check = nltc + #if _libs_to_check: + #nltc = [] + #for ltc in _libs_to_check: + #if os.path.isfile(ltc): + #ltc = scan(['-nBSF', '%S'], [ltc,], settings['CMD_MAX_ARGS'])[0].split()[0] + #nltc += [ltc,] + #_libs_to_check = nltc - _bits, linkg = platform.architecture() - if _bits.startswith('32'): - bits = 32 - elif _bits.startswith('64'): - bits = 64 + #_bits, linkg = platform.architecture() + #if _bits.startswith('32'): + #bits = 32 + #elif _bits.startswith('64'): + #bits = 64 - import time - broken = [] - for av_bits in glob.glob('/lib[0-9]*') or ('/lib32',): - bits = int(av_bits[4:]) + #import time + #broken = [] + #for av_bits in glob.glob('/lib[0-9]*') or ('/lib32',): + #bits = int(av_bits[4:]) - #_libraries = scan(['-M', str(bits), '-BF', '%F'], libraries+libraries_links, settings['CMD_MAX_ARGS']) - _libraries = libraries+libraries_links + ##_libraries = scan(['-M', str(bits), '-BF', '%F'], libraries+libraries_links, settings['CMD_MAX_ARGS']) + #_libraries = libraries+libraries_links - found_libs, dependencies = prepare_checks(libs_and_bins, _libraries, bits, settings['CMD_MAX_ARGS']) - broken = find_broken(found_libs, _libraries, _libs_to_check) + #found_libs, dependencies = prepare_checks(libs_and_bins, _libraries, bits, settings['CMD_MAX_ARGS']) + #broken = find_broken(found_libs, _libraries, _libs_to_check) - bits /= 2 - bits = int(bits) + #bits /= 2 + #bits = int(bits) - broken_la = extract_dependencies_from_la(la_libraries, libraries+libraries_links, _libs_to_check, logger) + #broken_la = extract_dependencies_from_la(la_libraries, libraries+libraries_links, _libs_to_check, logger) - broken_pathes = main_checks(found_libs, broken, dependencies, logger) - broken_pathes += broken_la + #broken_pathes = main_checks(found_libs, broken, dependencies, logger) + #broken_pathes += broken_la - logger.warn(green(' * ') + bold('Assign files to packages')) + #logger.warn(green(' * ') + bold('Assign files to packages')) - return assign_packages(broken_pathes, logger, settings) + #return assign_packages(broken_pathes, logger, settings) diff --git a/pym/gentoolkit/revdep_rebuild/rebuild.py b/pym/gentoolkit/revdep_rebuild/rebuild.py index cfceacc..a943902 100644 --- a/pym/gentoolkit/revdep_rebuild/rebuild.py +++ b/pym/gentoolkit/revdep_rebuild/rebuild.py @@ -240,5 +240,5 @@ def main(settings=None, logger=None): if __name__ == '__main__': - main(rebuild.parse_options()) + main(parse_options()) -- cgit v1.2.3