From 118b880d73e812069ec2fe72f921d70894eb10a0 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Thu, 6 May 2010 10:05:43 +0200 Subject: package: Add new -show-depends to list dependencies The new -show-depends simply outputs the list of dependencies for the given package. Signed-off-by: Thomas Petazzoni --- package/Makefile.package.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/package/Makefile.package.in b/package/Makefile.package.in index c2f86c7be..cdf49f8fe 100644 --- a/package/Makefile.package.in +++ b/package/Makefile.package.in @@ -338,6 +338,9 @@ $(1)-extract: $(1)-depends \ $(1)-depends: $(1)-source $$($(2)_DEPENDENCIES) +$(1)-show-depends: + @echo $$($(2)_DEPENDENCIES) + $(1)-source: $$($(2)_TARGET_SOURCE) $(1)-uninstall: $(1)-configure $$($(2)_TARGET_UNINSTALL) -- cgit v1.2.3 From 949db6ac05e42a90ee82e3f979805d98c41fa4f6 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Thu, 13 May 2010 19:20:21 +0200 Subject: Add a -root-show-depends target Signed-off-by: Thomas Petazzoni --- fs/common.mk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/common.mk b/fs/common.mk index a3248c165..50dc97425 100644 --- a/fs/common.mk +++ b/fs/common.mk @@ -57,6 +57,9 @@ ifeq ($$(BR2_TARGET_ROOTFS_$(2)_LZMA),y) $(LZMA) -9 -c $$@ > $$@.lzma endif +$(1)-root-show-depends: + @echo $(ROOTFS_$(2)_DEPENDENCIES) host-fakeroot host-makedevs $(if $(BR2_TARGET_ROOTFS_$(2)_LZMA),host-lzma) + $(1)-root: $(BINARIES_DIR)/rootfs.$(1) ifeq ($$(BR2_TARGET_ROOTFS_$(2)),y) -- cgit v1.2.3 From b7d6c8ad0f786552e21d91d97ad4221ebc43876f Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Thu, 13 May 2010 19:20:33 +0200 Subject: Add a show-targets target Signed-off-by: Thomas Petazzoni --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index a4bf4b570..ec2ec36ab 100644 --- a/Makefile +++ b/Makefile @@ -449,6 +449,9 @@ external-deps: @$(MAKE) -Bs BR2_WGET=$(TOPDIR)/toolchain/wget-show-external-deps.sh \ SPIDER=--spider source +show-targets: + @echo $(TARGETS) + ifeq ($(BR2_CONFIG_CACHE),y) # drop configure cache if configuration is changed $(BUILD_DIR)/tgt-config.cache: .config -- cgit v1.2.3 From 0e12aa3e0f9a3a1170196c1f078f633fcbc92568 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Thu, 6 May 2010 10:09:14 +0200 Subject: New graph-depends script Add a Python script that draws dependency graphs, either for the full set of selected packages, or for a particular given package. Of course, it is limited to packages that use either the generic or autotools infrastructures. The script generates a file that Graphviz can parse and generate a PDF (or other formats) from it. Full dependency graph of all selected packages : ./scripts/graph-depends > test.dot dot -Tpdf test.dot -o test.pdf Dependency graph of libgtk2 : ./scripts/graph-depends libgtk2 > test.dot dot -Tpdf test.dot -o test.pdf Signed-off-by: Thomas Petazzoni --- scripts/graph-depends | 169 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100755 scripts/graph-depends diff --git a/scripts/graph-depends b/scripts/graph-depends new file mode 100755 index 000000000..4d82282f5 --- /dev/null +++ b/scripts/graph-depends @@ -0,0 +1,169 @@ +#!/usr/bin/python + +# Usage (the graphviz package must be installed in your distribution) +# ./scripts/graph-depends [package-name] > test.dot +# dot -Tpdf test.dot -o test.pdf +# +# With no arguments, graph-depends will draw a complete graph of +# dependencies for the current configuration. With an argument, +# graph-depends will draw a graph of dependencies for the given +# package name. +# +# Limitations +# +# * Some packages have dependencies that depend on the Buildroot +# configuration. For example, many packages have a dependency on +# openssl if openssl has been enabled. This tool will graph the +# dependencies as they are with the current Buildroot +# configuration. +# +# * The X.org package definitions are only included when +# BR2_PACKAGE_XORG7 is enabled, so if this option is not enabled, +# it isn't possible to graph the dependencies of X.org stack +# components. +# +# Copyright (C) 2010 Thomas Petazzoni + +import sys +import subprocess + +# In FULL_MODE, we draw the full dependency graph for all selected +# packages +FULL_MODE = 1 + +# In PKG_MODE, we only draw the dependency graph for a given package +PKG_MODE = 2 + +mode = 0 + +if len(sys.argv) == 1: + mode = FULL_MODE +elif len(sys.argv) == 2: + mode = PKG_MODE + rootpkg = sys.argv[1] +else: + print "Usage: graph-depends [package-name]" + sys.exit(1) + +allpkgs = [] +unknownpkgs = [] + +# Execute the "make show-targets" command to get the list of the main +# Buildroot TARGETS and return it formatted as a Python list. This +# list is used as the starting point for full dependency graphs +def get_targets(): + sys.stderr.write("Getting targets\n") + cmd = ["make", "show-targets"] + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + output = p.communicate()[0].strip() + if p.returncode != 0: + return None + if output == '': + return [] + return output.split(' ') + +# Execute the "make -show-depends" command to get the list of +# dependencies of a given package, and return the list of dependencies +# formatted as a Python list. +def get_depends(pkg): + sys.stderr.write("Getting dependencies for %s\n" % pkg) + cmd = ["make", "%s-show-depends" % pkg] + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + output = p.communicate()[0].strip() + if p.returncode != 0: + return None + if output == '': + return [] + return output.split(' ') + +# Recursive function that builds the tree of dependencies for a given +# package. The dependencies are built in a list called 'dependencies', +# which contains tuples of the form (pkg1 -> +# pkg2_on_which_pkg1_depends) and the function finally returns this +# list. +def get_all_depends(pkg): + dependencies = [] + + # We already have the dependencies for this package + if pkg in allpkgs: + return + allpkgs.append(pkg) + depends = get_depends(pkg) + + # We couldn't get the dependencies of this package, because it + # doesn't use the generic or autotools infrastructure. Add it to + # unknownpkgs so that it is later rendered in red color to warn + # the user. + if depends == None: + unknownpkgs.append(pkg) + return + + # This package has no dependency. + if depends == []: + return + + # Add dependencies to the list of dependencies + for dep in depends: + dependencies.append((pkg, dep)) + + # Recurse into the dependencies + for dep in depends: + newdeps = get_all_depends(dep) + if newdeps != None: + dependencies += newdeps + + return dependencies + +# The Graphviz "dot" utility doesn't like dashes in node names. So for +# node names, we strip all dashes. +def pkg_node_name(pkg): + return pkg.replace("-","") + +# In full mode, start with the result of get_targets() to get the main +# targets and then use get_all_depends() for each individual target. +if mode == FULL_MODE: + targets = get_targets() + dependencies = [] + allpkgs.append('all') + for tg in targets: + # Skip uninteresting targets + if tg == 'target-generic-issue' or \ + tg == 'target-finalize' or \ + tg == 'erase-fakeroots' or \ + tg == 'target-generic-hostname': + continue + dependencies.append(('all', tg)) + deps = get_all_depends(tg) + if deps != None: + dependencies += deps + +# In pkg mode, start directly with get_all_depends() on the requested +# package +elif mode == PKG_MODE: + dependencies = get_all_depends(rootpkg) + +# Start printing the graph data +print "digraph G {" + +# First, the dependencies. Usage of set allows to remove duplicated +# dependencies in the graph +for dep in set(dependencies): + print "%s -> %s" % (pkg_node_name(dep[0]), pkg_node_name(dep[1])) + +# Then, the node attributes: color, style and label. +for pkg in allpkgs: + if pkg == 'all': + print "all [label = \"ALL\"]" + print "all [color=lightblue,style=filled]" + continue + + print "%s [label = \"%s\"]" % (pkg_node_name(pkg), pkg) + + if pkg in unknownpkgs: + print "%s [color=red,style=filled]" % pkg_node_name(pkg) + elif mode == PKG_MODE and pkg == rootpkg: + print "%s [color=lightblue,style=filled]" % pkg_node_name(rootpkg) + else: + print "%s [color=grey,style=filled]" % pkg_node_name(pkg) + +print "}" -- cgit v1.2.3