public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] proj/portage:prefix commit in: pym/portage/util/_dyn_libs/
@ 2011-05-14 13:59 Fabian Groffen
  0 siblings, 0 replies; 17+ messages in thread
From: Fabian Groffen @ 2011-05-14 13:59 UTC (permalink / raw
  To: gentoo-commits

commit:     5f826caddbc8b4eb68e2c535d47b2025ed3d2e32
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Sat May 14 13:56:32 2011 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Sat May 14 13:56:32 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=5f826cad

LinkageMap*: align with LinkageMapELF

Prefix' non-ELF LinkageMaps have diverged from the ELF map over time a
bit.  Manually vimdiffed all against the ELF map.

---
 pym/portage/util/_dyn_libs/LinkageMapMachO.py  |  121 ++++++++++++-----
 pym/portage/util/_dyn_libs/LinkageMapPeCoff.py |  128 +++++++++++++++----
 pym/portage/util/_dyn_libs/LinkageMapXCoff.py  |  170 ++++++++++++++---------
 3 files changed, 295 insertions(+), 124 deletions(-)

diff --git a/pym/portage/util/_dyn_libs/LinkageMapMachO.py b/pym/portage/util/_dyn_libs/LinkageMapMachO.py
index f03215a..cbdf6c2 100644
--- a/pym/portage/util/_dyn_libs/LinkageMapMachO.py
+++ b/pym/portage/util/_dyn_libs/LinkageMapMachO.py
@@ -1,4 +1,4 @@
-# Copyright 1998-2010 Gentoo Foundation
+# Copyright 1998-2011 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 
 import errno
@@ -29,7 +29,7 @@ class LinkageMapMachO(object):
 
 	def __init__(self, vardbapi):
 		self._dbapi = vardbapi
-		self._root = self._dbapi.root
+		self._root = self._dbapi.settings['ROOT']
 		self._libs = {}
 		self._obj_properties = {}
 		self._obj_key_cache = {}
@@ -109,7 +109,7 @@ class LinkageMapMachO(object):
 				else:
 					os = portage.os
 
-			abs_path = os.path.join(root, obj.lstrip(os.path.sep))
+			abs_path = os.path.join(root, obj.lstrip(os.sep))
 			try:
 				object_stat = os.stat(abs_path)
 			except OSError:
@@ -141,55 +141,98 @@ class LinkageMapMachO(object):
 		def __str__(self):
 			return str(sorted(self.alt_paths))
 
-	def rebuild(self, exclude_pkgs=None, include_file=None):
+	def rebuild(self, exclude_pkgs=None, include_file=None,
+		preserve_paths=None):
 		"""
 		Raises CommandNotFound if there are preserved libs
 		and the scanmacho binary is not available.
+
+		@param exclude_pkgs: A set of packages that should be excluded from
+			the LinkageMap, since they are being unmerged and their NEEDED
+			entries are therefore irrelevant and would only serve to corrupt
+			the LinkageMap.
+		@type exclude_pkgs: set
+		@param include_file: The path of a file containing NEEDED entries for
+			a package which does not exist in the vardbapi yet because it is
+			currently being merged.
+		@type include_file: String
+		@param preserve_paths: Libraries preserved by a package instance that
+			is currently being merged. They need to be explicitly passed to the
+			LinkageMap, since they are not registered in the
+			PreservedLibsRegistry yet.
+		@type preserve_paths: set
 		"""
+
+		os = _os_merge
 		root = self._root
 		root_len = len(root) - 1
 		self._clear_cache()
 		libs = self._libs
-		obj_key_cache = self._obj_key_cache
 		obj_properties = self._obj_properties
 
-		os = _os_merge
-
 		lines = []
 
 		# Data from include_file is processed first so that it
 		# overrides any data from previously installed files.
 		if include_file is not None:
-			lines += grabfile(include_file)
+			for line in grabfile(include_file):
+				lines.append((include_file, line))
 
 		aux_keys = [self._needed_aux_key]
-		for cpv in self._dbapi.cpv_all():
-			if exclude_pkgs is not None and cpv in exclude_pkgs:
-				continue
-			lines += self._dbapi.aux_get(cpv, aux_keys)[0].split('\n')
-		# Cache NEEDED.* files avoid doing excessive IO for every rebuild.
-		self._dbapi.flush_cache()
+		can_lock = os.access(os.path.dirname(self._dbapi._dbroot), os.W_OK)
+		if can_lock:
+			self._dbapi.lock()
+		try:
+			for cpv in self._dbapi.cpv_all():
+				if exclude_pkgs is not None and cpv in exclude_pkgs:
+					continue
+				needed_file = self._dbapi.getpath(cpv,
+					filename=self._needed_aux_key)
+				for line in self._dbapi.aux_get(cpv, aux_keys)[0].splitlines():
+					lines.append((needed_file, line))
+		finally:
+			if can_lock:
+				self._dbapi.unlock()
 
 		# have to call scanmacho for preserved libs here as they aren't 
 		# registered in NEEDED.MACHO.3 files
 		plibs = set()
-		if self._dbapi._plib_registry and self._dbapi._plib_registry.getPreservedLibs():
-			args = [EPREFIX+"/usr/bin/scanmacho", "-qF", "%a;%F;%S;%n"]
-			for items in self._dbapi._plib_registry.getPreservedLibs().values():
+		if preserve_paths is not None:
+			plibs.update(preserve_paths)
+		if self._dbapi._plib_registry and \
+			self._dbapi._plib_registry.hasEntries():
+			for cpv, items in \
+				self._dbapi._plib_registry.getPreservedLibs().items():
+				if exclude_pkgs is not None and cpv in exclude_pkgs:
+					# These preserved libs will either be unmerged,
+					# rendering them irrelevant, or they will be
+					# preserved in the replacement package and are
+					# already represented via the preserve_paths
+					# parameter.
+					continue
 				plibs.update(items)
-				args.extend(os.path.join(root, x.lstrip("." + os.sep)) \
-						for x in items)
+		if plibs:
+			args = [EPREFIX+"/usr/bin/scanmacho", "-qF", "%a;%F;%S;%n"]
+			args.extend(os.path.join(root, x.lstrip("." + os.sep)) \
+				for x in plibs)
 			try:
 				proc = subprocess.Popen(args, stdout=subprocess.PIPE)
-			except EnvironmentError, e:
+			except EnvironmentError as e:
 				if e.errno != errno.ENOENT:
 					raise
 				raise CommandNotFound(args[0])
 			else:
 				for l in proc.stdout:
-					if not isinstance(l, unicode):
-						l = unicode(l, encoding='utf_8', errors='replace')
-					l = l.rstrip("\n")
+					try:
+						l = _unicode_decode(l,
+							encoding=_encodings['content'], errors='strict')
+					except UnicodeDecodeError:
+						l = _unicode_decode(l,
+							encoding=_encodings['content'], errors='replace')
+						writemsg_level(_("\nError decoding characters " \
+							"returned from scanmacho: %s\n\n") % (l,),
+							level=logging.ERROR, noiselevel=-1)
+					l = l[3:].rstrip("\n")
 					if not l:
 						continue
 					fields = l.split(";")
@@ -200,7 +243,7 @@ class LinkageMapMachO(object):
 						continue
 					fields[1] = fields[1][root_len:]
 					plibs.discard(fields[1])
-					lines.append(";".join(fields))
+					lines.append(("scanmacho", ";".join(fields)))
 				proc.wait()
 
 		if plibs:
@@ -211,16 +254,16 @@ class LinkageMapMachO(object):
 			# self._obj_properties.  This is important in order to
 			# prevent findConsumers from raising an unwanted KeyError.
 			for x in plibs:
-				lines.append(";".join(['', x, '', '']))
+				lines.append(("plibs", ";".join(['', x, '', '', ''])))
 
-		for l in lines:
+		for location, l in lines:
 			l = l.rstrip("\n")
 			if not l:
 				continue
 			fields = l.split(";")
 			if len(fields) < 4:
 				writemsg_level("\nWrong number of fields " + \
-					"in %s: %s\n\n" % (self._needed_aux_key, l),
+					"in %s: %s\n\n") % (location, l),
 					level=logging.ERROR, noiselevel=-1)
 				continue
 			arch = fields[0]
@@ -263,7 +306,7 @@ class LinkageMapMachO(object):
 						providers=set(), consumers=set())
 					arch_map[needed_installname] = installname_map
 				installname_map.consumers.add(obj_key)
-		
+
 	def listBrokenBinaries(self, debug=False):
 		"""
 		Find binaries and their needed install_names, which have no providers.
@@ -277,6 +320,7 @@ class LinkageMapMachO(object):
 			corresponding libraries to fulfill the dependency.
 
 		"""
+
 		os = _os_merge
 
 		class _LibraryCache(object):
@@ -377,10 +421,14 @@ class LinkageMapMachO(object):
 						rValue.setdefault(lib, set()).add(install_name)
 						if debug:
 							if not os.path.isfile(lib):
-								print(_("Missing library:"), lib)
+								writemsg_level(_("Missing library:") + " %s\n" % (lib,),
+									level=logging.DEBUG,
+									noiselevel=-1)
 							else:
-								print(_("Possibly missing symlink:"), \
-										install_name)
+								writemsg_level(_("Possibly missing symlink:") + \
+									"%s\n" % (os.path.join(os.path.dirname(lib), soname)),
+									level=logging.DEBUG,
+									noiselevel=-1)
 		return rValue
 
 	def listProviders(self):
@@ -397,7 +445,7 @@ class LinkageMapMachO(object):
 		rValue = {}
 		if not self._libs:
 			self.rebuild()
-		# Iterate over all binaries within LinkageMapMachO.
+		# Iterate over all object keys within LinkageMapMachO.
 		for obj_key in self._obj_properties:
 			rValue.setdefault(obj_key, self.findProviders(obj_key))
 		return rValue
@@ -440,7 +488,7 @@ class LinkageMapMachO(object):
 				for obj_key in soname_map.providers:
 					rValue.extend(self._obj_properties[obj_key][3])
 		return rValue
-	
+
 	def getSoname(self, obj):
 		"""
 		Return the soname associated with an object.
@@ -482,6 +530,7 @@ class LinkageMapMachO(object):
 		set-of-library-paths satisfy install_name.
 
 		"""
+
 		os = _os_merge
 
 		rValue = {}
@@ -531,6 +580,11 @@ class LinkageMapMachO(object):
 		fail to preserve binutils libs that are needed by these unrecognized
 		consumers.
 
+		Note that library consumption via dlopen (common for kde plugins) is
+		currently undetected. However, it is possible to use the
+		corresponding libtool archive (*.la) files to detect such consumers
+		(revdep-rebuild is able to detect them).
+
 		@param obj: absolute path to an object or a key from _obj_properties
 		@type obj: string (example: '/usr/bin/bar') or _ObjectKey
 		@rtype: set of strings (example: set(['/bin/foo', '/usr/bin/bar']))
@@ -538,6 +592,7 @@ class LinkageMapMachO(object):
 		set-of-library-paths satisfy install_name.
 
 		"""
+
 		os = _os_merge
 
 		rValue = set()

diff --git a/pym/portage/util/_dyn_libs/LinkageMapPeCoff.py b/pym/portage/util/_dyn_libs/LinkageMapPeCoff.py
index 9df84f1..c90947e 100644
--- a/pym/portage/util/_dyn_libs/LinkageMapPeCoff.py
+++ b/pym/portage/util/_dyn_libs/LinkageMapPeCoff.py
@@ -1,4 +1,4 @@
-# Copyright 1998-2010 Gentoo Foundation
+# Copyright 1998-2011 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 
 import errno
@@ -46,7 +46,24 @@ class LinkageMapPeCoff(LinkageMapELF):
 			@return:
 				2-tuple of boolean indicating existance, and absolut path
 			"""
+
 			os = _os_merge
+
+			try:
+				_unicode_encode(obj,
+					encoding=_encodings['merge'], errors='strict')
+			except UnicodeEncodeError:
+				# The package appears to have been merged with a 
+				# different value of sys.getfilesystemencoding(),
+				# so fall back to utf_8 if appropriate.
+				try:
+					_unicode_encode(obj,
+						encoding=_encodings['fs'], errors='strict')
+				except UnicodeEncodeError:
+					pass
+				else:
+					os = portage.os
+
 			abs_path = os.path.join(root, obj.lstrip(os.sep))
 			try:
 				object_stat = os.stat(abs_path)
@@ -78,67 +95,130 @@ class LinkageMapPeCoff(LinkageMapELF):
 		def __str__(self):
 			return str(sorted(self.alt_paths))
 
-	def rebuild(self, exclude_pkgs=None, include_file=None):
+	def rebuild(self, exclude_pkgs=None, include_file=None,
+		preserve_paths=None):
 		"""
 		Raises CommandNotFound if there are preserved libs
 		and the readpecoff binary is not available.
+
+		@param exclude_pkgs: A set of packages that should be excluded from
+			the LinkageMap, since they are being unmerged and their NEEDED
+			entries are therefore irrelevant and would only serve to corrupt
+			the LinkageMap.
+		@type exclude_pkgs: set
+		@param include_file: The path of a file containing NEEDED entries for
+			a package which does not exist in the vardbapi yet because it is
+			currently being merged.
+		@type include_file: String
+		@param preserve_paths: Libraries preserved by a package instance that
+			is currently being merged. They need to be explicitly passed to the
+			LinkageMap, since they are not registered in the
+			PreservedLibsRegistry yet.
+		@type preserve_paths: set
 		"""
+
+		os = _os_merge
 		root = self._root
 		root_len = len(root) - 1
 		self._clear_cache()
 		self._defpath.update(getlibpaths(self._root))
 		libs = self._libs
-		obj_key_cache = self._obj_key_cache
 		obj_properties = self._obj_properties
 
-		os = _os_merge
-
 		lines = []
 
 		# Data from include_file is processed first so that it
 		# overrides any data from previously installed files.
 		if include_file is not None:
-			lines += grabfile(include_file)
+			for line in grabfile(include_file):
+				lines.append((include_file, line))
 
 		aux_keys = [self._needed_aux_key]
-		for cpv in self._dbapi.cpv_all():
-			if exclude_pkgs is not None and cpv in exclude_pkgs:
-				continue
-			lines += self._dbapi.aux_get(cpv, aux_keys)[0].split('\n')
-		# Cache NEEDED.* files avoid doing excessive IO for every rebuild.
-		self._dbapi.flush_cache()
+		can_lock = os.access(os.path.dirname(self._dbapi._dbroot), os.W_OK)
+		if can_lock:
+			self._dbapi.lock()
+		try:
+			for cpv in self._dbapi.cpv_all():
+				if exclude_pkgs is not None and cpv in exclude_pkgs:
+					continue
+				needed_file = self._dbapi.getpath(cpv,
+					filename=self._needed_aux_key)
+				for line in self._dbapi.aux_get(cpv, aux_keys)[0].splitlines():
+					lines.append((needed_file, line))
+		finally:
+			if can_lock:
+				self._dbapi.unlock()
 
 		# have to call readpecoff for preserved libs here as they aren't 
 		# registered in NEEDED.PECOFF.1 files
-		if self._dbapi._plib_registry and self._dbapi._plib_registry.getPreservedLibs():
+		plibs = set()
+		if preserve_paths is not None:
+			plibs.update(preserve_paths)
+		if self._dbapi._plib_registry and \
+			self._dbapi._plib_registry.hasEntries():
+			for cpv, items in \
+				self._dbapi._plib_registry.getPreservedLibs().items():
+				if exclude_pkgs is not None and cpv in exclude_pkgs:
+					# These preserved libs will either be unmerged,
+					# rendering them irrelevant, or they will be
+					# preserved in the replacement package and are
+					# already represented via the preserve_paths
+					# parameter.
+					continue
+				plibs.update(items)
+		if plibs:
 			args = ["readpecoff", self._dbapi.settings.get('CHOST')]
-			for items in self._dbapi._plib_registry.getPreservedLibs().values():
-				args.extend(os.path.join(root, x.lstrip("." + os.path.sep)) \
-					for x in items)
+			args.extend(os.path.join(root, x.lstrip("." + os.sep)) \
+				for x in plibs)
 			try:
 				proc = subprocess.Popen(args, stdout=subprocess.PIPE)
-			except EnvironmentError, e:
+			except EnvironmentError as e:
 				if e.errno != errno.ENOENT:
 					raise
 				raise CommandNotFound(args[0])
 			else:
 				for l in proc.stdout:
-					if not isinstance(l, unicode):
-						l = unicode(l, encoding='utf_8', errors='replace')
-					l = l.lstrip().rstrip()
+					try:
+						l = _unicode_decode(l,
+							encoding=_encodings['content'], errors='strict')
+					except UnicodeDecodeError:
+						l = _unicode_decode(l,
+							encoding=_encodings['content'], errors='replace')
+						writemsg_level(_("\nError decoding characters " \
+							"returned from readpecoff: %s\n\n") % (l,),
+							level=logging.ERROR, noiselevel=-1)
+					l = l[3:].rstrip("\n")
 					if not l:
 						continue
-					lines.append(l)
+					fields = l.split(";")
+					if len(fields) < 5:
+						writemsg_level(_("\nWrong number of fields " \
+							"returned from readpecoff: %s\n\n") % (l,),
+							level=logging.ERROR, noiselevel=-1)
+						continue
+					fields[1] = fields[1][root_len:]
+					plibs.discard(fields[1])
+					lines.append(("readpecoff", ";".join(fields)))
 				proc.wait()
 
-		for l in lines:
+		if plibs:
+			# Preserved libraries that did not appear in the scanelf output.
+			# This is known to happen with statically linked libraries.
+			# Generate dummy lines for these, so we can assume that every
+			# preserved library has an entry in self._obj_properties. This
+			# is important in order to prevent findConsumers from raising
+			# an unwanted KeyError.
+			for x in plibs:
+				lines.append(("plibs", ";".join(['', x, '', '', ''])))
+
+		for location, l in lines:
 			l = l.rstrip("\n")
 			if not l:
 				continue
 			fields = l.split(";")
 			if len(fields) < 5:
 				writemsg_level(_("\nWrong number of fields " \
-					"in %s: %s\n\n") % (self._needed_aux_key, l),
+					"in %s: %s\n\n") % (location, l),
 					level=logging.ERROR, noiselevel=-1)
 				continue
 			arch = fields[0]
@@ -148,7 +228,7 @@ class LinkageMapPeCoff(LinkageMapELF):
 				for x in filter(None, fields[3].replace(
 				"${ORIGIN}", os.path.dirname(obj)).replace(
 				"$ORIGIN", os.path.dirname(obj)).split(":"))])
-			needed = filter(None, fields[4].split(","))
+			needed = [x for x in fields[4].split(",") if x]
 
 			obj_key = self._obj_key(obj)
 			indexed = True

diff --git a/pym/portage/util/_dyn_libs/LinkageMapXCoff.py b/pym/portage/util/_dyn_libs/LinkageMapXCoff.py
index a6233b1..0e930fe 100644
--- a/pym/portage/util/_dyn_libs/LinkageMapXCoff.py
+++ b/pym/portage/util/_dyn_libs/LinkageMapXCoff.py
@@ -1,4 +1,4 @@
-# Copyright 1998-2010 Gentoo Foundation
+# Copyright 1998-2011 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 
 import errno
@@ -96,10 +96,26 @@ class LinkageMapXCoff(LinkageMapELF):
 		def __str__(self):
 			return str(sorted(self.alt_paths))
 
-	def rebuild(self, exclude_pkgs=None, include_file=None):
+	def rebuild(self, exclude_pkgs=None, include_file=None,
+		preserve_paths=None):
 		"""
 		Raises CommandNotFound if there are preserved libs
 		and the scanelf binary is not available.
+
+		@param exclude_pkgs: A set of packages that should be excluded from
+			the LinkageMap, since they are being unmerged and their NEEDED
+			entries are therefore irrelevant and would only serve to corrupt
+			the LinkageMap.
+		@type exclude_pkgs: set
+		@param include_file: The path of a file containing NEEDED entries for
+			a package which does not exist in the vardbapi yet because it is
+			currently being merged.
+		@type include_file: String
+		@param preserve_paths: Libraries preserved by a package instance that
+			is currently being merged. They need to be explicitly passed to the
+			LinkageMap, since they are not registered in the
+			PreservedLibsRegistry yet.
+		@type preserve_paths: set
 		"""
 
 		os = _os_merge
@@ -108,7 +124,6 @@ class LinkageMapXCoff(LinkageMapELF):
 		self._clear_cache()
 		self._defpath.update(getlibpaths(self._root))
 		libs = self._libs
-		obj_key_cache = self._obj_key_cache
 		obj_properties = self._obj_properties
 
 		lines = []
@@ -116,75 +131,96 @@ class LinkageMapXCoff(LinkageMapELF):
 		# Data from include_file is processed first so that it
 		# overrides any data from previously installed files.
 		if include_file is not None:
-			lines += grabfile(include_file)
+			for line in grabfile(include_file):
+				lines.append((include_file, line))
 
 		aux_keys = [self._needed_aux_key]
-		for cpv in self._dbapi.cpv_all():
-			if exclude_pkgs is not None and cpv in exclude_pkgs:
-				continue
-			lines += self._dbapi.aux_get(cpv, aux_keys)[0].split('\n')
-		# Cache NEEDED.* files avoid doing excessive IO for every rebuild.
-		self._dbapi.flush_cache()
+		can_lock = os.access(os.path.dirname(self._dbapi._dbroot), os.W_OK)
+		if can_lock:
+			self._dbapi.lock()
+		try:
+			for cpv in self._dbapi.cpv_all():
+				if exclude_pkgs is not None and cpv in exclude_pkgs:
+					continue
+				needed_file = self._dbapi.getpath(cpv,
+					filename=self._needed_aux_key)
+				for line in self._dbapi.aux_get(cpv, aux_keys)[0].splitlines():
+					lines.append((needed_file, line))
+		finally:
+			if can_lock:
+				self._dbapi.unlock()
 
 		# have to call scanelf for preserved libs here as they aren't 
 		# registered in NEEDED.XCOFF.1 files
 		plibs = set()
-		if self._dbapi._plib_registry and self._dbapi._plib_registry.getPreservedLibs():
-			for items in self._dbapi._plib_registry.getPreservedLibs().values():
+		if preserve_paths is not None:
+			plibs.update(preserve_paths)
+		if self._dbapi._plib_registry and \
+			self._dbapi._plib_registry.hasEntries():
+			for cpv, items in \
+				self._dbapi._plib_registry.getPreservedLibs().items():
+				if exclude_pkgs is not None and cpv in exclude_pkgs:
+					# These preserved libs will either be unmerged,
+					# rendering them irrelevant, or they will be
+					# preserved in the replacement package and are
+					# already represented via the preserve_paths
+					# parameter.
+					continue
 				plibs.update(items)
-				for x in items:
-					args = [BASH_BINARY, "-c", ':'
-						+ '; member="' + x + '"'
-						+ '; archive=${member}'
-						+ '; if [[ ${member##*/} == .*"["*"]" ]]'
-						+ '; then member=${member%/.*}/${member##*/.}'
-							 + '; archive=${member%[*}'
-						+ '; fi'
-						+ '; member=${member#${archive}}'
-						+ '; [[ -r ${archive} ]] || chmod a+r "${archive}"'
-						+ '; eval $(aixdll-query "${archive}${member}" FILE MEMBER FLAGS FORMAT RUNPATH DEPLIBS)'
-						+ '; [[ -n ${member} ]] && needed=${FILE##*/} || needed='
-						+ '; for deplib in ${DEPLIBS}'
-						+ '; do eval deplib=${deplib}'
-						   + '; if [[ ${deplib} != "." && ${deplib} != ".." ]]'
-						   + '; then needed="${needed}${needed:+,}${deplib}"'
-						   + '; fi'
-						+ '; done'
-						+ '; [[ -n ${MEMBER} ]] && MEMBER="[${MEMBER}]"'
-						+ '; [[ " ${FLAGS} " == *" SHROBJ "* ]] && soname=${FILE##*/}${MEMBER} || soname='
-						+ '; echo "${FORMAT##* }${FORMAT%%-*};${FILE#${ROOT%/}}${MEMBER};${soname};${RUNPATH};${needed}"'
-						+ '; [[ -z ${member} && -n ${MEMBER} ]] && echo "${FORMAT##* }${FORMAT%%-*};${FILE#${ROOT%/}};${FILE##*/};;"'
-					]
+		if plibs:
+			for x in plibs:
+				args = [BASH_BINARY, "-c", ':'
+					+ '; member="' + x + '"'
+					+ '; archive=${member}'
+					+ '; if [[ ${member##*/} == .*"["*"]" ]]'
+					+ '; then member=${member%/.*}/${member##*/.}'
+						 + '; archive=${member%[*}'
+					+ '; fi'
+					+ '; member=${member#${archive}}'
+					+ '; [[ -r ${archive} ]] || chmod a+r "${archive}"'
+					+ '; eval $(aixdll-query "${archive}${member}" FILE MEMBER FLAGS FORMAT RUNPATH DEPLIBS)'
+					+ '; [[ -n ${member} ]] && needed=${FILE##*/} || needed='
+					+ '; for deplib in ${DEPLIBS}'
+					+ '; do eval deplib=${deplib}'
+					   + '; if [[ ${deplib} != "." && ${deplib} != ".." ]]'
+					   + '; then needed="${needed}${needed:+,}${deplib}"'
+					   + '; fi'
+					+ '; done'
+					+ '; [[ -n ${MEMBER} ]] && MEMBER="[${MEMBER}]"'
+					+ '; [[ " ${FLAGS} " == *" SHROBJ "* ]] && soname=${FILE##*/}${MEMBER} || soname='
+					+ '; echo "${FORMAT##* }${FORMAT%%-*};${FILE#${ROOT%/}}${MEMBER};${soname};${RUNPATH};${needed}"'
+					+ '; [[ -z ${member} && -n ${MEMBER} ]] && echo "${FORMAT##* }${FORMAT%%-*};${FILE#${ROOT%/}};${FILE##*/};;"'
+				]
+			try:
+				proc = subprocess.Popen(args, stdout=subprocess.PIPE)
+			except EnvironmentError as e:
+				if e.errno != errno.ENOENT:
+					raise
+				raise CommandNotFound(args[0])
+			else:
+				for l in proc.stdout:
 					try:
-						proc = subprocess.Popen(args, stdout=subprocess.PIPE)
-					except EnvironmentError as e:
-						if e.errno != errno.ENOENT:
-							raise
-						raise CommandNotFound("aixdll-query via " + argv[0])
-					else:
-						for l in proc.stdout:
-							try:
-								l = _unicode_decode(l,
-									encoding=_encodings['content'], errors='strict')
-							except UnicodeDecodeError:
-								l = _unicode_decode(l,
-									encoding=_encodings['content'], errors='replace')
-								writemsg_level(_("\nError decoding characters " \
-									"returned from aixdll-query: %s\n\n") % (l,),
-									level=logging.ERROR, noiselevel=-1)
-							l = l.rstrip("\n")
-							if not l:
-								continue
-							fields = l.split(";")
-							if len(fields) < 5:
-								writemsg_level(_("\nWrong number of fields " \
-									"returned from aixdll-query: %s\n\n") % (l,),
-									level=logging.ERROR, noiselevel=-1)
-								continue
-							fields[1] = fields[1][root_len:]
-							plibs.discard(fields[1])
-							lines.append(";".join(fields))
-						proc.wait()
+						l = _unicode_decode(l,
+							encoding=_encodings['content'], errors='strict')
+					except UnicodeDecodeError:
+						l = _unicode_decode(l,
+							encoding=_encodings['content'], errors='replace')
+						writemsg_level(_("\nError decoding characters " \
+							"returned from aixdll-query: %s\n\n") % (l,),
+							level=logging.ERROR, noiselevel=-1)
+					l = l.rstrip("\n")
+					if not l:
+						continue
+					fields = l.split(";")
+					if len(fields) < 5:
+						writemsg_level(_("\nWrong number of fields " \
+							"returned from aixdll-query: %s\n\n") % (l,),
+							level=logging.ERROR, noiselevel=-1)
+						continue
+					fields[1] = fields[1][root_len:]
+					plibs.discard(fields[1])
+					lines.append(("aixdll-query", ";".join(fields)))
+				proc.wait()
 
 		if plibs:
 			# Preserved libraries that did not appear in the bash
@@ -195,16 +231,16 @@ class LinkageMapXCoff(LinkageMapELF):
 			# order to prevent findConsumers from raising an unwanted
 			# KeyError.
 			for x in plibs:
-				lines.append(";".join(['', x, '', '', '']))
+				lines.append(("plibs", ";".join(['', x, '', '', ''])))
 
-		for l in lines:
+		for location, l in lines:
 			l = l.rstrip("\n")
 			if not l:
 				continue
 			fields = l.split(";")
 			if len(fields) < 5:
 				writemsg_level(_("\nWrong number of fields " \
-					"in %s: %s\n\n") % (self._needed_aux_key, l),
+					"in %s: %s\n\n") % (location, l),
 					level=logging.ERROR, noiselevel=-1)
 				continue
 			arch = fields[0]



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [gentoo-commits] proj/portage:prefix commit in: pym/portage/util/_dyn_libs/
@ 2011-05-28  9:48 Fabian Groffen
  0 siblings, 0 replies; 17+ messages in thread
From: Fabian Groffen @ 2011-05-28  9:48 UTC (permalink / raw
  To: gentoo-commits

commit:     6092f34b78babcae2c8a3713ee97e6553d77c8aa
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Sat May 28 09:47:48 2011 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Sat May 28 09:47:48 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=6092f34b

LinkageMapMachO: fix indentation level

---
 pym/portage/util/_dyn_libs/LinkageMapMachO.py |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/pym/portage/util/_dyn_libs/LinkageMapMachO.py b/pym/portage/util/_dyn_libs/LinkageMapMachO.py
index 7ed004a..b562f5c 100644
--- a/pym/portage/util/_dyn_libs/LinkageMapMachO.py
+++ b/pym/portage/util/_dyn_libs/LinkageMapMachO.py
@@ -270,8 +270,7 @@ class LinkageMapMachO(object):
 			fields = l.split(";")
 			if len(fields) < 4:
 				writemsg_level("\nWrong number of fields " + \
-					"in %s: %s\n\n") % (location, l),
-					level=logging.ERROR, noiselevel=-1)
+					"in %s: %s\n\n") % (location, l), level=logging.ERROR, noiselevel=-1)
 				continue
 			arch = fields[0]
 			obj = fields[1]



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [gentoo-commits] proj/portage:prefix commit in: pym/portage/util/_dyn_libs/
@ 2011-05-28  9:59 Fabian Groffen
  0 siblings, 0 replies; 17+ messages in thread
From: Fabian Groffen @ 2011-05-28  9:59 UTC (permalink / raw
  To: gentoo-commits

commit:     a0ca4c604e3123b848a3d81f9aea30d54ba9e872
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Sat May 28 09:57:23 2011 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Sat May 28 09:57:23 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=a0ca4c60

LinkageMapMachO: fix indentation

Previous fix was not really a fix.  Get the parenthesis right this time.

---
 pym/portage/util/_dyn_libs/LinkageMapMachO.py |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/pym/portage/util/_dyn_libs/LinkageMapMachO.py b/pym/portage/util/_dyn_libs/LinkageMapMachO.py
index b562f5c..eb62e91 100644
--- a/pym/portage/util/_dyn_libs/LinkageMapMachO.py
+++ b/pym/portage/util/_dyn_libs/LinkageMapMachO.py
@@ -270,7 +270,8 @@ class LinkageMapMachO(object):
 			fields = l.split(";")
 			if len(fields) < 4:
 				writemsg_level("\nWrong number of fields " + \
-					"in %s: %s\n\n") % (location, l), level=logging.ERROR, noiselevel=-1)
+					"in %s: %s\n\n" % (location, l),
+					level=logging.ERROR, noiselevel=-1)
 				continue
 			arch = fields[0]
 			obj = fields[1]



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [gentoo-commits] proj/portage:prefix commit in: pym/portage/util/_dyn_libs/
@ 2011-07-01 18:45 Fabian Groffen
  0 siblings, 0 replies; 17+ messages in thread
From: Fabian Groffen @ 2011-07-01 18:45 UTC (permalink / raw
  To: gentoo-commits

commit:     3b0e4011279670b82d9a590ee6a43f027552a3ef
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Fri Jul  1 18:42:54 2011 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Fri Jul  1 18:42:54 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=3b0e4011

LinkageMapMachO: sync with changes in LinkageMapELF

---
 pym/portage/util/_dyn_libs/LinkageMapMachO.py |   25 ++++++++++++++++++-------
 1 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/pym/portage/util/_dyn_libs/LinkageMapMachO.py b/pym/portage/util/_dyn_libs/LinkageMapMachO.py
index eb62e91..54784f3 100644
--- a/pym/portage/util/_dyn_libs/LinkageMapMachO.py
+++ b/pym/portage/util/_dyn_libs/LinkageMapMachO.py
@@ -59,7 +59,7 @@ class LinkageMapMachO(object):
 
 		"""Helper class used as _obj_properties keys for objects."""
 
-		__slots__ = ("_key")
+		__slots__ = ("_key",)
 
 		def __init__(self, obj, root):
 			"""
@@ -459,7 +459,16 @@ class LinkageMapMachO(object):
 
 	def isMasterLink(self, obj):
 		"""
-		Determine whether an object is a master link.
+		Determine whether an object is a "master" symlink, which means
+		that its basename is the same as the beginning part of the
+		soname and it lacks the soname's version component.
+
+		Examples:
+
+		install_name              | master symlink name
+		-----------------------------------------------
+		libarchive.2.8.4.dylib    | libarchive.dylib
+		(typically the install_name is libarchive.2.dylib)
 
 		@param obj: absolute path to an object
 		@type obj: string (example: '/usr/bin/foo')
@@ -470,12 +479,14 @@ class LinkageMapMachO(object):
 
 		"""
 		os = _os_merge
-		basename = os.path.basename(obj)
 		obj_key = self._obj_key(obj)
 		if obj_key not in self._obj_properties:
 			raise KeyError("%s (%s) not in object list" % (obj_key, obj))
+		basename = os.path.basename(obj)
 		install_name = self._obj_properties[obj_key][2]
-		return (len(basename) < len(os.path.basename(install_name)))
+		return (len(basename) < len(os.path.basename(install_name)) and \
+			basename.endswith(".dylib") and \
+			os.path.basename(install_name).startswith(basename[:-6])
 
 	def listLibraryObjects(self):
 		"""
@@ -490,8 +501,8 @@ class LinkageMapMachO(object):
 		rValue = []
 		if not self._libs:
 			self.rebuild()
-		for arch_map in self._libs.itervalues():
-			for soname_map in arch_map.itervalues():
+		for arch_map in self._libs.values():
+			for soname_map in arch_map.values():
 				for obj_key in soname_map.providers:
 					rValue.extend(self._obj_properties[obj_key][3])
 		return rValue
@@ -620,7 +631,7 @@ class LinkageMapMachO(object):
 				raise KeyError("%s (%s) not in object list" % (obj_key, obj))
 
 		# If there is another version of this lib with the
-		# same soname and the master link points to that
+		# same soname and the install_name symlink points to that
 		# other version, this lib will be shadowed and won't
 		# have any consumers.
 		if not isinstance(obj, self._ObjectKey):



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [gentoo-commits] proj/portage:prefix commit in: pym/portage/util/_dyn_libs/
@ 2011-07-01 18:52 Fabian Groffen
  0 siblings, 0 replies; 17+ messages in thread
From: Fabian Groffen @ 2011-07-01 18:52 UTC (permalink / raw
  To: gentoo-commits

commit:     b2533f19526a45ee162519861e6bc81cfd1450fd
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Fri Jul  1 18:51:16 2011 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Fri Jul  1 18:51:16 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=b2533f19

Add missing )

---
 pym/portage/util/_dyn_libs/LinkageMapMachO.py |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/pym/portage/util/_dyn_libs/LinkageMapMachO.py b/pym/portage/util/_dyn_libs/LinkageMapMachO.py
index 54784f3..e64a54d 100644
--- a/pym/portage/util/_dyn_libs/LinkageMapMachO.py
+++ b/pym/portage/util/_dyn_libs/LinkageMapMachO.py
@@ -486,7 +486,7 @@ class LinkageMapMachO(object):
 		install_name = self._obj_properties[obj_key][2]
 		return (len(basename) < len(os.path.basename(install_name)) and \
 			basename.endswith(".dylib") and \
-			os.path.basename(install_name).startswith(basename[:-6])
+			os.path.basename(install_name).startswith(basename[:-6]))
 
 	def listLibraryObjects(self):
 		"""



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [gentoo-commits] proj/portage:prefix commit in: pym/portage/util/_dyn_libs/
@ 2011-07-26 17:35 Fabian Groffen
  0 siblings, 0 replies; 17+ messages in thread
From: Fabian Groffen @ 2011-07-26 17:35 UTC (permalink / raw
  To: gentoo-commits

commit:     12ac5edad5a51c5b29f11ed3d6f840f04e559e51
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Tue Jul 26 17:34:22 2011 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Tue Jul 26 17:34:22 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=12ac5eda

LinkageMapXCoff: sync with LinkageMapELF

---
 pym/portage/util/_dyn_libs/LinkageMapXCoff.py |   56 ++++++++++++++----------
 1 files changed, 33 insertions(+), 23 deletions(-)

diff --git a/pym/portage/util/_dyn_libs/LinkageMapXCoff.py b/pym/portage/util/_dyn_libs/LinkageMapXCoff.py
index 9259602..9e2cc6d 100644
--- a/pym/portage/util/_dyn_libs/LinkageMapXCoff.py
+++ b/pym/portage/util/_dyn_libs/LinkageMapXCoff.py
@@ -129,7 +129,7 @@ class LinkageMapXCoff(LinkageMapELF):
 		root = self._root
 		root_len = len(root) - 1
 		self._clear_cache()
-		self._defpath.update(getlibpaths(self._root))
+		self._defpath.update(getlibpaths(self._root, env=self._dbapi.settings))
 		libs = self._libs
 		obj_properties = self._obj_properties
 
@@ -139,7 +139,7 @@ class LinkageMapXCoff(LinkageMapELF):
 		# overrides any data from previously installed files.
 		if include_file is not None:
 			for line in grabfile(include_file):
-				lines.append((include_file, line))
+				lines.append((None, include_file, line))
 
 		aux_keys = [self._needed_aux_key]
 		can_lock = os.access(os.path.dirname(self._dbapi._dbroot), os.W_OK)
@@ -152,16 +152,16 @@ class LinkageMapXCoff(LinkageMapELF):
 				needed_file = self._dbapi.getpath(cpv,
 					filename=self._needed_aux_key)
 				for line in self._dbapi.aux_get(cpv, aux_keys)[0].splitlines():
-					lines.append((needed_file, line))
+					lines.append((cpv, needed_file, line))
 		finally:
 			if can_lock:
 				self._dbapi.unlock()
 
 		# have to call scanelf for preserved libs here as they aren't 
 		# registered in NEEDED.XCOFF.1 files
-		plibs = set()
+		plibs = {}
 		if preserve_paths is not None:
-			plibs.update(preserve_paths)
+			plibs.update((x, None) for x in preserve_paths)
 		if self._dbapi._plib_registry and \
 			self._dbapi._plib_registry.hasEntries():
 			for cpv, items in \
@@ -173,7 +173,7 @@ class LinkageMapXCoff(LinkageMapELF):
 					# already represented via the preserve_paths
 					# parameter.
 					continue
-				plibs.update(items)
+				plibs.update((x, cpv) for x in items)
 		if plibs:
 			for x in plibs:
 				args = [BASH_BINARY, "-c", ':'
@@ -225,8 +225,8 @@ class LinkageMapXCoff(LinkageMapELF):
 							level=logging.ERROR, noiselevel=-1)
 						continue
 					fields[1] = fields[1][root_len:]
-					plibs.discard(fields[1])
-					lines.append(("aixdll-query", ";".join(fields)))
+					owner = plibs.pop(fields[1], None)
+					lines.append((owner, "aixdll-query", ";".join(fields)))
 				proc.wait()
 
 		if plibs:
@@ -237,10 +237,13 @@ class LinkageMapXCoff(LinkageMapELF):
 			# an entry in self._obj_properties.  This is important in
 			# order to prevent findConsumers from raising an unwanted
 			# KeyError.
-			for x in plibs:
-				lines.append(("plibs", ";".join(['', x, '', '', ''])))
+			for x, cpv in plibs.items():
+				lines.append((cpv, "plibs", ";".join(['', x, '', '', ''])))
+		# Share identical frozenset instances when available,
+		# in order to conserve memory.
+		frozensets = {}
 
-		for location, l in lines:
+		for owner, location, l in lines:
 			l = l.rstrip("\n")
 			if not l:
 				continue
@@ -265,21 +268,24 @@ class LinkageMapXCoff(LinkageMapELF):
 
 			obj = as_contentmember(fields[1])
 			soname = as_contentmember(fields[2])
-			path = set([normalize_path(x) \
+			path = frozenset(normalize_path(x) \
 				for x in filter(None, fields[3].replace(
 				"${ORIGIN}", os.path.dirname(obj)).replace(
-				"$ORIGIN", os.path.dirname(obj)).split(":"))])
-			needed = [as_contentmember(x) for x in fields[4].split(",") if x]
+				"$ORIGIN", os.path.dirname(obj)).split(":")))
+			path = frozensets.setdefault(path, path)
+			needed = frozenset(as_contentmember(x) for x in fields[4].split(",") if x)
+			needed = frozensets.setdefault(needed, needed)
 
 			obj_key = self._obj_key(obj)
 			indexed = True
 			myprops = obj_properties.get(obj_key)
 			if myprops is None:
 				indexed = False
-				myprops = (arch, needed, path, soname, set())
+				myprops = self._obj_properies_class(
+					arch, needed, path, soname, [], owner)
 				obj_properties[obj_key] = myprops
 			# All object paths are added into the obj_properties tuple.
-			myprops[4].add(obj)
+			myprops.alt_paths.append(obj)
 
 			# Don't index the same file more that once since only one
 			# set of data can be correct and therefore mixing data
@@ -296,16 +302,21 @@ class LinkageMapXCoff(LinkageMapELF):
 				soname_map = arch_map.get(soname)
 				if soname_map is None:
 					soname_map = self._soname_map_class(
-						providers=set(), consumers=set())
+						providers=[], consumers=[])
 					arch_map[soname] = soname_map
-				soname_map.providers.add(obj_key)
+				soname_map.providers.append(obj_key)
 			for needed_soname in needed:
 				soname_map = arch_map.get(needed_soname)
 				if soname_map is None:
 					soname_map = self._soname_map_class(
-						providers=set(), consumers=set())
+						providers=[], consumers=[])
 					arch_map[needed_soname] = soname_map
-				soname_map.consumers.add(obj_key)
+				soname_map.consumers.append(obj_key)
+
+		for arch, sonames in libs.items():
+			for soname_node in sonames.values():
+				soname_node.providers = tuple(set(soname_node.providers))
+				soname_node.consumers = tuple(set(soname_node.consumers))
 
 	def getSoname(self, obj):
 		"""
@@ -323,8 +334,7 @@ class LinkageMapXCoff(LinkageMapELF):
 			obj_key = obj
 			if obj_key not in self._obj_properties:
 				raise KeyError("%s not in object list" % obj_key)
-			return self._obj_properties[obj_key][3]
+			return self._obj_properties[obj_key].soname
 		if obj not in self._obj_key_cache:
 			raise KeyError("%s not in object list" % obj)
-		return self._obj_properties[self._obj_key_cache[obj]][3]
-
+		return self._obj_properties[self._obj_key_cache[obj]].soname



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [gentoo-commits] proj/portage:prefix commit in: pym/portage/util/_dyn_libs/
@ 2011-07-26 17:35 Fabian Groffen
  0 siblings, 0 replies; 17+ messages in thread
From: Fabian Groffen @ 2011-07-26 17:35 UTC (permalink / raw
  To: gentoo-commits

commit:     841a7a3228619b41a7f579f5090edd2bed5bfcac
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Tue Jul 26 17:27:55 2011 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Tue Jul 26 17:27:55 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=841a7a32

LinkageMapPeCoff: sync with LinkageMapELF

---
 pym/portage/util/_dyn_libs/LinkageMapPeCoff.py |   52 ++++++++++++++---------
 1 files changed, 32 insertions(+), 20 deletions(-)

diff --git a/pym/portage/util/_dyn_libs/LinkageMapPeCoff.py b/pym/portage/util/_dyn_libs/LinkageMapPeCoff.py
index 25e8a45..0a42784 100644
--- a/pym/portage/util/_dyn_libs/LinkageMapPeCoff.py
+++ b/pym/portage/util/_dyn_libs/LinkageMapPeCoff.py
@@ -128,7 +128,7 @@ class LinkageMapPeCoff(LinkageMapELF):
 		root = self._root
 		root_len = len(root) - 1
 		self._clear_cache()
-		self._defpath.update(getlibpaths(self._root))
+		self._defpath.update(getlibpaths(self._root, env=self._dbapi.settings))
 		libs = self._libs
 		obj_properties = self._obj_properties
 
@@ -138,7 +138,7 @@ class LinkageMapPeCoff(LinkageMapELF):
 		# overrides any data from previously installed files.
 		if include_file is not None:
 			for line in grabfile(include_file):
-				lines.append((include_file, line))
+				lines.append((None, include_file, line))
 
 		aux_keys = [self._needed_aux_key]
 		can_lock = os.access(os.path.dirname(self._dbapi._dbroot), os.W_OK)
@@ -151,16 +151,16 @@ class LinkageMapPeCoff(LinkageMapELF):
 				needed_file = self._dbapi.getpath(cpv,
 					filename=self._needed_aux_key)
 				for line in self._dbapi.aux_get(cpv, aux_keys)[0].splitlines():
-					lines.append((needed_file, line))
+					lines.append((cpv, needed_file, line))
 		finally:
 			if can_lock:
 				self._dbapi.unlock()
 
 		# have to call readpecoff for preserved libs here as they aren't 
 		# registered in NEEDED.PECOFF.1 files
-		plibs = set()
+		plibs = {}
 		if preserve_paths is not None:
-			plibs.update(preserve_paths)
+			plibs.update((x, None) for x in preserve_paths)
 		if self._dbapi._plib_registry and \
 			self._dbapi._plib_registry.hasEntries():
 			for cpv, items in \
@@ -172,7 +172,7 @@ class LinkageMapPeCoff(LinkageMapELF):
 					# already represented via the preserve_paths
 					# parameter.
 					continue
-				plibs.update(items)
+				plibs.update((x, cpv) for x in items)
 		if plibs:
 			args = ["readpecoff", self._dbapi.settings.get('CHOST')]
 			args.extend(os.path.join(root, x.lstrip("." + os.sep)) \
@@ -204,8 +204,8 @@ class LinkageMapPeCoff(LinkageMapELF):
 							level=logging.ERROR, noiselevel=-1)
 						continue
 					fields[1] = fields[1][root_len:]
-					plibs.discard(fields[1])
-					lines.append(("readpecoff", ";".join(fields)))
+					owner = plibs.pop(fields[1], None)
+					lines.append((owner, "readpecoff", ";".join(fields)))
 				proc.wait()
 
 		if plibs:
@@ -215,10 +215,14 @@ class LinkageMapPeCoff(LinkageMapELF):
 			# preserved library has an entry in self._obj_properties. This
 			# is important in order to prevent findConsumers from raising
 			# an unwanted KeyError.
-			for x in plibs:
-				lines.append(("plibs", ";".join(['', x, '', '', ''])))
+			for x, cpv in plibs.items():
+				lines.append((cpv, "plibs", ";".join(['', x, '', '', ''])))
 
-		for location, l in lines:
+		# Share identical frozenset instances when available,
+		# in order to conserve memory.
+		frozensets = {}
+
+		for owner, location, l in lines:
 			l = l.rstrip("\n")
 			if not l:
 				continue
@@ -231,21 +235,24 @@ class LinkageMapPeCoff(LinkageMapELF):
 			arch = fields[0]
 			obj = fields[1]
 			soname = fields[2]
-			path = set([normalize_path(x) \
+			path = frozenset(normalize_path(x) \
 				for x in filter(None, fields[3].replace(
 				"${ORIGIN}", os.path.dirname(obj)).replace(
-				"$ORIGIN", os.path.dirname(obj)).split(":"))])
-			needed = [x for x in fields[4].split(",") if x]
+				"$ORIGIN", os.path.dirname(obj)).split(":")))
+			path = frozensets.setdefault(path, path)
+			needed = frozenset(x for x in fields[4].split(",") if x)
+			needed = frozensets.setdefault(needed, needed)
 
 			obj_key = self._obj_key(obj)
 			indexed = True
 			myprops = obj_properties.get(obj_key)
 			if myprops is None:
 				indexed = False
-				myprops = (arch, needed, path, soname, set())
+				myprops = self._obj_properies_class(
+					arch, needed, path, soname, [], owner)
 				obj_properties[obj_key] = myprops
 			# All object paths are added into the obj_properties tuple.
-			myprops[4].add(obj)
+			myprops.alt_paths.append(obj)
 
 			# Don't index the same file more that once since only one
 			# set of data can be correct and therefore mixing data
@@ -262,13 +269,18 @@ class LinkageMapPeCoff(LinkageMapELF):
 				soname_map = arch_map.get(soname)
 				if soname_map is None:
 					soname_map = self._soname_map_class(
-						providers=set(), consumers=set())
+						providers=[], consumers=[])
 					arch_map[soname] = soname_map
-				soname_map.providers.add(obj_key)
+				soname_map.providers.append(obj_key)
 			for needed_soname in needed:
 				soname_map = arch_map.get(needed_soname)
 				if soname_map is None:
 					soname_map = self._soname_map_class(
-						providers=set(), consumers=set())
+						providers=[], consumers=[])
 					arch_map[needed_soname] = soname_map
-				soname_map.consumers.add(obj_key)
+				soname_map.consumers.append(obj_key)
+
+		for arch, sonames in libs.items():
+			for soname_node in sonames.values():
+				soname_node.providers = tuple(set(soname_node.providers))
+				soname_node.consumers = tuple(set(soname_node.consumers))



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [gentoo-commits] proj/portage:prefix commit in: pym/portage/util/_dyn_libs/
@ 2011-07-26 17:35 Fabian Groffen
  0 siblings, 0 replies; 17+ messages in thread
From: Fabian Groffen @ 2011-07-26 17:35 UTC (permalink / raw
  To: gentoo-commits

commit:     71a47b1875141b038489ab87b87f7f5eb1e7332b
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Tue Jul 26 17:23:06 2011 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Tue Jul 26 17:23:06 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=71a47b18

LinkageMapMachO: sync with LinkageMapELF

---
 pym/portage/util/_dyn_libs/LinkageMapMachO.py |  153 +++++++++++++++++++------
 1 files changed, 116 insertions(+), 37 deletions(-)

diff --git a/pym/portage/util/_dyn_libs/LinkageMapMachO.py b/pym/portage/util/_dyn_libs/LinkageMapMachO.py
index e64a54d..0e7c333 100644
--- a/pym/portage/util/_dyn_libs/LinkageMapMachO.py
+++ b/pym/portage/util/_dyn_libs/LinkageMapMachO.py
@@ -27,6 +27,18 @@ class LinkageMapMachO(object):
 	_installname_map_class = slot_dict_class(
 		("consumers", "providers"), prefix="")
 
+	class _obj_properies_class(object):
+
+		__slots__ = ("arch", "needed", "install_name", "alt_paths",
+			"owner",)
+
+		def __init__(self, arch, needed, install_name, alt_paths, owner):
+			self.arch = arch
+			self.needed = needed
+			self.install_name = install_name
+			self.alt_paths = alt_paths
+			self.owner = owner
+
 	def __init__(self, vardbapi):
 		self._dbapi = vardbapi
 		self._root = self._dbapi.settings['ROOT']
@@ -183,7 +195,7 @@ class LinkageMapMachO(object):
 		# overrides any data from previously installed files.
 		if include_file is not None:
 			for line in grabfile(include_file):
-				lines.append((include_file, line))
+				lines.append((None, include_file, line))
 
 		aux_keys = [self._needed_aux_key]
 		can_lock = os.access(os.path.dirname(self._dbapi._dbroot), os.W_OK)
@@ -196,16 +208,16 @@ class LinkageMapMachO(object):
 				needed_file = self._dbapi.getpath(cpv,
 					filename=self._needed_aux_key)
 				for line in self._dbapi.aux_get(cpv, aux_keys)[0].splitlines():
-					lines.append((needed_file, line))
+					lines.append((cpv, needed_file, line))
 		finally:
 			if can_lock:
 				self._dbapi.unlock()
 
 		# have to call scanmacho for preserved libs here as they aren't 
 		# registered in NEEDED.MACHO.3 files
-		plibs = set()
+		plibs = {}
 		if preserve_paths is not None:
-			plibs.update(preserve_paths)
+			plibs.update((x, None) for x in preserve_paths)
 		if self._dbapi._plib_registry and \
 			self._dbapi._plib_registry.hasEntries():
 			for cpv, items in \
@@ -217,7 +229,7 @@ class LinkageMapMachO(object):
 					# already represented via the preserve_paths
 					# parameter.
 					continue
-				plibs.update(items)
+				plibs.update((x, cpv) for x in items)
 		if plibs:
 			args = [EPREFIX+"/usr/bin/scanmacho", "-qF", "%a;%F;%S;%n"]
 			args.extend(os.path.join(root, x.lstrip("." + os.sep)) \
@@ -249,8 +261,8 @@ class LinkageMapMachO(object):
 							level=logging.ERROR, noiselevel=-1)
 						continue
 					fields[1] = fields[1][root_len:]
-					plibs.discard(fields[1])
-					lines.append(("scanmacho", ";".join(fields)))
+					owner = plibs.pop(fields[1], None)
+					lines.append((owner, "scanmacho", ";".join(fields)))
 				proc.wait()
 
 		if plibs:
@@ -260,33 +272,39 @@ class LinkageMapMachO(object):
 			# assume that every preserved library has an entry in
 			# self._obj_properties.  This is important in order to
 			# prevent findConsumers from raising an unwanted KeyError.
-			for x in plibs:
-				lines.append(("plibs", ";".join(['', x, '', '', ''])))
+			for x, cpv in plibs.items():
+				lines.append((cpv, "plibs", ";".join(['', x, '', '', ''])))
 
-		for location, l in lines:
+		# Share identical frozenset instances when available,
+		# in order to conserve memory.
+		frozensets = {}
+
+		for owner, location, l in lines:
 			l = l.rstrip("\n")
 			if not l:
 				continue
 			fields = l.split(";")
 			if len(fields) < 4:
-				writemsg_level("\nWrong number of fields " + \
-					"in %s: %s\n\n" % (location, l),
+				writemsg_level(_("\nWrong number of fields " \
+					"in %s: %s\n\n") % (location, l),
 					level=logging.ERROR, noiselevel=-1)
 				continue
 			arch = fields[0]
 			obj = fields[1]
 			install_name = os.path.normpath(fields[2])
-			needed = filter(None, fields[3].split(","))
+			needed = frozenset(x for x in fields[3].split(",") if x)
+			needed = frozensets.setdefault(needed, needed)
 
 			obj_key = self._obj_key(obj)
 			indexed = True
 			myprops = obj_properties.get(obj_key)
 			if myprops is None:
 				indexed = False
-				myprops = (arch, needed, install_name, set())
+				myprops = self._obj_properies_class(
+					arch, needed, install_name, [], owner)
 				obj_properties[obj_key] = myprops
 			# All object paths are added into the obj_properties tuple.
-			myprops[3].add(obj)
+			myprops.alt_paths.append(obj)
 
 			# Don't index the same file more that once since only one
 			# set of data can be correct and therefore mixing data
@@ -303,17 +321,22 @@ class LinkageMapMachO(object):
 				installname_map = arch_map.get(install_name)
 				if installname_map is None:
 					installname_map = self._installname_map_class(
-						providers=set(), consumers=set())
+						providers=[], consumers=[])
 					arch_map[install_name] = installname_map
 				installname_map.providers.add(obj_key)
 			for needed_installname in needed:
 				installname_map = arch_map.get(needed_installname)
 				if installname_map is None:
 					installname_map = self._installname_map_class(
-						providers=set(), consumers=set())
+						providers=[], consumers=[])
 					arch_map[needed_installname] = installname_map
 				installname_map.consumers.add(obj_key)
 
+		for arch, install_names in libs.items():
+			for install_name_node in install_names.values():
+				install_name_node.providers = tuple(set(install_name_node.providers))
+				install_name_node.consumers = tuple(set(install_name_node.consumers))
+
 	def listBrokenBinaries(self, debug=False):
 		"""
 		Find binaries and their needed install_names, which have no providers.
@@ -367,8 +390,13 @@ class LinkageMapMachO(object):
 					if obj_key.file_exists():
 						# Get the install_name from LinkageMapMachO._obj_properties if
 						# it exists. Otherwise, None.
-						arch = self._obj_properties.get(obj_key, (None,)*4)[0]
-						install_name = self._obj_properties.get(obj_key, (None,)*4)[2]
+						obj_props = self._obj_properties.get(obj_key)
+						if obj_props is None:
+							arch = None
+							install_name = None
+						else:
+							arch = obj_props.arch
+							install_name = obj_props.install_name
 						return cache_self.cache.setdefault(obj, \
 								(arch, install_name, obj_key, True))
 					else:
@@ -381,8 +409,9 @@ class LinkageMapMachO(object):
 
 		# Iterate over all obj_keys and their providers.
 		for obj_key, install_names in providers.items():
-			arch = self._obj_properties[obj_key][0]
-			objs = self._obj_properties[obj_key][3]
+			obj_props = self._obj_properties[obj_key]
+			arch = obj_props.arch
+			objs = obj_props.alt_paths
 			# Iterate over each needed install_name and the set of
 			# library paths that fulfill the install_name to determine
 			# if the dependency is broken.
@@ -483,7 +512,7 @@ class LinkageMapMachO(object):
 		if obj_key not in self._obj_properties:
 			raise KeyError("%s (%s) not in object list" % (obj_key, obj))
 		basename = os.path.basename(obj)
-		install_name = self._obj_properties[obj_key][2]
+		install_name = self._obj_properties[obj_key].install_name
 		return (len(basename) < len(os.path.basename(install_name)) and \
 			basename.endswith(".dylib") and \
 			os.path.basename(install_name).startswith(basename[:-6]))
@@ -504,9 +533,40 @@ class LinkageMapMachO(object):
 		for arch_map in self._libs.values():
 			for soname_map in arch_map.values():
 				for obj_key in soname_map.providers:
-					rValue.extend(self._obj_properties[obj_key][3])
+					rValue.extend(self._obj_properties[obj_key].alt_paths)
 		return rValue
 
+	def getOwners(self, obj):
+		"""
+		Return the package(s) associated with an object. Raises KeyError
+		if the object is unknown. Returns an empty tuple if the owner(s)
+		are unknown.
+
+		NOTE: For preserved libraries, the owner(s) may have been
+		previously uninstalled, but these uninstalled owners can be
+		returned by this method since they are registered in the
+		PreservedLibsRegistry.
+
+		@param obj: absolute path to an object
+		@type obj: string (example: '/usr/bin/bar')
+		@rtype: tuple
+		@return: a tuple of cpv
+		"""
+		if not self._libs:
+			self.rebuild()
+		if isinstance(obj, self._ObjectKey):
+			obj_key = obj
+		else:
+			obj_key = self._obj_key_cache.get(obj)
+			if obj_key is None:
+				raise KeyError("%s not in object list" % obj)
+		obj_props = self._obj_properties.get(obj_key)
+		if obj_props is None:
+			raise KeyError("%s not in object list" % obj_key)
+		if obj_props.owner is None:
+			return ()
+		return (obj_props.owner,)
+
 	def getSoname(self, obj):
 		"""
 		Return the soname associated with an object.
@@ -523,10 +583,10 @@ class LinkageMapMachO(object):
 			obj_key = obj
 			if obj_key not in self._obj_properties:
 				raise KeyError("%s not in object list" % obj_key)
-			return self._obj_properties[obj_key][2]
+			return self._obj_properties[obj_key].install_name
 		if obj not in self._obj_key_cache:
 			raise KeyError("%s not in object list" % obj)
-		return self._obj_properties[self._obj_key_cache[obj]][2]
+		return self._obj_properties[self._obj_key_cache[obj]].install_name
 
 	def findProviders(self, obj):
 		"""
@@ -566,7 +626,10 @@ class LinkageMapMachO(object):
 			if obj_key not in self._obj_properties:
 				raise KeyError("%s (%s) not in object list" % (obj_key, obj))
 
-		arch, needed, install_name, _ = self._obj_properties[obj_key]
+		obj_props = self._obj_properties[obj_key]
+		arch = obj_props.arch
+		needed = obj_props.needed
+		install_name = obj_props.install_name
 		for install_name in needed:
 			rValue[install_name] = set()
 			if arch not in self._libs or install_name not in self._libs[arch]:
@@ -574,13 +637,13 @@ class LinkageMapMachO(object):
 			# For each potential provider of the install_name, add it to
 			# rValue if it exists.  (Should be one)
 			for provider_key in self._libs[arch][install_name].providers:
-				providers = self._obj_properties[provider_key][3]
+				providers = self._obj_properties[provider_key].alt_paths
 				for provider in providers:
 					if os.path.exists(provider):
 						rValue[install_name].add(provider)
 		return rValue
 
-	def findConsumers(self, obj):
+	def findConsumers(self, obj, exclude_providers=None):
 		"""
 		Find consumers of an object or object key.
 
@@ -603,8 +666,16 @@ class LinkageMapMachO(object):
 		corresponding libtool archive (*.la) files to detect such consumers
 		(revdep-rebuild is able to detect them).
 
+		The exclude_providers argument is only useful on platforms where
+		references to libraries are not full paths, e.g. they are being
+		searched for in a path, like ELF.  On Mach-O, these references
+		are full paths, and hence this argument is ignored, since there
+		never will be alternative providers.
+
 		@param obj: absolute path to an object or a key from _obj_properties
 		@type obj: string (example: '/usr/bin/bar') or _ObjectKey
+		@param exclude_providers: ignored in LinkageMapMachO
+		@type exclude_providers: collection
 		@rtype: set of strings (example: set(['/bin/foo', '/usr/bin/bar']))
 		@return: The return value is a install_name -> set-of-library-paths, where
 		set-of-library-paths satisfy install_name.
@@ -613,8 +684,6 @@ class LinkageMapMachO(object):
 
 		os = _os_merge
 
-		rValue = set()
-
 		if not self._libs:
 			self.rebuild()
 
@@ -623,7 +692,7 @@ class LinkageMapMachO(object):
 			obj_key = obj
 			if obj_key not in self._obj_properties:
 				raise KeyError("%s not in object list" % obj_key)
-			objs = self._obj_properties[obj_key][3]
+			objs = self._obj_properties[obj_key].alt_paths
 		else:
 			objs = set([obj])
 			obj_key = self._obj_key(obj)
@@ -635,7 +704,7 @@ class LinkageMapMachO(object):
 		# other version, this lib will be shadowed and won't
 		# have any consumers.
 		if not isinstance(obj, self._ObjectKey):
-			install_name = self._obj_properties[obj_key][2]
+			install_name = self._obj_properties[obj_key].install_name
 			master_link = os.path.join(self._root,
 					install_name.lstrip(os.path.sep))
 			try:
@@ -648,12 +717,22 @@ class LinkageMapMachO(object):
 					(master_st.st_dev, master_st.st_ino):
 					return set()
 
-		arch = self._obj_properties[obj_key][0]
-		install_name = self._obj_properties[obj_key][2]
-		if arch in self._libs and install_name in self._libs[arch]:
+		obj_props = self._obj_properties[obj_key]
+		arch = obj_props.arch
+		install_name = obj_props.install_name
+
+		install_name_node = None
+		arch_map = self._libs.get(arch)
+		if arch_map is not None:
+			install_name_node = arch_map.get(install_name)
+
+
+		rValue = set()
+		if install_name_node is not None:
 			# For each potential consumer, add it to rValue if an object from the
 			# arguments resides in the consumer's runpath.
-			for consumer_key in self._libs[arch][install_name].consumers:
-				consumer_objs = self._obj_properties[consumer_key][3]
+			for consumer_key in install_name_node.consumers:
+				consumer_props = self._obj_properties[consumer_key]
+				consumer_objs = consumer_props.alt_paths
 				rValue.update(consumer_objs)
 		return rValue



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [gentoo-commits] proj/portage:prefix commit in: pym/portage/util/_dyn_libs/
@ 2011-07-26 18:06 Fabian Groffen
  0 siblings, 0 replies; 17+ messages in thread
From: Fabian Groffen @ 2011-07-26 18:06 UTC (permalink / raw
  To: gentoo-commits

commit:     8713a8b8b1422a49867b0c909143c7b313263816
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Tue Jul 26 18:06:19 2011 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Tue Jul 26 18:06:19 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=8713a8b8

LinkageMapMachO: use append with lists

---
 pym/portage/util/_dyn_libs/LinkageMapMachO.py |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/pym/portage/util/_dyn_libs/LinkageMapMachO.py b/pym/portage/util/_dyn_libs/LinkageMapMachO.py
index 0e7c333..b34359c 100644
--- a/pym/portage/util/_dyn_libs/LinkageMapMachO.py
+++ b/pym/portage/util/_dyn_libs/LinkageMapMachO.py
@@ -323,14 +323,14 @@ class LinkageMapMachO(object):
 					installname_map = self._installname_map_class(
 						providers=[], consumers=[])
 					arch_map[install_name] = installname_map
-				installname_map.providers.add(obj_key)
+				installname_map.providers.append(obj_key)
 			for needed_installname in needed:
 				installname_map = arch_map.get(needed_installname)
 				if installname_map is None:
 					installname_map = self._installname_map_class(
 						providers=[], consumers=[])
 					arch_map[needed_installname] = installname_map
-				installname_map.consumers.add(obj_key)
+				installname_map.consumers.append(obj_key)
 
 		for arch, install_names in libs.items():
 			for install_name_node in install_names.values():



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [gentoo-commits] proj/portage:prefix commit in: pym/portage/util/_dyn_libs/
@ 2011-09-20 18:25 Fabian Groffen
  0 siblings, 0 replies; 17+ messages in thread
From: Fabian Groffen @ 2011-09-20 18:25 UTC (permalink / raw
  To: gentoo-commits

commit:     f837815500bb5c1a46e6aa9aaccfeeeb737e2a49
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Tue Sep 20 17:35:08 2011 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Tue Sep 20 17:35:08 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=f8378155

LinkageMapMachO: align more with LinkageMapELF

---
 pym/portage/util/_dyn_libs/LinkageMapMachO.py |   27 ++++++++++++-------------
 1 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/pym/portage/util/_dyn_libs/LinkageMapMachO.py b/pym/portage/util/_dyn_libs/LinkageMapMachO.py
index b34359c..e937b7c 100644
--- a/pym/portage/util/_dyn_libs/LinkageMapMachO.py
+++ b/pym/portage/util/_dyn_libs/LinkageMapMachO.py
@@ -231,7 +231,7 @@ class LinkageMapMachO(object):
 					continue
 				plibs.update((x, cpv) for x in items)
 		if plibs:
-			args = [EPREFIX+"/usr/bin/scanmacho", "-qF", "%a;%F;%S;%n"]
+			args = [EPREFIX + "/usr/bin/scanmacho", "-qF", "%a;%F;%S;%n"]
 			args.extend(os.path.join(root, x.lstrip("." + os.sep)) \
 				for x in plibs)
 			try:
@@ -266,12 +266,12 @@ class LinkageMapMachO(object):
 				proc.wait()
 
 		if plibs:
-			# Preserved libraries that did not appear in the scanmacho
-			# output.  This is known to happen with statically linked
-			# libraries.  Generate dummy lines for these, so we can
-			# assume that every preserved library has an entry in
-			# self._obj_properties.  This is important in order to
-			# prevent findConsumers from raising an unwanted KeyError.
+			# Preserved libraries that did not appear in the scanmacho output.
+			# This is known to happen with statically linked libraries.
+			# Generate dummy lines for these, so we can assume that every
+			# preserved library has an entry in self._obj_properties. This
+			# is important in order to prevent findConsumers from raising
+			# an unwanted KeyError.
 			for x, cpv in plibs.items():
 				lines.append((cpv, "plibs", ";".join(['', x, '', '', ''])))
 
@@ -344,10 +344,9 @@ class LinkageMapMachO(object):
 		@param debug: Boolean to enable debug output
 		@type debug: Boolean
 		@rtype: dict (example: {'/usr/bin/foo': set(['/usr/lib/libbar.dylib'])})
-		@return: The return value is an object -> set-of-install_names
-			mapping, where object is a broken binary and the set
-			consists of install_names needed by object that have no
-			corresponding libraries to fulfill the dependency.
+		@return: The return value is an object -> set-of-install_names mapping, where
+			object is a broken binary and the set consists of install_names needed by
+			object that have no corresponding libraries to fulfill the dependency.
 
 		"""
 
@@ -474,14 +473,14 @@ class LinkageMapMachO(object):
 		@rtype: dict (example:
 			{(123L, 456L): {'libbar.dylib': set(['/lib/libbar.1.5.dylib'])}})
 		@return: The return value is an object -> providers mapping, where
-			providers is a mapping of install_name ->
-			set-of-library-paths returned from the findProviders method.
+			providers is a mapping of install_name -> set-of-library-paths returned
+			from the findProviders method.
 
 		"""
 		rValue = {}
 		if not self._libs:
 			self.rebuild()
-		# Iterate over all object keys within LinkageMapMachO.
+		# Iterate over all object keys within LinkageMap.
 		for obj_key in self._obj_properties:
 			rValue.setdefault(obj_key, self.findProviders(obj_key))
 		return rValue



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [gentoo-commits] proj/portage:prefix commit in: pym/portage/util/_dyn_libs/
@ 2011-09-20 18:25 Fabian Groffen
  0 siblings, 0 replies; 17+ messages in thread
From: Fabian Groffen @ 2011-09-20 18:25 UTC (permalink / raw
  To: gentoo-commits

commit:     2188d83595fcf8302c70deae70f56ffa69978158
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Tue Sep 20 18:24:42 2011 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Tue Sep 20 18:24:42 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=2188d835

LinkageMapMachO: attempt to fix preserve-libs by porting provider_excluded

---
 pym/portage/util/_dyn_libs/LinkageMapMachO.py |   47 +++++++++++++++++++-----
 1 files changed, 37 insertions(+), 10 deletions(-)

diff --git a/pym/portage/util/_dyn_libs/LinkageMapMachO.py b/pym/portage/util/_dyn_libs/LinkageMapMachO.py
index e937b7c..10cf482 100644
--- a/pym/portage/util/_dyn_libs/LinkageMapMachO.py
+++ b/pym/portage/util/_dyn_libs/LinkageMapMachO.py
@@ -264,6 +264,7 @@ class LinkageMapMachO(object):
 					owner = plibs.pop(fields[1], None)
 					lines.append((owner, "scanmacho", ";".join(fields)))
 				proc.wait()
+				proc.stdout.close()
 
 		if plibs:
 			# Preserved libraries that did not appear in the scanmacho output.
@@ -665,15 +666,19 @@ class LinkageMapMachO(object):
 		corresponding libtool archive (*.la) files to detect such consumers
 		(revdep-rebuild is able to detect them).
 
-		The exclude_providers argument is only useful on platforms where
-		references to libraries are not full paths, e.g. they are being
-		searched for in a path, like ELF.  On Mach-O, these references
-		are full paths, and hence this argument is ignored, since there
-		never will be alternative providers.
+		The exclude_providers argument is useful for determining whether
+		removal of one or more packages will create unsatisfied consumers. When
+		this option is given, consumers are excluded from the results if there
+		is an alternative provider (which is not excluded) of the required
+		soname such that the consumers will remain satisfied if the files
+		owned by exclude_providers are removed.
 
 		@param obj: absolute path to an object or a key from _obj_properties
 		@type obj: string (example: '/usr/bin/bar') or _ObjectKey
-		@param exclude_providers: ignored in LinkageMapMachO
+		@param exclude_providers: A collection of callables that each take a
+			single argument referring to the path of a library (example:
+			'/usr/lib/libssl.0.9.8.dylib'), and return True if the library is
+			owned by a provider which is planned for removal.
 		@type exclude_providers: collection
 		@rtype: set of strings (example: set(['/bin/foo', '/usr/bin/bar']))
 		@return: The return value is a install_name -> set-of-library-paths, where
@@ -699,16 +704,17 @@ class LinkageMapMachO(object):
 				raise KeyError("%s (%s) not in object list" % (obj_key, obj))
 
 		# If there is another version of this lib with the
-		# same soname and the install_name symlink points to that
+		# same install_name and the install_name symlink points to that
 		# other version, this lib will be shadowed and won't
 		# have any consumers.
 		if not isinstance(obj, self._ObjectKey):
 			install_name = self._obj_properties[obj_key].install_name
 			master_link = os.path.join(self._root,
 					install_name.lstrip(os.path.sep))
+			obj_path = os.path.join(self._root, obj.lstrip(os.sep))
 			try:
 				master_st = os.stat(master_link)
-				obj_st = os.stat(obj)
+				obj_st = os.stat(obj_path)
 			except OSError:
 				pass
 			else:
@@ -725,12 +731,33 @@ class LinkageMapMachO(object):
 		if arch_map is not None:
 			install_name_node = arch_map.get(install_name)
 
+		satisfied_consumer_keys = set()
+		if install_name_node is not None:
+			if exclude_providers is not None:
+				relevant_dir_keys = set()
+				for provider_key in install_name_node.providers:
+					provider_objs = self._obj_properties[provider_key].alt_paths
+					for p in provider_objs:
+						provider_excluded = False
+						for excluded_provider_isowner in exclude_providers:
+							if excluded_provider_isowner(p):
+								provider_excluded = True
+								break
+						if not provider_excluded:
+							# This provider is not excluded. It will
+							# satisfy a consumer of this install_name.
+							relevant_dir_keys.add(self._path_key(p))
+
+				if relevant_dir_keys:
+					for consumer_key in install_name_node.consumers:
+							satisfied_consumer_keys.add(consumer_key)
 
 		rValue = set()
 		if install_name_node is not None:
-			# For each potential consumer, add it to rValue if an object from the
-			# arguments resides in the consumer's runpath.
+			# For each potential consumer, add it to rValue.
 			for consumer_key in install_name_node.consumers:
+				if consumer_key in satisfied_consumer_keys:
+					continue
 				consumer_props = self._obj_properties[consumer_key]
 				consumer_objs = consumer_props.alt_paths
 				rValue.update(consumer_objs)



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [gentoo-commits] proj/portage:prefix commit in: pym/portage/util/_dyn_libs/
@ 2011-09-20 19:01 Fabian Groffen
  0 siblings, 0 replies; 17+ messages in thread
From: Fabian Groffen @ 2011-09-20 19:01 UTC (permalink / raw
  To: gentoo-commits

commit:     ee9b5fecb61f75cad11667253758e4fa8818ce63
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Tue Sep 20 19:01:13 2011 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Tue Sep 20 19:01:13 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=ee9b5fec

LinkageMapMachO: don't strip scanmacho output like ELF, fixes bug #383691

---
 pym/portage/util/_dyn_libs/LinkageMapMachO.py |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/pym/portage/util/_dyn_libs/LinkageMapMachO.py b/pym/portage/util/_dyn_libs/LinkageMapMachO.py
index 10cf482..492334e 100644
--- a/pym/portage/util/_dyn_libs/LinkageMapMachO.py
+++ b/pym/portage/util/_dyn_libs/LinkageMapMachO.py
@@ -251,7 +251,7 @@ class LinkageMapMachO(object):
 						writemsg_level(_("\nError decoding characters " \
 							"returned from scanmacho: %s\n\n") % (l,),
 							level=logging.ERROR, noiselevel=-1)
-					l = l[3:].rstrip("\n")
+					l = l.rstrip("\n")
 					if not l:
 						continue
 					fields = l.split(";")



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [gentoo-commits] proj/portage:prefix commit in: pym/portage/util/_dyn_libs/
@ 2013-05-05  9:10 Fabian Groffen
  0 siblings, 0 replies; 17+ messages in thread
From: Fabian Groffen @ 2013-05-05  9:10 UTC (permalink / raw
  To: gentoo-commits

commit:     1ba557576601aca71ddf5dc46eab94f33d2b9a51
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Sun May  5 09:09:05 2013 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Sun May  5 09:09:05 2013 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=1ba55757

LinkageMapMachO: use non-greedy findConsumers

This applies the changes to LinkageMapELF from
361706c50ca591c22ac3ca5fca6450a7cbe510d2 to LinkageMapMachO

---
 pym/portage/util/_dyn_libs/LinkageMapMachO.py |   18 ++++++++++++------
 1 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/pym/portage/util/_dyn_libs/LinkageMapMachO.py b/pym/portage/util/_dyn_libs/LinkageMapMachO.py
index 492334e..b25b132 100644
--- a/pym/portage/util/_dyn_libs/LinkageMapMachO.py
+++ b/pym/portage/util/_dyn_libs/LinkageMapMachO.py
@@ -643,7 +643,7 @@ class LinkageMapMachO(object):
 						rValue[install_name].add(provider)
 		return rValue
 
-	def findConsumers(self, obj, exclude_providers=None):
+	def findConsumers(self, obj, exclude_providers=None, greedy=True):
 		"""
 		Find consumers of an object or object key.
 
@@ -680,6 +680,9 @@ class LinkageMapMachO(object):
 			'/usr/lib/libssl.0.9.8.dylib'), and return True if the library is
 			owned by a provider which is planned for removal.
 		@type exclude_providers: collection
+        @param greedy: If True, then include consumers that are satisfied
+        by alternative providers, otherwise omit them. Default is True.
+        @type greedy: Boolean
 		@rtype: set of strings (example: set(['/bin/foo', '/usr/bin/bar']))
 		@return: The return value is a install_name -> set-of-library-paths, where
 		set-of-library-paths satisfy install_name.
@@ -733,16 +736,19 @@ class LinkageMapMachO(object):
 
 		satisfied_consumer_keys = set()
 		if install_name_node is not None:
-			if exclude_providers is not None:
+			if exclude_providers is not None and not greedy:
 				relevant_dir_keys = set()
 				for provider_key in install_name_node.providers:
+                    if not greedy and provider_key == obj_key:
+                        continue
 					provider_objs = self._obj_properties[provider_key].alt_paths
 					for p in provider_objs:
 						provider_excluded = False
-						for excluded_provider_isowner in exclude_providers:
-							if excluded_provider_isowner(p):
-								provider_excluded = True
-								break
+                        if exclude_providers is not None:
+                            for excluded_provider_isowner in exclude_providers:
+                                if excluded_provider_isowner(p):
+                                    provider_excluded = True
+                                    break
 						if not provider_excluded:
 							# This provider is not excluded. It will
 							# satisfy a consumer of this install_name.


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [gentoo-commits] proj/portage:prefix commit in: pym/portage/util/_dyn_libs/
@ 2013-05-05  9:14 Fabian Groffen
  0 siblings, 0 replies; 17+ messages in thread
From: Fabian Groffen @ 2013-05-05  9:14 UTC (permalink / raw
  To: gentoo-commits

commit:     fd8aa0a3ec82b5b9c7aebe07463c707db19ef65c
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Sun May  5 09:14:01 2013 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Sun May  5 09:14:01 2013 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=fd8aa0a3

Fix spacing

---
 pym/portage/util/_dyn_libs/LinkageMapMachO.py |   20 ++++++++++----------
 1 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/pym/portage/util/_dyn_libs/LinkageMapMachO.py b/pym/portage/util/_dyn_libs/LinkageMapMachO.py
index b25b132..e6bdb8e 100644
--- a/pym/portage/util/_dyn_libs/LinkageMapMachO.py
+++ b/pym/portage/util/_dyn_libs/LinkageMapMachO.py
@@ -680,9 +680,9 @@ class LinkageMapMachO(object):
 			'/usr/lib/libssl.0.9.8.dylib'), and return True if the library is
 			owned by a provider which is planned for removal.
 		@type exclude_providers: collection
-        @param greedy: If True, then include consumers that are satisfied
-        by alternative providers, otherwise omit them. Default is True.
-        @type greedy: Boolean
+		@param greedy: If True, then include consumers that are satisfied
+		by alternative providers, otherwise omit them. Default is True.
+		@type greedy: Boolean
 		@rtype: set of strings (example: set(['/bin/foo', '/usr/bin/bar']))
 		@return: The return value is a install_name -> set-of-library-paths, where
 		set-of-library-paths satisfy install_name.
@@ -739,16 +739,16 @@ class LinkageMapMachO(object):
 			if exclude_providers is not None and not greedy:
 				relevant_dir_keys = set()
 				for provider_key in install_name_node.providers:
-                    if not greedy and provider_key == obj_key:
-                        continue
+					if not greedy and provider_key == obj_key:
+						continue
 					provider_objs = self._obj_properties[provider_key].alt_paths
 					for p in provider_objs:
 						provider_excluded = False
-                        if exclude_providers is not None:
-                            for excluded_provider_isowner in exclude_providers:
-                                if excluded_provider_isowner(p):
-                                    provider_excluded = True
-                                    break
+						if exclude_providers is not None:
+							for excluded_provider_isowner in exclude_providers:
+								if excluded_provider_isowner(p):
+									provider_excluded = True
+									break
 						if not provider_excluded:
 							# This provider is not excluded. It will
 							# satisfy a consumer of this install_name.


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [gentoo-commits] proj/portage:prefix commit in: pym/portage/util/_dyn_libs/
@ 2013-05-29 21:52 Zac Medico
  0 siblings, 0 replies; 17+ messages in thread
From: Zac Medico @ 2013-05-29 21:52 UTC (permalink / raw
  To: gentoo-commits

commit:     d9f1f4b7a6a982f3300d8ff7be3d5feca452b707
Author:     John Stroy <jdstroy>
AuthorDate: Wed May 29 21:51:03 2013 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Wed May 29 21:51:03 2013 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=d9f1f4b7

LinkageMap: fix obj_properties_class spelling

---
 pym/portage/util/_dyn_libs/LinkageMapMachO.py  | 4 ++--
 pym/portage/util/_dyn_libs/LinkageMapPeCoff.py | 2 +-
 pym/portage/util/_dyn_libs/LinkageMapXCoff.py  | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/pym/portage/util/_dyn_libs/LinkageMapMachO.py b/pym/portage/util/_dyn_libs/LinkageMapMachO.py
index e6bdb8e..7cfb18e 100644
--- a/pym/portage/util/_dyn_libs/LinkageMapMachO.py
+++ b/pym/portage/util/_dyn_libs/LinkageMapMachO.py
@@ -27,7 +27,7 @@ class LinkageMapMachO(object):
 	_installname_map_class = slot_dict_class(
 		("consumers", "providers"), prefix="")
 
-	class _obj_properies_class(object):
+	class _obj_properties_class(object):
 
 		__slots__ = ("arch", "needed", "install_name", "alt_paths",
 			"owner",)
@@ -301,7 +301,7 @@ class LinkageMapMachO(object):
 			myprops = obj_properties.get(obj_key)
 			if myprops is None:
 				indexed = False
-				myprops = self._obj_properies_class(
+				myprops = self._obj_properties_class(
 					arch, needed, install_name, [], owner)
 				obj_properties[obj_key] = myprops
 			# All object paths are added into the obj_properties tuple.

diff --git a/pym/portage/util/_dyn_libs/LinkageMapPeCoff.py b/pym/portage/util/_dyn_libs/LinkageMapPeCoff.py
index 0a42784..fd0ab6e 100644
--- a/pym/portage/util/_dyn_libs/LinkageMapPeCoff.py
+++ b/pym/portage/util/_dyn_libs/LinkageMapPeCoff.py
@@ -248,7 +248,7 @@ class LinkageMapPeCoff(LinkageMapELF):
 			myprops = obj_properties.get(obj_key)
 			if myprops is None:
 				indexed = False
-				myprops = self._obj_properies_class(
+				myprops = self._obj_properties_class(
 					arch, needed, path, soname, [], owner)
 				obj_properties[obj_key] = myprops
 			# All object paths are added into the obj_properties tuple.

diff --git a/pym/portage/util/_dyn_libs/LinkageMapXCoff.py b/pym/portage/util/_dyn_libs/LinkageMapXCoff.py
index 06789b5..6c4c994 100644
--- a/pym/portage/util/_dyn_libs/LinkageMapXCoff.py
+++ b/pym/portage/util/_dyn_libs/LinkageMapXCoff.py
@@ -272,7 +272,7 @@ class LinkageMapXCoff(LinkageMapELF):
 			myprops = obj_properties.get(obj_key)
 			if myprops is None:
 				indexed = False
-				myprops = self._obj_properies_class(
+				myprops = self._obj_properties_class(
 					arch, needed, path, soname, [], owner)
 				obj_properties[obj_key] = myprops
 			# All object paths are added into the obj_properties tuple.


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [gentoo-commits] proj/portage:prefix commit in: pym/portage/util/_dyn_libs/
@ 2015-06-09 18:30 Fabian Groffen
  0 siblings, 0 replies; 17+ messages in thread
From: Fabian Groffen @ 2015-06-09 18:30 UTC (permalink / raw
  To: gentoo-commits

commit:     a719fc4b3e858ab8ddf6e64be5bf632624bdbe7d
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Tue Jun  9 18:30:16 2015 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Tue Jun  9 18:30:16 2015 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=a719fc4b

LinkageMapELF: remove conflict marker

 pym/portage/util/_dyn_libs/LinkageMapELF.py | 1 -
 1 file changed, 1 deletion(-)

diff --git a/pym/portage/util/_dyn_libs/LinkageMapELF.py b/pym/portage/util/_dyn_libs/LinkageMapELF.py
index d5d3a55..b32ee81 100644
--- a/pym/portage/util/_dyn_libs/LinkageMapELF.py
+++ b/pym/portage/util/_dyn_libs/LinkageMapELF.py
@@ -43,7 +43,6 @@ _approx_multilib_categories = {
 	"SPARCV9":       "sparc_64",
 	"X86_64":        "x86_64",
 }
->>>>>>> overlays-gentoo-org/master
 
 class LinkageMapELF(object):
 


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [gentoo-commits] proj/portage:prefix commit in: pym/portage/util/_dyn_libs/
@ 2017-03-24 19:56 Fabian Groffen
  0 siblings, 0 replies; 17+ messages in thread
From: Fabian Groffen @ 2017-03-24 19:56 UTC (permalink / raw
  To: gentoo-commits

commit:     16ef282a3a368e0725e2ebffbd3db4474fcc9f7a
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Fri Mar 24 19:47:00 2017 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Fri Mar 24 19:47:00 2017 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=16ef282a

LinkageMapELF: drop duplicate import

 pym/portage/util/_dyn_libs/LinkageMapELF.py | 1 -
 1 file changed, 1 deletion(-)

diff --git a/pym/portage/util/_dyn_libs/LinkageMapELF.py b/pym/portage/util/_dyn_libs/LinkageMapELF.py
index 54a25e0fd..a063621c1 100644
--- a/pym/portage/util/_dyn_libs/LinkageMapELF.py
+++ b/pym/portage/util/_dyn_libs/LinkageMapELF.py
@@ -23,7 +23,6 @@ from portage.util import varexpand
 from portage.util import writemsg_level
 from portage.util._dyn_libs.NeededEntry import NeededEntry
 from portage.util.elf.header import ELFHeader
-from portage.const import EPREFIX
 
 if sys.hexversion >= 0x3000000:
 	_unicode = str


^ permalink raw reply related	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2017-03-24 19:56 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-03-24 19:56 [gentoo-commits] proj/portage:prefix commit in: pym/portage/util/_dyn_libs/ Fabian Groffen
  -- strict thread matches above, loose matches on Subject: below --
2015-06-09 18:30 Fabian Groffen
2013-05-29 21:52 Zac Medico
2013-05-05  9:14 Fabian Groffen
2013-05-05  9:10 Fabian Groffen
2011-09-20 19:01 Fabian Groffen
2011-09-20 18:25 Fabian Groffen
2011-09-20 18:25 Fabian Groffen
2011-07-26 18:06 Fabian Groffen
2011-07-26 17:35 Fabian Groffen
2011-07-26 17:35 Fabian Groffen
2011-07-26 17:35 Fabian Groffen
2011-07-01 18:52 Fabian Groffen
2011-07-01 18:45 Fabian Groffen
2011-05-28  9:59 Fabian Groffen
2011-05-28  9:48 Fabian Groffen
2011-05-14 13:59 Fabian Groffen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox