public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Mike Frysinger (vapier)" <vapier@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] gentoo-projects commit in pax-utils: lddtree.py
Date: Tue, 13 Nov 2012 05:10:37 +0000 (UTC)	[thread overview]
Message-ID: <20121113051037.CAF5B20C65@flycatcher.gentoo.org> (raw)

vapier      12/11/13 05:10:37

  Modified:             lddtree.py
  Log:
  lddtree.py: add a --copy-to-tree option so people can quickly copy ELFs and their dependencies to a different location (useful for initramfs and such)

Revision  Changes    Path
1.5                  pax-utils/lddtree.py

file : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/pax-utils/lddtree.py?rev=1.5&view=markup
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-projects/pax-utils/lddtree.py?rev=1.5&content-type=text/plain
diff : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/pax-utils/lddtree.py?r1=1.4&r2=1.5

Index: lddtree.py
===================================================================
RCS file: /var/cvsroot/gentoo-projects/pax-utils/lddtree.py,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- lddtree.py	13 Nov 2012 02:33:01 -0000	1.4
+++ lddtree.py	13 Nov 2012 05:10:37 -0000	1.5
@@ -2,7 +2,7 @@
 # Copyright 2012 Gentoo Foundation
 # Copyright 2012 Mike Frysinger <vapier@gentoo.org>
 # Distributed under the terms of the GNU General Public License v2
-# $Header: /var/cvsroot/gentoo-projects/pax-utils/lddtree.py,v 1.4 2012/11/13 02:33:01 vapier Exp $
+# $Header: /var/cvsroot/gentoo-projects/pax-utils/lddtree.py,v 1.5 2012/11/13 05:10:37 vapier Exp $
 
 """Read the ELF dependency tree and show it
 
@@ -15,6 +15,7 @@
 import glob
 import optparse
 import os
+import shutil
 import sys
 
 from elftools.elf.elffile import ELFFile
@@ -193,6 +194,7 @@
 	"""
 	ret = {
 		'interp': None,
+		'path': file,
 		'needed': [],
 		'libs': _all_libs,
 	}
@@ -261,18 +263,94 @@
 	return ret
 
 
-def _NormalizeRoot(_option, _opt, value, parser):
-	parser.values.root = normpath(value)
-	if parser.values.root == '/':
-		parser.values.root = ''
+def _NormalizePath(option, _opt, value, parser):
+	setattr(parser.values, option.dest, normpath(value))
 
 
 def _ShowVersion(_option, _opt, _value, _parser):
-	id = '$Id: lddtree.py,v 1.4 2012/11/13 02:33:01 vapier Exp $'.split()
+	id = '$Id: lddtree.py,v 1.5 2012/11/13 05:10:37 vapier Exp $'.split()
 	print('%s-%s %s %s' % (id[1].split('.')[0], id[2], id[3], id[4]))
 	sys.exit(0)
 
 
+def _ActionShow(options, elf):
+	"""Show the dependency tree for this ELF"""
+	def _show(lib, depth):
+		chain_libs.append(lib)
+		fullpath = elf['libs'][lib]['path']
+		if options.list:
+			print(fullpath or lib)
+		else:
+			print('%s%s => %s' % ('    ' * depth, lib, fullpath))
+
+		new_libs = []
+		for lib in elf['libs'][lib]['needed']:
+			if lib in chain_libs:
+				if not options.list:
+					print('%s%s => !!! circular loop !!!' % ('    ' * depth, lib))
+				continue
+			if options.all or not lib in shown_libs:
+				shown_libs.add(lib)
+				new_libs.append(lib)
+
+		for lib in new_libs:
+			_show(lib, depth + 1)
+		chain_libs.pop()
+
+	shown_libs = set(elf['needed'])
+	chain_libs = []
+	interp = elf['interp']
+	if interp:
+		shown_libs.add(os.path.basename(interp))
+	if options.list:
+		print(elf['path'])
+		if not interp is None:
+			print(interp)
+	else:
+		print('%s (interpreter => %s)' % (elf['path'], interp))
+	for lib in elf['needed']:
+		_show(lib, 1)
+
+
+def _ActionCopy(options, elf):
+	"""Copy the ELF and its dependencies to a destination tree"""
+	def _copy(file):
+		if file is None:
+			return
+
+		dest = options.dest + file
+		if os.path.exists(dest):
+			# See if they're the same file.
+			ostat = os.stat(file)
+			nstat = os.stat(dest)
+			for field in ('mode', 'mtime', 'size'):
+				if getattr(ostat, 'st_' + field) != \
+				   getattr(nstat, 'st_' + field):
+					break
+			else:
+				return
+
+		if options.verbose:
+			print('%s -> %s' % (file, dest))
+
+		try:
+			os.makedirs(os.path.dirname(dest))
+		except OSError as e:
+			if e.errno != os.errno.EEXIST:
+				raise
+		try:
+			shutil.copy2(file, dest)
+			return
+		except IOError:
+			os.unlink(dest)
+		shutil.copy2(file, dest)
+
+	_copy(elf['path'])
+	_copy(elf['interp'])
+	for lib in elf['libs']:
+		_copy(elf['libs'][lib]['path'])
+
+
 def main(argv):
 	parser = optparse.OptionParser("""%prog [options] <ELFs>
 
@@ -282,24 +360,34 @@
 		help=('Show all duplicated dependencies'))
 	parser.add_option('-R', '--root',
 		dest='root', default=os.environ.get('ROOT', ''), type='string',
-		action='callback', callback=_NormalizeRoot,
+		action='callback', callback=_NormalizePath,
 		help=('Show all duplicated dependencies'))
+	parser.add_option('--copy-to-tree',
+		dest='dest', default=None, type='string',
+		action='callback', callback=_NormalizePath,
+		help=('Copy all files to the specified tree'))
 	parser.add_option('-l', '--list',
 		action='store_true', default=False,
 		help=('Display output in a simple list (easy for copying)'))
 	parser.add_option('-x', '--debug',
 		action='store_true', default=False,
 		help=('Run with debugging'))
+	parser.add_option('-v', '--verbose',
+		action='store_true', default=False,
+		help=('Be verbose'))
 	parser.add_option('-V', '--version',
 		action='callback', callback=_ShowVersion,
 		help=('Show version information'))
 	(options, files) = parser.parse_args(argv)
 
 	files.pop(0)
-	options.root += '/'
+	if options.root != '/':
+		options.root += '/'
 
 	if options.debug:
 		print('root =', options.root)
+		if options.dest:
+			print('dest =', options.dest)
 	if not files:
 		err('missing ELF files to scan')
 
@@ -325,29 +413,7 @@
 		print('ldpaths[conf] =', ldpaths['conf'])
 		print('ldpaths[env]  =', ldpaths['env'])
 
-	# Now show the tree for each specified ELF.
-	def _show(lib, depth):
-		chain_libs.append(lib)
-		fullpath = elf['libs'][lib]['path']
-		if options.list:
-			print(fullpath or lib)
-		else:
-			print('%s%s => %s' % ('    ' * depth, lib, fullpath))
-
-		new_libs = []
-		for lib in elf['libs'][lib]['needed']:
-			if lib in chain_libs:
-				if not options.list:
-					print('%s%s => !!! circular loop !!!' % ('    ' * depth, lib))
-				continue
-			if options.all or not lib in shown_libs:
-				shown_libs.add(lib)
-				new_libs.append(lib)
-
-		for lib in new_libs:
-			_show(lib, depth + 1)
-		chain_libs.pop()
-
+	# Process all the files specified.
 	ret = 0
 	for file in files:
 		try:
@@ -356,19 +422,10 @@
 			ret = 1
 			warn('%s: %s' % (file, e))
 			continue
-		shown_libs = set(elf['needed'])
-		chain_libs = []
-		interp = elf['interp']
-		if interp:
-			shown_libs.add(os.path.basename(interp))
-		if options.list:
-			print(file)
-			if not interp is None:
-				print(interp)
+		if options.dest is None:
+			_ActionShow(options, elf)
 		else:
-			print('%s (interpreter => %s)' % (file, interp))
-		for lib in elf['needed']:
-			_show(lib, 1)
+			_ActionCopy(options, elf)
 	return ret
 
 





             reply	other threads:[~2012-11-13  5:10 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-11-13  5:10 Mike Frysinger (vapier) [this message]
  -- strict thread matches above, loose matches on Subject: below --
2014-11-20  1:22 [gentoo-commits] gentoo-projects commit in pax-utils: lddtree.py Mike Frysinger (vapier)
2014-11-20  1:17 Mike Frysinger (vapier)
2014-11-20  1:13 Mike Frysinger (vapier)
2014-08-01  2:20 Mike Frysinger (vapier)
2014-08-01  1:39 Mike Frysinger (vapier)
2014-07-30 14:35 Mike Frysinger (vapier)
2014-07-30  8:22 Mike Frysinger (vapier)
2014-07-30  4:34 Mike Frysinger (vapier)
2014-07-30  4:28 Mike Frysinger (vapier)
2014-07-30  4:16 Mike Frysinger (vapier)
2014-07-30  4:07 Mike Frysinger (vapier)
2014-07-30  4:06 Mike Frysinger (vapier)
2014-03-20  8:25 Mike Frysinger (vapier)
2014-03-20  8:18 Mike Frysinger (vapier)
2013-04-23  2:16 Mike Frysinger (vapier)
2013-04-22 22:02 Mike Frysinger (vapier)
2013-04-22 18:31 Mike Frysinger (vapier)
2013-04-05 22:26 Mike Frysinger (vapier)
2013-04-03  4:51 Mike Frysinger (vapier)
2013-03-28 17:14 Mike Frysinger (vapier)
2013-03-28  1:17 Mike Frysinger (vapier)
2013-03-28  0:58 Mike Frysinger (vapier)
2013-03-27  3:22 Mike Frysinger (vapier)
2013-03-27  3:20 Mike Frysinger (vapier)
2013-03-27  3:20 Mike Frysinger (vapier)
2013-03-27  3:07 Mike Frysinger (vapier)
2013-03-26  5:22 Mike Frysinger (vapier)
2013-03-26  5:03 Mike Frysinger (vapier)
2013-03-26  4:50 Mike Frysinger (vapier)
2013-03-25 22:35 Mike Frysinger (vapier)
2013-03-24  5:37 Mike Frysinger (vapier)
2013-03-24  5:27 Mike Frysinger (vapier)
2013-03-23  7:28 Mike Frysinger (vapier)
2013-03-21 22:55 Mike Frysinger (vapier)
2013-03-21  3:04 Mike Frysinger (vapier)
2013-03-21  3:03 Mike Frysinger (vapier)
2013-01-05 20:39 Mike Frysinger (vapier)
2012-12-14  4:22 Mike Frysinger (vapier)
2012-11-26 20:06 Mike Frysinger (vapier)
2012-11-24 19:44 Mike Frysinger (vapier)
2012-11-24 17:01 Mike Frysinger (vapier)
2012-11-24 16:54 Mike Frysinger (vapier)
2012-11-17  0:11 Mike Frysinger (vapier)
2012-11-16 23:53 Mike Frysinger (vapier)
2012-11-15 20:39 Mike Frysinger (vapier)
2012-11-15 20:28 Mike Frysinger (vapier)
2012-11-15 20:26 Mike Frysinger (vapier)
2012-11-15 19:33 Mike Frysinger (vapier)
2012-11-13  2:33 Mike Frysinger (vapier)
2012-11-12 23:08 Mike Frysinger (vapier)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20121113051037.CAF5B20C65@flycatcher.gentoo.org \
    --to=vapier@gentoo.org \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox