Skip to contentSkip to conversation

graph-depends improvements (branch yem/graphs)

PATCH Superseded Yann E. MORIN 3 participants 13 messages May 16, 2014 – May 30, 2014 Kbuild

v3 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

v3 cover graph-depends improvements (branch yem/graphs)

From: "Yann E. MORIN" <[email protected]>

Hello All!

This series brings a few improvements to the graph-depends utility:

- add option to remove transitive dependencies
- add option to pas arbitrary args to the dot utility
- cleanup and re-arrange the code

This series is open for discusion, especially on how we pass options to the graph generators:

- support/scripts/graph-depends: needs to know whether to generate transitive dependencies or not, and how deep to limit the dependencies

- the 'dot' utility: needs to know whether to graph top-down or left-right (or whatever), the type of graph (tree, circle...) and so on...

Currently, environment variables are used, but that is not in the tastes of some (me including), but I can't see a better way.

Peter suggested using kconfig knobs, but it does not scale when you want different settings for different graphs (e.g, different depth level for different packages).

Samuel suggested using a config file, but it has the same issues as the kconfig options. He also suggested pasing a single environment variable, but that does not work since some options are for graph-depends shile others are for dot.

So I went for:

- renaming the existing DEPTH variable: we can do that since it's been in no release for now (quick! let's apply at least the first patch for this cycle! ;-) )

- add a new variable to pass options to dot

Changes v2 -> v3:
- pythonise even further the handling of --depth (Samuel)
- rename BR2_GRAPH_DEPTH to BR2_GRAPH_DEPS_OPTS
- introduce BR2_GRAPH_DOT_OPTS
- update manual accordingly

Changes v1 -> v2:
- complete rewrite, split into a series

Regards,
Yann E. MORIN.

The following changes since commit ae1df831c0d56aaa88741595963e97aa39ed5961:

package/avahi: does not build with static-only (2014-05-16 22:41:55 +0200)

are available in the git repository at:

git://gitorious.org/buildroot/buildroot.git

for you to fetch changes up to 62b0daddcbd6ba88226ca7cb658b9ad021168b56:

manual: document the new graph-depends options (2014-05-16 22:57:56 +0200)

----------------------------------------------------------------
Yann E. MORIN (8):
graph-depends: rename the variable to pass the max depth
graphs: add option to remove transitive dependencies in dependency graph
graphs-depends: merge redundant-dependencies elimination
graph-depends: handle the depth argument in a more pythonic way
graph-depends: document the max_depth variable
graph-depends: rename the mode constants
graph-depends: add option to pass arbitrary dot options
manual: document the new graph-depends options

 Makefile                      |   5 +-
 docs/manual/common-usage.txt  |  19 ++++++-
 foo                           |   0
 package/pkg-generic.mk        |   4 +-
 support/scripts/graph-depends | 125 ++++++++++++++++++++++++------------------
 5 files changed, 94 insertions(+), 59 deletions(-)
 create mode 100644 foo
Signature · 6 lines
.-----------------.--------------------.------------------.--------------------.
|  Yann E. MORIN  | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
| +33 662 376 056 | Software  Designer | \ / CAMPAIGN     |  ___               |
| +33 223 225 172 `------------.-------:  X  AGAINST      |  \e/  There is no  |
| http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL    |   v   conspiracy.  |
'------------------------------^-------^------------------^--------------------'
#1 lore raw

PATCH v3 1/8 graph-depends: rename the variable to pass the max depth

From: "Yann E. MORIN" <[email protected]>

There will soon be new options to the graph-depends script, which we can only sanely pass via environment variables.

Currently, we use such an environment variable to pass the maximum depth of the dependency graph; the name of that variable is explicit that it contains just the depth.

However, there has been so far no release of Buildroot which would make use of that variable, so no user should have come to rely on it.

Rename that variable so it is less specific, and more generic, so it can be used to pass more options to graph-depends.

Cc Thomas Petazzoni <[email protected]>
Cc Maxime Hadjinlian <[email protected]>
Cc Samuel Martin <[email protected]>
---
 Makefile                     |  3 +--
 docs/manual/common-usage.txt | 14 ++++++++++++--
 foo                          |  0
 package/pkg-generic.mk       |  2 +-
 4 files changed, 14 insertions(+), 5 deletions(-)
 create mode 100644 foo
Makefile +1 -2
index 6d97262..d91231c 100644
@@ -150,7 +150,6 @@ endif
 # Need that early, before we scan packages
 # Avoids doing the $(or...) everytime
 BR_GRAPH_OUT := $(or $(BR2_GRAPH_OUT),pdf)
-BR_GRAPH_DEPTH := $(or $(BR2_GRAPH_DEPTH),0)
 
 BUILD_DIR := $(BASE_DIR)/build
 BINARIES_DIR := $(BASE_DIR)/images
@@ -675,7 +674,7 @@ graph-build: $(O)/build/build-time.log
 graph-depends:
 	@$(INSTALL) -d $(O)/graphs
 	@cd "$(CONFIG_DIR)"; \
-	$(TOPDIR)/support/scripts/graph-depends -d $(BR_GRAPH_DEPTH) \
+	$(TOPDIR)/support/scripts/graph-depends $(BR2_GRAPH_DEPS_OPTS) \
 	|tee $(O)/graphs/$(@).dot \
 	|dot -T$(BR_GRAPH_OUT) -o $(O)/graphs/$(@).$(BR_GRAPH_OUT)
 
docs/manual/common-usage.txt +12 -2
index 3d5842d..772982a 100644
@@ -92,8 +92,8 @@ to +make+ or set in the environment:
   build-time graphs
 * +BR2_GRAPH_OUT+ to set the filetype of generated graphs, either +pdf+ (the
   default), or +png+.
-* +BR2_GRAPH_DEPTH+ (an integer) to limit the depth of the dependency graph.
-  The default, +0+, is to not limit the depth.
+* +BR2_GRAPH_DEPS_OPTS+ to pass extra options to the dependency graph; see
+  xref:graph-depends[] for the accepted options
 
 An example that uses config files located in the toplevel directory and
 in your $HOME:
@@ -198,6 +198,16 @@ supported.
 BR2_GRAPH_OUT=svg make graph-depends
 --------------------------------
 
+The +graph-depends+ behaviour can be controlled by setting options in the
++BR2_GRAPH_DEPS_OPTS+ environment variable. The accepted options are:
+
+* +--depth N+, +-d N+, to limit the dependency depth to +N+ levels. The
+  default, +0+, means no limit.
+
+--------------------------------
+BR2_GRAPH_DEPS_OPTS='-d 3' make graph-depends
+--------------------------------
+
 === Graphing the build duration
 
 [[graph-duration]]
foo new file +0 -0
new file mode 100644
index 0000000..e69de29
package/pkg-generic.mk +1 -1
index 6eca6d4..426d269 100644
@@ -512,7 +512,7 @@ $(1)-show-depends:
 $(1)-graph-depends:
 			@$(INSTALL) -d $(O)/graphs
 			@cd "$(CONFIG_DIR)"; \
-			$(TOPDIR)/support/scripts/graph-depends -p $(1) -d $(BR_GRAPH_DEPTH) \
+			$(TOPDIR)/support/scripts/graph-depends -p $(1) $(BR2_GRAPH_DEPS_OPTS) \
 			|tee $(O)/graphs/$$(@).dot \
 			|dot -T$(BR_GRAPH_OUT) -o $(O)/graphs/$$(@).$(BR_GRAPH_OUT)
 
Signature · 1 line
1.8.3.2
#2 lore raw

PATCH 1/8 graph-depends: rename the variable to pass the max depth

Quoted 13 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

"Yann" == Yann E MORIN <[email protected]> writes:

From: "Yann E. MORIN" <[email protected]>
There will soon be new options to the graph-depends script, which we can only sanely pass via environment variables.

Currently, we use such an environment variable to pass the maximum depth of the dependency graph; the name of that variable is explicit that it contains just the depth.

However, there has been so far no release of Buildroot which would make use of that variable, so no user should have come to rely on it.

Quoted 7 lines

Rename that variable so it is less specific, and more generic, so it can be used to pass more options to graph-depends.

Cc Thomas Petazzoni <[email protected]>
Cc Maxime Hadjinlian <[email protected]>
Cc Samuel Martin <[email protected]>

Committed, thanks. The rest of the series is imho for 2014.08, but this one makes sense to apply now.

Signature · 1 line
Bye, Peter Korsgaard
#3 lore raw

PATCH v3 2/8 graphs: add option to remove transitive dependencies in dependency graph

In reply to Yann E. MORIN

From: "Yann E. MORIN" <[email protected]>

Currently, all the dependencies of a package are drawn on the dependency graph, including transitive dependencies (e.g. A->B->C and A->C).

For very big graphs, with lots of packages with lots of dependencies, the dependency graph can be very dense, and transitive dependencies are cluttering the graph.

In some cases, only getting the "build-order" dependencies is enough (e.g. to see what impact a package rebuild would have).

Add a new environment variable to disable drawing transitive dependencies.

Basically, it would turn this graph:

    pkg1 ---> pkg2 ---> pkg3 -------------------.
         |\__________/                 \         \
         |\____________________         \         \
         |                     \         \         \
          `-> pkg4 ---> pkg5 ---> pkg6 ---> pkg7 ---> pkg8
                    \__________/

into that graph:

    pkg1 ---> pkg2 ---> pkg3 -----------.
         |                               \
          `-> pkg4 ---> pkg5 ---> pkg6 ---> pkg7 ---> pkg8

[Thanks to Samuel for the parser hints]

Cc Thomas Petazzoni <[email protected]>
Cc Maxime Hadjinlian <[email protected]>
Cc Samuel Martin <[email protected]>

---
Note: some graphs showing the results are there:
http://ymorin.is-a-geek.org/download/tmp/graphs/

---
 support/scripts/graph-depends | 49 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)
support/scripts/graph-depends +49 -0
index e2a5e1e..4ad18b4 100755
@@ -40,6 +40,10 @@ parser.add_argument("--package", '-p', metavar="PACKAGE",
                     help="Graph the dependencies of PACKAGE")
 parser.add_argument("--depth", '-d', metavar="DEPTH",
                     help="Limit the dependency graph to DEPTH levels")
+parser.add_argument("--transitive", dest="transitive", action='store_true')
+parser.add_argument("--no-transitive", dest="transitive", action='store_false',
+                    default=True,
+                    help="Draw (do not draw) transitive dependencies")
 args = parser.parse_args()
 
 if args.package is None:
@@ -51,6 +55,8 @@ else:
 if args.depth is not None:
     max_depth = int(args.depth)
 
+transitive = args.transitive
+
 allpkgs = []
 
 # Execute the "make show-targets" command to get the list of the main
@@ -220,6 +226,49 @@ for dep in dependencies:
         dict_deps[dep[0]] = []
     dict_deps[dep[0]].append(dep[1])
 
+# This function return True if pkg is a dependency (direct or
+# transitive) of pkg2, dependencies being listed in the deps
+# dictionary. Returns False otherwise.
+def is_dep(pkg,pkg2,deps):
+    if deps.has_key(pkg2):
+        for p in deps[pkg2]:
+            if pkg == p:
+                return True
+            if is_dep(pkg,p,deps):
+                return True
+    return False
+
+# This function eliminates transitive dependencies; for example, given
+# these dependency chain: A->{B,C} and B->{C}, the A->{C} dependency is
+# already covered by B->{C}, so C is a transitive dependency of A, via B.
+# The functions does:
+#   - for each dependency d[i] of the package pkg
+#     - if d[i] is a dependency of any of the other dependencies d[j]
+#       - do not keep d[i]
+#     - otherwise keep d[i]
+def remove_transitive_deps(pkg,deps):
+    d = deps[pkg]
+    new_d = []
+    for i in range(len(d)):
+        keep_me = True
+        for j in range(len(d)):
+            if j==i:
+                continue
+            if is_dep(d[i],d[j],deps):
+                keep_me = False
+        if keep_me:
+            new_d.append(d[i])
+    return new_d
+
+# This functions trims down the dependency list of all packages.
+def remove_extra_deps(deps):
+    for pkg in deps.keys():
+        if not transitive:
+            deps[pkg] = remove_transitive_deps(pkg,deps)
+    return deps
+
+dict_deps = remove_extra_deps(dict_deps)
+
 # Print the attributes of a node: label and fill-color
 def print_attrs(pkg):
     if pkg == 'all':
Signature · 1 line
1.8.3.2
#4 lore raw

PATCH v3 2/8 graphs: add option to remove transitive dependencies in dependency graph

All,

On 2014-05-16 23:05 +0200, Yann E. MORIN spake thusly:
[--SNIP--]

Quoted 1 line

Add a new environment variable to disable drawing transitive dependencies.

[--SNIP--]

support/scripts/graph-depends parser.add_argument("--package", '-p', metavar="PACKAGE", · line 46

Quoted 12 lines
support/scripts/graph-depends +4 -0
index e2a5e1e..4ad18b4 100755
@@ -40,6 +40,10 @@ parser.add_argument("--package", '-p', metavar="PACKAGE",
                     help="Graph the dependencies of PACKAGE")
 parser.add_argument("--depth", '-d', metavar="DEPTH",
                     help="Limit the dependency graph to DEPTH levels")
+parser.add_argument("--transitive", dest="transitive", action='store_true')
+parser.add_argument("--no-transitive", dest="transitive", action='store_false',
+                    default=True,
+                    help="Draw (do not draw) transitive dependencies")

Bummer, this changes the default to not draw transitive deps. Fixed locally, so the default is still to draw them.

Regards,
Yann E. MORIN.

Signature · 6 lines
.-----------------.--------------------.------------------.--------------------.
|  Yann E. MORIN  | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
| +33 662 376 056 | Software  Designer | \ / CAMPAIGN     |  ___               |
| +33 223 225 172 `------------.-------:  X  AGAINST      |  \e/  There is no  |
| http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL    |   v   conspiracy.  |
'------------------------------^-------^------------------^--------------------'
#5 lore raw

PATCH v3 3/8 graphs-depends: merge redundant-dependencies elimination

In reply to Yann E. MORIN

From: "Yann E. MORIN" <[email protected]>

Merge the redundant-dependencies elimination into the newly introduced transitive-dependencies elimination.

This makes the code cleaner and much shorter, because:

- the ('all',pkg) redundant dependency is in fact a transitive dependency, and we now have code to deal with that

- the (pkg,'toolchain') dependency is easy enough to deal with that having a separate function for that is overkill

Cc Thomas Petazzoni <[email protected]>
Cc Maxime Hadjinlian <[email protected]>
Cc Samuel Martin <[email protected]>
---
 support/scripts/graph-depends | 46 +++++++++----------------------------------
 1 file changed, 9 insertions(+), 37 deletions(-)
support/scripts/graph-depends +9 -37
index 4ad18b4..1146ed4 100755
@@ -146,40 +146,6 @@ def get_all_depends(pkgs):
 def pkg_node_name(pkg):
     return pkg.replace("-","")
 
-# Helper function for remove_redundant_deps(). This function tells
-# whether package "pkg" is the dependency of another package that is
-# not the special "all" package.
-def has_redundant_deps(deps, pkg):
-    for dep in deps:
-        if dep[0] != "all" and dep[1] == pkg:
-            return True
-    return False
-
-# This function removes redundant dependencies of the special "all"
-# package. This "all" package is created to reflect the origin of the
-# selection for all packages that are not themselves selected by any
-# other package. So for example if you enable libpng, zlib is enabled
-# as a dependency. But zlib being selected by libpng, it also appears
-# as a dependency of the "all" package. This needlessly complicates
-# the generated dependency graph. So when we have the dependency list
-# (all -> zlib, all -> libpn, libpng -> zlib), we get rid of the 'all
-# -> zlib' dependency, because zlib is already a dependency of a
-# regular package.
-def remove_redundant_deps(deps):
-    newdeps = []
-    for dep in deps:
-        if dep[0] == "all" and dep[1] == "toolchain":
-            newdeps.append(dep)
-            continue
-        if dep[0] != "all" and dep[1] != "toolchain":
-            newdeps.append(dep)
-            continue
-        if not has_redundant_deps(deps, dep[1]):
-            newdeps.append(dep)
-            continue
-        sys.stderr.write("Removing redundant dep %s -> %s\n" % (dep[0],dep[1]))
-    return newdeps
-
 TARGET_EXCEPTIONS = [
     "target-generic-securetty",
     "target-generic-issue",
@@ -217,8 +183,6 @@ if mode == FULL_MODE:
 elif mode == PKG_MODE:
     dependencies = get_all_depends([rootpkg])
 
-dependencies = remove_redundant_deps(dependencies)
-
 # Make the dependencies a dictionnary { 'pkg':[dep1, dep2, ...] }
 dict_deps = {}
 for dep in dependencies:
@@ -260,10 +224,18 @@ def remove_transitive_deps(pkg,deps):
             new_d.append(d[i])
     return new_d
 
+# This function removes the dependency on the 'toolchain' package
+def remove_toolchain_deps(pkg,deps):
+    return [p for p in deps[pkg] if not p == 'toolchain']
+
 # This functions trims down the dependency list of all packages.
+# It applies in sequence all the dependency-elimination methods.
 def remove_extra_deps(deps):
     for pkg in deps.keys():
-        if not transitive:
+        if not pkg == 'all':
+            deps[pkg] = remove_toolchain_deps(pkg,deps)
+    for pkg in deps.keys():
+        if not transitive or pkg == 'all':
             deps[pkg] = remove_transitive_deps(pkg,deps)
     return deps
 
Signature · 1 line
1.8.3.2
#6 lore raw

PATCH v3 4/8 graph-depends: handle the depth argument in a more pythonic way

In reply to Yann E. MORIN

From: "Yann E. MORIN" <[email protected]>

Add some comment as well, enhance help text.

[thanks to Samuel for the hints to make it even more pythonic]

Cc Thomas Petazzoni <[email protected]>
Cc Maxime Hadjinlian <[email protected]>
Cc Samuel Martin <[email protected]>
---
 support/scripts/graph-depends | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)
support/scripts/graph-depends +5 -4
index 1146ed4..c3dcbf1 100755
@@ -33,13 +33,15 @@ FULL_MODE = 1
 PKG_MODE  = 2
 
 mode = 0
+
+# Limit drawing the dependency graph to this depth. 0 means 'no limit'.
 max_depth = 0
 
 parser = argparse.ArgumentParser(description="Graph pacakges dependencies")
 parser.add_argument("--package", '-p', metavar="PACKAGE",
                     help="Graph the dependencies of PACKAGE")
-parser.add_argument("--depth", '-d', metavar="DEPTH",
-                    help="Limit the dependency graph to DEPTH levels")
+parser.add_argument("--depth", '-d', metavar="DEPTH", dest="depth", type=int, default=0,
+                    help="Limit the dependency graph to DEPTH levels; 0 means no limit.")
 parser.add_argument("--transitive", dest="transitive", action='store_true')
 parser.add_argument("--no-transitive", dest="transitive", action='store_false',
                     default=True,
@@ -52,8 +54,7 @@ else:
     mode = PKG_MODE
     rootpkg = args.package
 
-if args.depth is not None:
-    max_depth = int(args.depth)
+max_depth = args.depth
 
 transitive = args.transitive
 
Signature · 1 line
1.8.3.2
#7 lore raw

PATCH v3 5/8 graph-depends: document the max_depth variable

In reply to Yann E. MORIN

From: "Yann E. MORIN" <[email protected]>

Although unnecessary (we already have initialisation via the parser), initialise the max_depth option, and document it at the same time.

Cc Thomas Petazzoni <[email protected]>
Cc Maxime Hadjinlian <[email protected]>
Cc Samuel Martin <[email protected]>
---
 support/scripts/graph-depends | 3 +++
 1 file changed, 3 insertions(+)
support/scripts/graph-depends +3 -0
index c3dcbf1..dc6b98f 100755
@@ -37,6 +37,9 @@ mode = 0
 # Limit drawing the dependency graph to this depth. 0 means 'no limit'.
 max_depth = 0
 
+# Whether to draw the transitive dependencies
+transitive = True
+
 parser = argparse.ArgumentParser(description="Graph pacakges dependencies")
 parser.add_argument("--package", '-p', metavar="PACKAGE",
                     help="Graph the dependencies of PACKAGE")
Signature · 1 line
1.8.3.2
#8 lore raw

PATCH 5/8 graph-depends: document the max_depth variable

Dear Yann E. MORIN,

Quoted 4 lines · Yann E. MORIN

From: "Yann E. MORIN" <[email protected]>

Although unnecessary (we already have initialisation via the parser), initialise the max_depth option, and document it at the same time.

This description...

Quoted 14 lines
Cc Thomas Petazzoni <[email protected]>
Cc Maxime Hadjinlian <[email protected]>
Cc Samuel Martin <[email protected]>
---
 support/scripts/graph-depends | 3 +++
 1 file changed, 3 insertions(+)
support/scripts/graph-depends +0 -0
index c3dcbf1..dc6b98f 100755

support/scripts/graph-depends mode = 0 · line 42

Quoted 6 lines
support/scripts/graph-depends +3 -0
@@ -37,6 +37,9 @@ mode = 0
 # Limit drawing the dependency graph to this depth. 0 means 'no limit'.
 max_depth = 0
 
+# Whether to draw the transitive dependencies
+transitive = True
+

doesn't seem to match what the patch is doing. Am I missing something?

Thomas

Signature · 3 lines
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
#9 lore raw

PATCH v3 5/8 graph-depends: document the max_depth variable

Thomas, All,

On 2014-05-16 23:26 +0200, Thomas Petazzoni spake thusly:

Quoted 27 lines

Dear Yann E. MORIN,

Quoted 4 lines · Yann E. MORIN

From: "Yann E. MORIN" <[email protected]>

Although unnecessary (we already have initialisation via the parser), initialise the max_depth option, and document it at the same time.

This description...

Quoted 17 lines
Cc Thomas Petazzoni <[email protected]>
Cc Maxime Hadjinlian <[email protected]>
Cc Samuel Martin <[email protected]>
---
 support/scripts/graph-depends | 3 +++
 1 file changed, 3 insertions(+)
support/scripts/graph-depends +0 -0
index c3dcbf1..dc6b98f 100755
@@ -37,6 +37,9 @@ mode = 0
 # Limit drawing the dependency graph to this depth. 0 means 'no limit'.
 max_depth = 0
 
Quoted 5 lines

support/scripts/graph-depends mode = 0 · line 42

Quoted 3 lines
support/scripts/graph-depends +3 -0
+# Whether to draw the transitive dependencies
+transitive = True
+

doesn't seem to match what the patch is doing. Am I missing something?

You are missing nothing. I am missing some sleep, a new pair of eyes, and a brain. ;-)

The code is correct, and the commit log should be:
s/max_depth/transitive/

Thanks for spotting! :-)

I will respin after the dust has settled, to let other time to review.

Regards,
Yann E. MORIN.

Signature · 6 lines
.-----------------.--------------------.------------------.--------------------.
|  Yann E. MORIN  | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
| +33 662 376 056 | Software  Designer | \ / CAMPAIGN     |  ___               |
| +33 223 225 172 `------------.-------:  X  AGAINST      |  \e/  There is no  |
| http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL    |   v   conspiracy.  |
'------------------------------^-------^------------------^--------------------'
#10 lore raw

PATCH v3 6/8 graph-depends: rename the mode constants

In reply to Yann E. MORIN

From: "Yann E. MORIN" <[email protected]>

This is ugly, since Python does not have enum constructs, so by moving the 'type' of the constant ('MODE' here) to the beginning, we get an artificial 'namespace' for the constants.

Cc Thomas Petazzoni <[email protected]>
Cc Maxime Hadjinlian <[email protected]>
Cc Samuel Martin <[email protected]>
---
 support/scripts/graph-depends | 20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)
support/scripts/graph-depends +8 -12
index dc6b98f..86af779 100755
@@ -25,13 +25,9 @@ import sys
 import subprocess
 import argparse
 
-# 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
-
+# Modes of operation:
+MODE_FULL = 1   # draw full dependency graph for all selected packages
+MODE_PKG  = 2   # draw dependency graph for a given package
 mode = 0
 
 # Limit drawing the dependency graph to this depth. 0 means 'no limit'.
@@ -52,9 +48,9 @@ parser.add_argument("--no-transitive", dest="transitive", action='store_false',
 args = parser.parse_args()
 
 if args.package is None:
-    mode = FULL_MODE
+    mode = MODE_FULL
 else:
-    mode = PKG_MODE
+    mode = MODE_PKG
     rootpkg = args.package
 
 max_depth = args.depth
@@ -166,7 +162,7 @@ TARGET_EXCEPTIONS = [
 
 # In full mode, start with the result of get_targets() to get the main
 # targets and then use get_all_depends() for all targets
-if mode == FULL_MODE:
+if mode == MODE_FULL:
     targets = get_targets()
     dependencies = []
     allpkgs.append('all')
@@ -184,7 +180,7 @@ if mode == FULL_MODE:
 
 # In pkg mode, start directly with get_all_depends() on the requested
 # package
-elif mode == PKG_MODE:
+elif mode == MODE_PKG:
     dependencies = get_all_depends([rootpkg])
 
 # Make the dependencies a dictionnary { 'pkg':[dep1, dep2, ...] }
@@ -252,7 +248,7 @@ def print_attrs(pkg):
         print "all [color=lightblue,style=filled]"
         return
     print "%s [label = \"%s\"]" % (pkg_node_name(pkg), pkg)
-    if mode == PKG_MODE and pkg == rootpkg:
+    if mode == MODE_PKG and pkg == rootpkg:
         print "%s [color=lightblue,style=filled]" % pkg_node_name(rootpkg)
     else:
         print "%s [color=grey,style=filled]" % pkg_node_name(pkg)
Signature · 1 line
1.8.3.2
#11 lore raw

PATCH v3 7/8 graph-depends: add option to pass arbitrary dot options

In reply to Yann E. MORIN

From: "Yann E. MORIN" <[email protected]>

Kids nowaday seem to prefer a left-to-right drawing rather than the more conventional and historical top-down drawing.

Rather than multiply the number of environment variables, just add a single one where the user can pass arbitrary dot options, such as:

make BR2_GRAPH_DOT_OPTS=-Grankdir=LR graph-depends

Cc Thomas Petazzoni <[email protected]>
Cc Maxime Hadjinlian <[email protected]>
Cc Samuel Martin <[email protected]>
---
 Makefile               | 2 +-
 package/pkg-generic.mk | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
Makefile +1 -1
index d91231c..950f95f 100644
@@ -676,7 +676,7 @@ graph-depends:
 	@cd "$(CONFIG_DIR)"; \
 	$(TOPDIR)/support/scripts/graph-depends $(BR2_GRAPH_DEPS_OPTS) \
 	|tee $(O)/graphs/$(@).dot \
-	|dot -T$(BR_GRAPH_OUT) -o $(O)/graphs/$(@).$(BR_GRAPH_OUT)
+	|dot $(BR2_GRAPH_DOT_OPTS) -T$(BR_GRAPH_OUT) -o $(O)/graphs/$(@).$(BR_GRAPH_OUT)
 
 else # ifeq ($(BR2_HAVE_DOT_CONFIG),y)
 
package/pkg-generic.mk +1 -1
index 426d269..9251290 100644
@@ -514,7 +514,7 @@ $(1)-graph-depends:
 			@cd "$(CONFIG_DIR)"; \
 			$(TOPDIR)/support/scripts/graph-depends -p $(1) $(BR2_GRAPH_DEPS_OPTS) \
 			|tee $(O)/graphs/$$(@).dot \
-			|dot -T$(BR_GRAPH_OUT) -o $(O)/graphs/$$(@).$(BR_GRAPH_OUT)
+			|dot $(BR2_GRAPH_DOT_OPTS) -T$(BR_GRAPH_OUT) -o $(O)/graphs/$$(@).$(BR_GRAPH_OUT)
 
 $(1)-dirclean:		$$($(2)_TARGET_DIRCLEAN)
 
Signature · 1 line
1.8.3.2
#12 lore raw

PATCH v3 8/8 manual: document the new graph-depends options

In reply to Yann E. MORIN

From: "Yann E. MORIN" <[email protected]>

Cc Thomas Petazzoni <[email protected]>
Cc Maxime Hadjinlian <[email protected]>
Cc Samuel Martin <[email protected]>
---
 docs/manual/common-usage.txt | 5 +++++
 1 file changed, 5 insertions(+)
docs/manual/common-usage.txt +5 -0
index 772982a..9817915 100644
@@ -94,6 +94,8 @@ to +make+ or set in the environment:
   default), or +png+.
 * +BR2_GRAPH_DEPS_OPTS+ to pass extra options to the dependency graph; see
   xref:graph-depends[] for the accepted options
+* +BR2_GRAPH_DOT_OPTS+ is passed verbatim as options to the +dot+ utility to
+  draw the dependency graph.
 
 An example that uses config files located in the toplevel directory and
 in your $HOME:
@@ -204,6 +206,9 @@ The +graph-depends+ behaviour can be controlled by setting options in the
 * +--depth N+, +-d N+, to limit the dependency depth to +N+ levels. The
   default, +0+, means no limit.
 
+* +--transitive+, +--no-transitive+, to draw (or not) the transitive
+  dependencies. The default is to draw transitive dependencies.
+
 --------------------------------
 BR2_GRAPH_DEPS_OPTS='-d 3' make graph-depends
 --------------------------------
Signature · 1 line
1.8.3.2