[Buildroot] [PATCH 1/6] check-shlibs-deps: new script to check shared library dependencies
Jérôme Pouiller
jezz at sysmic.org
Fri Feb 10 17:22:53 UTC 2017
Hello Samuel,
On Monday 6 February 2017 22:04:23 CET Samuel Martin wrote:
> On Mon, Nov 14, 2016 at 2:22 PM, Jérôme Pouiller <jezz at sysmic.org> wrote:
[...]
> > +# Build dictionnaries from "build/packages-file-list.txt"
> > +def build_dicts(builddir):
> > + pkgsdict = {}
> > + filesdict = {}
> > + with open(os.path.join(builddir, "build", "packages-file-list.txt")) as filelistf:
> > + for line in filelistf.readlines():
> > + pkg, fpath = line.split(",", 1)
> > + fpath = fpath.strip()
> > + fpath = os.path.join(builddir, "target", fpath)
> > + fpath = os.path.normpath(os.path.relpath(fpath))
>
> I wonder why relpath is needed here? since it is resloving relative
> path from the current location, i.e. BR's top directory.
> BTW, is it really the BR's top dir. you want to use here as start path
> to compute the relative path, not $(O)? How does this behave with
> out-of-tree build?
In subsequent case, I need to call realpath() in order to resolve
symlinks. realpath() return an absolute paths, but I prefer to convert
them in relative paths because they are smaller in error messages.
In case above, relpath is necessary because 'builddir' may be absolute.
> > + add_file(pkgsdict, filesdict, fpath, pkg)
> > + return filesdict, pkgsdict
> > +
> > +# Return package associated to a file
> > +def get_package(filesdict, fpath):
> > + if not fpath in filesdict:
> > + #print("WARNING: %s is not part of any package" % fpath)
> > + # Do not flood user with warning messages. Especially host-gcc-final
> > + # does not declare its files and produce many warnings.
> > + filesdict[fpath] = "unknown"
> > + return filesdict[fpath]
> > +
> > +# Return list of libraries linked with a binary
> > +def get_shared_libs(builddir, binary):
> > + libs = set()
> > + # Host readelf seems able to read foreign binaries (tested with arm/glibc and arm/uclibc)
> > + pipe = subprocess.Popen([ "readelf", "-d", binary ], stdout=subprocess.PIPE)
>
> Side note:
> There is this project [1] out-there that looks nice, but I wonder if
> it is worthwhile to add/embedded another python modules dependency to
> BR.
Interesting. (But not enough interesting to rewrite this script :) )
> > + for line in pipe.stdout:
> > + match = re.match("^.* \(NEEDED\) .*Shared library: \[(.+)\]$",
> > line)
> > + if match:
> > + libname = match.group(1)
> > + # Support case where "/lib" s a symlink to "/usr/lib"
> > + lpaths = set()
> > + for dir in [ "usr/lib", "lib" ]:
> > +
> > lpaths.add(os.path.relpath(os.path.realpath(os.path.join(builddir,
> > "target", dir, libname))))>
> ditto for relpath/start path.
[...]
> > +# Return files found in "target/"
> > +def build_file_list(builddir):
> > + files = set()
> > + for dirpath, _, filelist in os.walk(os.path.join(builddir,
> > "target")):
> > + for f in filelist:
> > + file = os.path.join(dirpath, f)
> > + file = os.path.relpath(os.path.realpath(file))
>
> ditto for relpath/start path.
[...]
> > + for p, pdeps in sorted(pkgdeps.items()):
> > + if not deps == None:
>
> s/deps == None/deps is None/
ok
> or simply: if deps:
I do want to make a difference between [] and None (see below). So I
think "if deps:" does not work.
[...]
> > +parser = argparse.ArgumentParser(description='Show or check binary dependencies based on linked shared libraries')
> > +
> > +parser.add_argument("--builddir", '-b', metavar="BUILDDIR", required=True,
> > + help="Buildroot output directory")
> > +parser.add_argument("--package", '-p', metavar="PACKAGE",
> > + help="Check only PACKAGE (else, show dpendencies of all binairies)")
> > +parser.add_argument("--deps", '-d', metavar="DEP1,DEP2,...", nargs='?', default="",
> > + help="Report errors if found dependencies are not a subset of '--deps'. Pass "". '-p' is mandatory with this option")
> > +parser.add_argument('-w', action='store_true',
> > + help="Do not return non zero when dependency is missing")
> > +args = parser.parse_args()
> > +if not args.package and args.deps:
> > + print("ERROR: cannot use --deps wihout --package")
> > + exit(1)
> > +
> > +if args.deps == "":
> > + deps = None
> > +elif args.deps == None:
> > + deps = []
>
> What is the difference between "deps = None" and "deps = []"?
'None' means user don't to check dependencies (-d is not used) while '[]'
means package shouldn't have dependencies.
However, my current implementation is broken. Following command does not
work as expected:
check-shlibs-deps -b OUTDIR -p PACKAGE -d ""
I will change that.
> > +else:
> > + deps = args.deps.split(",")
> > +
[...]
--
Jérôme Pouiller, Sysmic
Embedded Linux specialist
http://www.sysmic.fr
More information about the buildroot
mailing list