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
next 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