Buildroot Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [Buildroot] [PATCH 1/2] support/scripts/graph-depends cleanup done_deps global
@ 2023-01-22 23:43 Steve Hay via buildroot
  2023-01-22 23:43 ` [Buildroot] [PATCH 2/2] support/scripts/graph-depends allow for forward and reverse depends on same graph Steve Hay via buildroot
  2023-01-23  7:01 ` [Buildroot] [PATCH 1/2] support/scripts/graph-depends cleanup done_deps global Yann E. MORIN
  0 siblings, 2 replies; 9+ messages in thread
From: Steve Hay via buildroot @ 2023-01-22 23:43 UTC (permalink / raw)
  To: buildroot; +Cc: Steve

From: Steve <me@stevenhay.com>

Signed-off-by: Steve Hay <me@stevenhay.com>
---
 support/scripts/graph-depends | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/support/scripts/graph-depends b/support/scripts/graph-depends
index a66fb28f41..3e3373950f 100755
--- a/support/scripts/graph-depends
+++ b/support/scripts/graph-depends
@@ -197,12 +197,11 @@ def print_attrs(outfile, pkg, pkg_type, pkg_version, depth, colors):
     outfile.write("%s [color=%s,style=filled]\n" % (name, color))
 
 
-done_deps = []
-
-
 # Print the dependency graph of a package
 def print_pkg_deps(outfile, dict_deps, dict_types, dict_versions, stop_list, exclude_list,
-                   arrow_dir, draw_graph, depth, max_depth, pkg, colors):
+                   arrow_dir, draw_graph, depth, max_depth, pkg, colors, done_deps=None):
+    if done_deps is None:
+        done_deps = []
     if pkg in done_deps:
         return
     done_deps.append(pkg)
@@ -234,7 +233,7 @@ def print_pkg_deps(outfile, dict_deps, dict_types, dict_versions, stop_list, exc
                 if draw_graph:
                     outfile.write("%s -> %s [dir=%s]\n" % (pkg_node_name(pkg), pkg_node_name(d), arrow_dir))
                 print_pkg_deps(outfile, dict_deps, dict_types, dict_versions, stop_list, exclude_list,
-                               arrow_dir, draw_graph, depth + 1, max_depth, d, colors)
+                               arrow_dir, draw_graph, depth + 1, max_depth, d, colors, done_deps)
 
 
 def parse_args():
-- 
2.30.2

_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Buildroot] [PATCH 2/2] support/scripts/graph-depends allow for forward and reverse depends on same graph
  2023-01-22 23:43 [Buildroot] [PATCH 1/2] support/scripts/graph-depends cleanup done_deps global Steve Hay via buildroot
@ 2023-01-22 23:43 ` Steve Hay via buildroot
  2023-01-23  7:20   ` Yann E. MORIN
  2023-01-23  7:01 ` [Buildroot] [PATCH 1/2] support/scripts/graph-depends cleanup done_deps global Yann E. MORIN
  1 sibling, 1 reply; 9+ messages in thread
From: Steve Hay via buildroot @ 2023-01-22 23:43 UTC (permalink / raw)
  To: buildroot; +Cc: Steve Hay

Signed-off-by: Steve Hay <me@stevenhay.com>
---
 support/scripts/graph-depends | 55 +++++++++++++++++++++++++----------
 1 file changed, 39 insertions(+), 16 deletions(-)

diff --git a/support/scripts/graph-depends b/support/scripts/graph-depends
index 3e3373950f..91aaf5d867 100755
--- a/support/scripts/graph-depends
+++ b/support/scripts/graph-depends
@@ -159,11 +159,11 @@ def check_circular_deps(deps):
 
 # This functions trims down the dependency list of all packages.
 # It applies in sequence all the dependency-elimination methods.
-def remove_extra_deps(deps, rootpkg, transitive, arrow_dir):
+def remove_extra_deps(deps, rootpkg, transitive, direct):
     # For the direct dependencies, find and eliminate mandatory
     # deps, and add them to the root package. Don't do it for a
     # reverse graph, because mandatory deps are only direct deps.
-    if arrow_dir == "forward":
+    if direct:
         for pkg in list(deps.keys()):
             if not pkg == rootpkg:
                 for d in get_mandatory_deps(pkg, deps):
@@ -197,14 +197,16 @@ def print_attrs(outfile, pkg, pkg_type, pkg_version, depth, colors):
     outfile.write("%s [color=%s,style=filled]\n" % (name, color))
 
 
+
 # Print the dependency graph of a package
 def print_pkg_deps(outfile, dict_deps, dict_types, dict_versions, stop_list, exclude_list,
-                   arrow_dir, draw_graph, depth, max_depth, pkg, colors, done_deps=None):
+                   direct, draw_graph, depth, max_depth, pkg, colors, done_deps=None):
     if done_deps is None:
         done_deps = []
     if pkg in done_deps:
         return
     done_deps.append(pkg)
+
     if draw_graph:
         print_attrs(outfile, pkg, dict_types[pkg], dict_versions[pkg], depth, colors)
     elif depth != 0:
@@ -231,9 +233,12 @@ def print_pkg_deps(outfile, dict_deps, dict_types, dict_versions, stop_list, exc
                     break
             if add:
                 if draw_graph:
-                    outfile.write("%s -> %s [dir=%s]\n" % (pkg_node_name(pkg), pkg_node_name(d), arrow_dir))
+                    if direct:
+                        outfile.write("%s -> %s [dir=%s]\n" % (pkg_node_name(pkg), pkg_node_name(d), "forward"))
+                    else:
+                        outfile.write("%s -> %s [dir=%s]\n" % (pkg_node_name(d), pkg_node_name(pkg), "forward"))
                 print_pkg_deps(outfile, dict_deps, dict_types, dict_versions, stop_list, exclude_list,
-                               arrow_dir, draw_graph, depth + 1, max_depth, d, colors, done_deps)
+                               direct, draw_graph, depth + 1, max_depth, d, colors, done_deps)
 
 
 def parse_args():
@@ -246,6 +251,8 @@ def parse_args():
                         help="Graph the dependencies of PACKAGE")
     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("--rdepth", metavar="RDEPTH", dest="rdepth", type=int, default=0,
+                        help="Limit the dependency graph to DEPTH levels; 0 means no limit.")
     parser.add_argument("--stop-on", "-s", metavar="PACKAGE", dest="stop_list", action="append",
                         help="Do not graph past this package (can be given multiple times)." +
                         " Can be a package name or a glob, " +
@@ -267,7 +274,7 @@ def parse_args():
                         help="Draw (do not draw) transitive dependencies")
     parser.add_argument("--direct", dest="direct", action='store_true', default=True,
                         help="Draw direct dependencies (the default)")
-    parser.add_argument("--reverse", dest="direct", action='store_false',
+    parser.add_argument("--reverse", dest="reverse", action='store_true', default=False,
                         help="Draw reverse dependencies")
     parser.add_argument("--quiet", '-q', dest="quiet", action='store_true',
                         help="Quiet")
@@ -330,21 +337,37 @@ def main():
         logging.error("Error: incorrect color list '%s'" % args.colors)
         sys.exit(1)
 
-    deps, rdeps, dict_types, dict_versions = brpkgutil.get_dependency_tree()
-    dict_deps = deps if args.direct else rdeps
-
-    check_circular_deps(dict_deps)
-    if check_only:
-        sys.exit(0)
-
-    dict_deps = remove_extra_deps(dict_deps, rootpkg, args.transitive, arrow_dir)
 
     # Start printing the graph data
     if draw_graph:
         outfile.write("digraph G {\n")
 
-    print_pkg_deps(outfile, dict_deps, dict_types, dict_versions, stop_list, exclude_list,
-                   arrow_dir, draw_graph, 0, args.depth, rootpkg, colors)
+
+    deps, rdeps, dict_types, dict_versions = brpkgutil.get_dependency_tree()
+
+    # forward
+    if args.direct:
+        dict_deps = deps
+        direct = True
+        #arrow_dir = "forward" # hack
+        check_circular_deps(dict_deps)
+        if check_only:
+            sys.exit(0)
+        dict_deps = remove_extra_deps(dict_deps, rootpkg, args.transitive, direct)
+        print_pkg_deps(outfile, dict_deps, dict_types, dict_versions, stop_list, exclude_list,
+                       direct, draw_graph, 0, args.depth, rootpkg, colors)
+
+    # reverse
+    if args.reverse:
+        dict_deps = rdeps
+        direct = False
+        #arrow_dir = "back" # hack
+        check_circular_deps(dict_deps)
+        if check_only:
+            sys.exit(0)
+        dict_deps = remove_extra_deps(dict_deps, rootpkg, args.transitive, direct)
+        print_pkg_deps(outfile, dict_deps, dict_types, dict_versions, stop_list, exclude_list,
+                       direct, draw_graph, 0, args.depth, rootpkg, colors)
 
     if draw_graph:
         outfile.write("}\n")
-- 
2.30.2

_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [Buildroot] [PATCH 1/2] support/scripts/graph-depends cleanup done_deps global
  2023-01-22 23:43 [Buildroot] [PATCH 1/2] support/scripts/graph-depends cleanup done_deps global Steve Hay via buildroot
  2023-01-22 23:43 ` [Buildroot] [PATCH 2/2] support/scripts/graph-depends allow for forward and reverse depends on same graph Steve Hay via buildroot
@ 2023-01-23  7:01 ` Yann E. MORIN
       [not found]   ` <f1b4fdfa-786f-2b09-5396-33ad4e79b64f@stevenhay.com>
  1 sibling, 1 reply; 9+ messages in thread
From: Yann E. MORIN @ 2023-01-23  7:01 UTC (permalink / raw)
  To: Steve Hay; +Cc: buildroot

Steve, All,

Thanks for this patch, here a quick review.

On 2023-01-23 00:43 +0100, Steve Hay via buildroot spake thusly:
> From: Steve <me@stevenhay.com>

Please use you full name as author (not just your first name).

Please provide a (potentially terse) explanation for the change.

> Signed-off-by: Steve Hay <me@stevenhay.com>
> ---
>  support/scripts/graph-depends | 9 ++++-----
>  1 file changed, 4 insertions(+), 5 deletions(-)
> 
> diff --git a/support/scripts/graph-depends b/support/scripts/graph-depends
> index a66fb28f41..3e3373950f 100755
> --- a/support/scripts/graph-depends
> +++ b/support/scripts/graph-depends
> @@ -197,12 +197,11 @@ def print_attrs(outfile, pkg, pkg_type, pkg_version, depth, colors):
>      outfile.write("%s [color=%s,style=filled]\n" % (name, color))
>  
>  
> -done_deps = []
> -
> -
>  # Print the dependency graph of a package
>  def print_pkg_deps(outfile, dict_deps, dict_types, dict_versions, stop_list, exclude_list,
> -                   arrow_dir, draw_graph, depth, max_depth, pkg, colors):
> +                   arrow_dir, draw_graph, depth, max_depth, pkg, colors, done_deps=None):

Make the default be the empty list:  done_deps=[]

> +    if done_deps is None:
> +        done_deps = []

... which allows to drop this conditional.

I was wondering how that could work, as the list is now a parameter,
but the list is not passed as a copy, it is passed as a "reference"
in python... So yes, it works (the .dot are the same before/after).

Regards,
Yann E. MORIN.

>      if pkg in done_deps:
>          return
>      done_deps.append(pkg)
> @@ -234,7 +233,7 @@ def print_pkg_deps(outfile, dict_deps, dict_types, dict_versions, stop_list, exc
>                  if draw_graph:
>                      outfile.write("%s -> %s [dir=%s]\n" % (pkg_node_name(pkg), pkg_node_name(d), arrow_dir))
>                  print_pkg_deps(outfile, dict_deps, dict_types, dict_versions, stop_list, exclude_list,
> -                               arrow_dir, draw_graph, depth + 1, max_depth, d, colors)
> +                               arrow_dir, draw_graph, depth + 1, max_depth, d, colors, done_deps)
>  
>  
>  def parse_args():
> -- 
> 2.30.2
> 
> _______________________________________________
> buildroot mailing list
> buildroot@buildroot.org
> https://lists.buildroot.org/mailman/listinfo/buildroot

-- 
.-----------------.--------------------.------------------.--------------------.
|  Yann E. MORIN  | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
| +33 662 376 056 | Software  Designer | \ / CAMPAIGN     |  ___               |
| +33 561 099 427 `------------.-------:  X  AGAINST      |  \e/  There is no  |
| http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL    |   v   conspiracy.  |
'------------------------------^-------^------------------^--------------------'
_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Buildroot] [PATCH 2/2] support/scripts/graph-depends allow for forward and reverse depends on same graph
  2023-01-22 23:43 ` [Buildroot] [PATCH 2/2] support/scripts/graph-depends allow for forward and reverse depends on same graph Steve Hay via buildroot
@ 2023-01-23  7:20   ` Yann E. MORIN
  2023-01-23 23:06     ` ʎɐH ǝʌǝʇS via buildroot
  0 siblings, 1 reply; 9+ messages in thread
From: Yann E. MORIN @ 2023-01-23  7:20 UTC (permalink / raw)
  To: Steve Hay; +Cc: buildroot

Steve, All,

On 2023-01-23 00:43 +0100, Steve Hay via buildroot spake thusly:
> Signed-off-by: Steve Hay <me@stevenhay.com>

Please write a commit log that explains the change (don't describe it.
explain it): as you could see from our discussion on IRC, the title of
your commit is not enough to understand what you are trying to achieve.

Maybe explain that it tries to represent both forward and backward
dependencies of a single package, with a little schema (here for pkg D):

    $ make pkg-d-graph-both-depends

    pkg A -.            .-> pkg E
            \          /
    pkg B ----> pkg D ----> pkg F
            /          \
    pkg C -'            '-> pkg G

Also, please insert this in the current package rules:

    $ make help
    [...]
    Package-specific:
      <pkg>                  - Build and install <pkg> and all its dependencies
      <pkg>-source           - Only download the source files for <pkg>
  [...]
      <pkg>-show-depends     - List packages on which <pkg> depends
      <pkg>-show-rdepends    - List packages which have <pkg> as a dependency
      <pkg>-show-recursive-depends
                             - Recursively list packages on which <pkg>
                               depends
      <pkg>-show-recursive-rdepends
                             - Recursively list packages which have <pkg> as
                               a dependency
      <pkg>-graph-depends    - Generate a graph of <pkg>'s dependencies
      <pkg>-graph-rdepends   - Generate a graph of <pkg>'s reverse dependencies
      <pkg>-graph-both-depends
                             - Generate a graph of both <pkg>'s forward and
                               reverse dependencies
      <pkg>-dirclean         - Remove <pkg> build directory
    [...]

> ---
>  support/scripts/graph-depends | 55 +++++++++++++++++++++++++----------
>  1 file changed, 39 insertions(+), 16 deletions(-)
> 
> diff --git a/support/scripts/graph-depends b/support/scripts/graph-depends
> index 3e3373950f..91aaf5d867 100755
> --- a/support/scripts/graph-depends
> +++ b/support/scripts/graph-depends
[--SNIP--]
> @@ -246,6 +251,8 @@ def parse_args():
>                          help="Graph the dependencies of PACKAGE")
>      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("--rdepth", metavar="RDEPTH", dest="rdepth", type=int, default=0,
> +                        help="Limit the dependency graph to DEPTH levels; 0 means no limit.")

Do we really need to have two different options for the direct and
reverse depths?

If so, then be sure to modify the <pkg>-graph-rdepends accordingly (in
package/pkg-generic).

[--SNIP--]
> @@ -330,21 +337,37 @@ def main():
>          logging.error("Error: incorrect color list '%s'" % args.colors)
>          sys.exit(1)
>  
> -    deps, rdeps, dict_types, dict_versions = brpkgutil.get_dependency_tree()
> -    dict_deps = deps if args.direct else rdeps
> -
> -    check_circular_deps(dict_deps)
> -    if check_only:
> -        sys.exit(0)
> -
> -    dict_deps = remove_extra_deps(dict_deps, rootpkg, args.transitive, arrow_dir)
>  
>      # Start printing the graph data
>      if draw_graph:
>          outfile.write("digraph G {\n")
>  
> -    print_pkg_deps(outfile, dict_deps, dict_types, dict_versions, stop_list, exclude_list,
> -                   arrow_dir, draw_graph, 0, args.depth, rootpkg, colors)
> +
> +    deps, rdeps, dict_types, dict_versions = brpkgutil.get_dependency_tree()
> +
> +    # forward
> +    if args.direct:
> +        dict_deps = deps
> +        direct = True
> +        #arrow_dir = "forward" # hack
> +        check_circular_deps(dict_deps)
> +        if check_only:
> +            sys.exit(0)

I am not very fond of this: if one were to call:

    $ graph-depends --direct --reverse --check-only

then one would expect to have both checks be run, but here only the
direct one will be.

I think we need to change check_circular_deps() to return False (no
circular dependencies) or True (circular dependencies) (or it can raise
an exception that we catch) and store that for later concumption.

    circ_deps = []

    if args.direct:
        if check_circular_deps(...):
            circ_deps.append('direct')
        if not args.checkonly:
            dict_deps = remove_extra_deps(...)
            print_pkg_deps(...)

    if args.reverse:
        if check_circular_deps(...):
            circ_deps.append('reverse')
        if not args.checkonly:
            dict_deps = remove_extra_deps(...)
            print_pkg_deps(...)

    if circ_deps:
        print(f"Bummer: circular {' and '.join(circ_deps)} dependencies detected")
        os.exit(1)

Something along those lines...

Regards,
Yann E. MORIN.

> +        dict_deps = remove_extra_deps(dict_deps, rootpkg, args.transitive, direct)
> +        print_pkg_deps(outfile, dict_deps, dict_types, dict_versions, stop_list, exclude_list,
> +                       direct, draw_graph, 0, args.depth, rootpkg, colors)
> +
> +    # reverse
> +    if args.reverse:
> +        dict_deps = rdeps
> +        direct = False
> +        #arrow_dir = "back" # hack
> +        check_circular_deps(dict_deps)
> +        if check_only:
> +            sys.exit(0)
> +        dict_deps = remove_extra_deps(dict_deps, rootpkg, args.transitive, direct)
> +        print_pkg_deps(outfile, dict_deps, dict_types, dict_versions, stop_list, exclude_list,
> +                       direct, draw_graph, 0, args.depth, rootpkg, colors)
>  
>      if draw_graph:
>          outfile.write("}\n")
> -- 
> 2.30.2
> 
> _______________________________________________
> buildroot mailing list
> buildroot@buildroot.org
> https://lists.buildroot.org/mailman/listinfo/buildroot

-- 
.-----------------.--------------------.------------------.--------------------.
|  Yann E. MORIN  | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
| +33 662 376 056 | Software  Designer | \ / CAMPAIGN     |  ___               |
| +33 561 099 427 `------------.-------:  X  AGAINST      |  \e/  There is no  |
| http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL    |   v   conspiracy.  |
'------------------------------^-------^------------------^--------------------'
_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Buildroot] [PATCH 1/2] support/scripts/graph-depends cleanup done_deps global
       [not found]   ` <f1b4fdfa-786f-2b09-5396-33ad4e79b64f@stevenhay.com>
@ 2023-01-23 20:15     ` ʎɐH ǝʌǝʇS via buildroot
  0 siblings, 0 replies; 9+ messages in thread
From: ʎɐH ǝʌǝʇS via buildroot @ 2023-01-23 20:15 UTC (permalink / raw)
  To: buildroot


Yann, All,

Thank you.

> On 1/23/23 2:01 AM, Yann E. MORIN wrote:
>> On 2023-01-23 00:43 +0100, Steve Hay via buildroot spake thusly:
>>> From: Steve <me@stevenhay.com>
>> Please use you full name as author (not just your first name).
>>
>> Please provide a (potentially terse) explanation for the change. 
I don't know why the git client did that with my first name. I will try 
to fix it.
>> Make the default be the empty list: done_deps=[] 

I don't think this works because it essentially moves the global list 
into the Python interpreter:

https://docs.python.org/3/faq/programming.html#why-are-default-values-shared-between-objects 


_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Buildroot] [PATCH 2/2] support/scripts/graph-depends allow for forward and reverse depends on same graph
  2023-01-23  7:20   ` Yann E. MORIN
@ 2023-01-23 23:06     ` ʎɐH ǝʌǝʇS via buildroot
  0 siblings, 0 replies; 9+ messages in thread
From: ʎɐH ǝʌǝʇS via buildroot @ 2023-01-23 23:06 UTC (permalink / raw)
  To: buildroot

Yann, All,

On 1/23/23 2:20 AM, Yann E. MORIN wrote:
> Do we really need to have two different options for the direct and
> reverse depths?
>
> If so, then be sure to modify the <pkg>-graph-rdepends accordingly (in
> package/pkg-generic).
I think it is nice to have the "control knob" available for both, but 
the current API to this script uses default values of 0 (no limit) in 
all cases--so no change to <pkg>-graph-rdepends is needed. I've added 
the ability to specify depth to the makefile.
> I am not very fond of this: if one were to call:
>      $ graph-depends --direct --reverse --check-only
>
> then one would expect to have both checks be run, but here only the
> direct one will be.
>
> I think we need to change check_circular_deps() to return False (no
> circular dependencies) or True (circular dependencies) (or it can raise
> an exception that we catch) and store that for later concumption.
I agree that it should check both and have updated the script so that it 
does, but I'd rather the enhancements you're talking about be handled 
with a separate patch.

Revised patch forthcoming.

Steve

_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Buildroot] [PATCH 2/2] support/scripts/graph-depends allow for forward and reverse depends on same graph
@ 2023-01-23 23:12 Steve Hay via buildroot
  2023-02-06  5:27 ` ʎɐH ǝʌǝʇS via buildroot
  2024-07-14 19:33 ` Arnout Vandecappelle via buildroot
  0 siblings, 2 replies; 9+ messages in thread
From: Steve Hay via buildroot @ 2023-01-23 23:12 UTC (permalink / raw)
  To: buildroot; +Cc: Thomas Petazzoni, Steve Hay

The current implementation of buildroot depe dependency graphing
either does forward- or reverse-dependency traversal.

This patch enables buildroot to graph forward and reverse dependencies on the
graph for the same package: (Diagram Credit: Yann E. MORRIN)

    $ make pkg-d-graph-both-depends

    pkg A -.            .-> pkg E
            \          /
    pkg B ----> pkg D ----> pkg F
            /          \
    pkg C -'            '-> pkg G

In the above example a single graph shows pkg {A,B,C} are needed
by pkg D, and pkg D is a dependency of pkg {E,F,G}.

The variables DEPTH and RDEPTH can be passed into the graphing functions to
specify the maximum depths of direct and reverse dependencies to control graph
size.

Makefile documentation is also updated.

Signed-off-by: Steve Hay <me@stevenhay.com>

---
Changes v1 -> v2:
  - Enhanced patch description. (Yann)
  - Added Makefile documentation. (Yann)
  - Completed the implementation of graph-both-depends. (Yann)
  - Added ability to control depth of the generated graph.
  - Ensured both forward and reverse dependencies are checked for --check-only case. (Yann)
---
 Makefile                      |  7 ++++
 package/pkg-generic.mk        |  7 +++-
 support/scripts/graph-depends | 69 ++++++++++++++++++++++-------------
 3 files changed, 55 insertions(+), 28 deletions(-)

diff --git a/Makefile b/Makefile
index 8517d563d5..e47544fd42 100644
--- a/Makefile
+++ b/Makefile
@@ -1163,7 +1163,14 @@ help:
 	@echo '  <pkg>-show-recursive-rdepends'
 	@echo '                         - Recursively list packages which have <pkg> as a dependency'
 	@echo '  <pkg>-graph-depends    - Generate a graph of <pkg>'\''s dependencies'
+	@echo '                             DEPTH, if set on the command line, is used to specify maximum'
+	@echo '                               depth to graph dependencies.'
 	@echo '  <pkg>-graph-rdepends   - Generate a graph of <pkg>'\''s reverse dependencies'
+	@echo '                             RDEPTH, if set on the command line, is used to specify maximum'
+	@echo '                               depth to graph reverse dependencies.'
+	@echo '  <pkg>-graph-both-depends'
+	@echo '                         - Generate a graph of both <pkg>'\''s forward and'
+	@echo '                           reverse dependencies. DEPTH and RDEPTH work as described above.'
 	@echo '  <pkg>-dirclean         - Remove <pkg> build directory'
 	@echo '  <pkg>-reconfigure      - Restart the build from the configure step'
 	@echo '  <pkg>-rebuild          - Restart the build from the build step'
diff --git a/package/pkg-generic.mk b/package/pkg-generic.mk
index 2f8ba39edf..6ddb304a12 100644
--- a/package/pkg-generic.mk
+++ b/package/pkg-generic.mk
@@ -1031,10 +1031,13 @@ $(1)-show-info:
 	$$(info $$(call clean-json,{ $$(call json-info,$(2)) }))
 
 $(1)-graph-depends: graph-depends-requirements
-	$(call pkg-graph-depends,$(1),--direct)
+	$(call pkg-graph-depends,$(1),--direct --depth $(or $(DEPTH),0))
 
 $(1)-graph-rdepends: graph-depends-requirements
-	$(call pkg-graph-depends,$(1),--reverse)
+	$(call pkg-graph-depends,$(1),--reverse --rdepth $(or $(RDEPTH),0))
+
+$(1)-graph-both-depends: graph-depends-requirements
+	$(call pkg-graph-depends,$(1),--direct --reverse --depth $(or $(DEPTH),0) --rdepth $(or $(RDEPTH),0))
 
 $(1)-all-source:	$(1)-source
 $(1)-all-source:	$$(foreach p,$$($(2)_FINAL_ALL_DEPENDENCIES),$$(p)-all-source)
diff --git a/support/scripts/graph-depends b/support/scripts/graph-depends
index 3e3373950f..0285afb46d 100755
--- a/support/scripts/graph-depends
+++ b/support/scripts/graph-depends
@@ -159,11 +159,11 @@ def check_circular_deps(deps):
 
 # This functions trims down the dependency list of all packages.
 # It applies in sequence all the dependency-elimination methods.
-def remove_extra_deps(deps, rootpkg, transitive, arrow_dir):
+def remove_extra_deps(deps, rootpkg, transitive, direct):
     # For the direct dependencies, find and eliminate mandatory
     # deps, and add them to the root package. Don't do it for a
     # reverse graph, because mandatory deps are only direct deps.
-    if arrow_dir == "forward":
+    if direct:
         for pkg in list(deps.keys()):
             if not pkg == rootpkg:
                 for d in get_mandatory_deps(pkg, deps):
@@ -197,14 +197,16 @@ def print_attrs(outfile, pkg, pkg_type, pkg_version, depth, colors):
     outfile.write("%s [color=%s,style=filled]\n" % (name, color))
 
 
+
 # Print the dependency graph of a package
 def print_pkg_deps(outfile, dict_deps, dict_types, dict_versions, stop_list, exclude_list,
-                   arrow_dir, draw_graph, depth, max_depth, pkg, colors, done_deps=None):
+                   direct, draw_graph, depth, max_depth, pkg, colors, done_deps=None):
     if done_deps is None:
         done_deps = []
     if pkg in done_deps:
         return
     done_deps.append(pkg)
+
     if draw_graph:
         print_attrs(outfile, pkg, dict_types[pkg], dict_versions[pkg], depth, colors)
     elif depth != 0:
@@ -231,9 +233,12 @@ def print_pkg_deps(outfile, dict_deps, dict_types, dict_versions, stop_list, exc
                     break
             if add:
                 if draw_graph:
-                    outfile.write("%s -> %s [dir=%s]\n" % (pkg_node_name(pkg), pkg_node_name(d), arrow_dir))
+                    if direct:
+                        outfile.write("%s -> %s [dir=%s]\n" % (pkg_node_name(pkg), pkg_node_name(d), "forward"))
+                    else:
+                        outfile.write("%s -> %s [dir=%s]\n" % (pkg_node_name(d), pkg_node_name(pkg), "forward"))
                 print_pkg_deps(outfile, dict_deps, dict_types, dict_versions, stop_list, exclude_list,
-                               arrow_dir, draw_graph, depth + 1, max_depth, d, colors, done_deps)
+                               direct, draw_graph, depth + 1, max_depth, d, colors, done_deps)
 
 
 def parse_args():
@@ -246,6 +251,8 @@ def parse_args():
                         help="Graph the dependencies of PACKAGE")
     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("--rdepth", metavar="RDEPTH", dest="rdepth", type=int, default=0,
+                        help="Limit the dependency graph to DEPTH levels; 0 means no limit.")
     parser.add_argument("--stop-on", "-s", metavar="PACKAGE", dest="stop_list", action="append",
                         help="Do not graph past this package (can be given multiple times)." +
                         " Can be a package name or a glob, " +
@@ -265,9 +272,9 @@ def parse_args():
                         default=False)
     parser.add_argument("--no-transitive", dest="transitive", action='store_false',
                         help="Draw (do not draw) transitive dependencies")
-    parser.add_argument("--direct", dest="direct", action='store_true', default=True,
+    parser.add_argument("--direct", dest="direct", action='store_true', default=False,
                         help="Draw direct dependencies (the default)")
-    parser.add_argument("--reverse", dest="direct", action='store_false',
+    parser.add_argument("--reverse", dest="reverse", action='store_true', default=False,
                         help="Draw reverse dependencies")
     parser.add_argument("--quiet", '-q', dest="quiet", action='store_true',
                         help="Quiet")
@@ -292,6 +299,9 @@ def main():
             sys.exit(1)
         outfile = open(args.outfile, "w")
 
+    if not args.direct and not args.reverse: # select default direct if none is specified.
+        args.direct = True
+ 
     if args.package is None:
         mode = MODE_FULL
         rootpkg = 'all'
@@ -312,13 +322,9 @@ def main():
     if args.exclude_mandatory:
         exclude_list += MANDATORY_DEPS
 
-    if args.direct:
-        arrow_dir = "forward"
-    else:
-        if mode == MODE_FULL:
-            logging.error("--reverse needs a package")
-            sys.exit(1)
-        arrow_dir = "back"
+    if args.reverse and mode == MODE_FULL:
+        logging.error("--reverse needs a package")
+        sys.exit(1)
 
     draw_graph = not args.flat_list
 
@@ -330,23 +336,34 @@ def main():
         logging.error("Error: incorrect color list '%s'" % args.colors)
         sys.exit(1)
 
-    deps, rdeps, dict_types, dict_versions = brpkgutil.get_dependency_tree()
-    dict_deps = deps if args.direct else rdeps
-
-    check_circular_deps(dict_deps)
-    if check_only:
-        sys.exit(0)
-
-    dict_deps = remove_extra_deps(dict_deps, rootpkg, args.transitive, arrow_dir)
 
     # Start printing the graph data
-    if draw_graph:
+    if not check_only and draw_graph:
         outfile.write("digraph G {\n")
 
-    print_pkg_deps(outfile, dict_deps, dict_types, dict_versions, stop_list, exclude_list,
-                   arrow_dir, draw_graph, 0, args.depth, rootpkg, colors)
+    deps, rdeps, dict_types, dict_versions = brpkgutil.get_dependency_tree()
 
-    if draw_graph:
+    # forward
+    if args.direct:
+        dict_deps = deps
+        direct = True
+        check_circular_deps(dict_deps)
+        if not check_only:
+            dict_deps = remove_extra_deps(dict_deps, rootpkg, args.transitive, direct)
+            print_pkg_deps(outfile, dict_deps, dict_types, dict_versions, stop_list, exclude_list,
+                           direct, draw_graph, 0, args.depth, rootpkg, colors)
+
+    # reverse
+    if args.reverse:
+        dict_deps = rdeps
+        direct = False
+        check_circular_deps(dict_deps)
+        if not check_only:
+            dict_deps = remove_extra_deps(dict_deps, rootpkg, args.transitive, direct)
+            print_pkg_deps(outfile, dict_deps, dict_types, dict_versions, stop_list, exclude_list,
+                           direct, draw_graph, 0, args.rdepth, rootpkg, colors)
+
+    if not check_only and draw_graph:
         outfile.write("}\n")
     else:
         outfile.write("\n")
-- 
2.30.2

_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [Buildroot] [PATCH 2/2] support/scripts/graph-depends allow for forward and reverse depends on same graph
  2023-01-23 23:12 [Buildroot] [PATCH 2/2] support/scripts/graph-depends allow for forward and reverse depends on same graph Steve Hay via buildroot
@ 2023-02-06  5:27 ` ʎɐH ǝʌǝʇS via buildroot
  2024-07-14 19:33 ` Arnout Vandecappelle via buildroot
  1 sibling, 0 replies; 9+ messages in thread
From: ʎɐH ǝʌǝʇS via buildroot @ 2023-02-06  5:27 UTC (permalink / raw)
  To: buildroot; +Cc: Yann E. MORIN, thomas.petazzoni

All,

Wanted to bump this email thread to see what we think of the second part 
(the meat) of this patch.

On 1/23/23 6:12 PM, Steve Hay wrote:
> The current implementation of buildroot depe dependency graphing
> either does forward- or reverse-dependency traversal.
>
> This patch enables buildroot to graph forward and reverse dependencies on the
> graph for the same package: (Diagram Credit: Yann E. MORRIN)
>
>      $ make pkg-d-graph-both-depends
>
>      pkg A -.            .-> pkg E
>              \          /
>      pkg B ----> pkg D ----> pkg F
>              /          \
>      pkg C -'            '-> pkg G
>
> In the above example a single graph shows pkg {A,B,C} are needed
> by pkg D, and pkg D is a dependency of pkg {E,F,G}.
>
> The variables DEPTH and RDEPTH can be passed into the graphing functions to
> specify the maximum depths of direct and reverse dependencies to control graph
> size.
>
> Makefile documentation is also updated.
>
> Signed-off-by: Steve Hay <me@stevenhay.com>
>
> ---
> Changes v1 -> v2:
>    - Enhanced patch description. (Yann)
>    - Added Makefile documentation. (Yann)
>    - Completed the implementation of graph-both-depends. (Yann)
>    - Added ability to control depth of the generated graph.
>    - Ensured both forward and reverse dependencies are checked for --check-only case. (Yann)
> ---
>   Makefile                      |  7 ++++
>   package/pkg-generic.mk        |  7 +++-
>   support/scripts/graph-depends | 69 ++++++++++++++++++++++-------------
>   3 files changed, 55 insertions(+), 28 deletions(-)
>
> diff --git a/Makefile b/Makefile
> index 8517d563d5..e47544fd42 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -1163,7 +1163,14 @@ help:
>   	@echo '  <pkg>-show-recursive-rdepends'
>   	@echo '                         - Recursively list packages which have <pkg> as a dependency'
>   	@echo '  <pkg>-graph-depends    - Generate a graph of <pkg>'\''s dependencies'
> +	@echo '                             DEPTH, if set on the command line, is used to specify maximum'
> +	@echo '                               depth to graph dependencies.'
>   	@echo '  <pkg>-graph-rdepends   - Generate a graph of <pkg>'\''s reverse dependencies'
> +	@echo '                             RDEPTH, if set on the command line, is used to specify maximum'
> +	@echo '                               depth to graph reverse dependencies.'
> +	@echo '  <pkg>-graph-both-depends'
> +	@echo '                         - Generate a graph of both <pkg>'\''s forward and'
> +	@echo '                           reverse dependencies. DEPTH and RDEPTH work as described above.'
>   	@echo '  <pkg>-dirclean         - Remove <pkg> build directory'
>   	@echo '  <pkg>-reconfigure      - Restart the build from the configure step'
>   	@echo '  <pkg>-rebuild          - Restart the build from the build step'
> diff --git a/package/pkg-generic.mk b/package/pkg-generic.mk
> index 2f8ba39edf..6ddb304a12 100644
> --- a/package/pkg-generic.mk
> +++ b/package/pkg-generic.mk
> @@ -1031,10 +1031,13 @@ $(1)-show-info:
>   	$$(info $$(call clean-json,{ $$(call json-info,$(2)) }))
>   
>   $(1)-graph-depends: graph-depends-requirements
> -	$(call pkg-graph-depends,$(1),--direct)
> +	$(call pkg-graph-depends,$(1),--direct --depth $(or $(DEPTH),0))
>   
>   $(1)-graph-rdepends: graph-depends-requirements
> -	$(call pkg-graph-depends,$(1),--reverse)
> +	$(call pkg-graph-depends,$(1),--reverse --rdepth $(or $(RDEPTH),0))
> +
> +$(1)-graph-both-depends: graph-depends-requirements
> +	$(call pkg-graph-depends,$(1),--direct --reverse --depth $(or $(DEPTH),0) --rdepth $(or $(RDEPTH),0))
>   
>   $(1)-all-source:	$(1)-source
>   $(1)-all-source:	$$(foreach p,$$($(2)_FINAL_ALL_DEPENDENCIES),$$(p)-all-source)
> diff --git a/support/scripts/graph-depends b/support/scripts/graph-depends
> index 3e3373950f..0285afb46d 100755
> --- a/support/scripts/graph-depends
> +++ b/support/scripts/graph-depends
> @@ -159,11 +159,11 @@ def check_circular_deps(deps):
>   
>   # This functions trims down the dependency list of all packages.
>   # It applies in sequence all the dependency-elimination methods.
> -def remove_extra_deps(deps, rootpkg, transitive, arrow_dir):
> +def remove_extra_deps(deps, rootpkg, transitive, direct):
>       # For the direct dependencies, find and eliminate mandatory
>       # deps, and add them to the root package. Don't do it for a
>       # reverse graph, because mandatory deps are only direct deps.
> -    if arrow_dir == "forward":
> +    if direct:
>           for pkg in list(deps.keys()):
>               if not pkg == rootpkg:
>                   for d in get_mandatory_deps(pkg, deps):
> @@ -197,14 +197,16 @@ def print_attrs(outfile, pkg, pkg_type, pkg_version, depth, colors):
>       outfile.write("%s [color=%s,style=filled]\n" % (name, color))
>   
>   
> +
>   # Print the dependency graph of a package
>   def print_pkg_deps(outfile, dict_deps, dict_types, dict_versions, stop_list, exclude_list,
> -                   arrow_dir, draw_graph, depth, max_depth, pkg, colors, done_deps=None):
> +                   direct, draw_graph, depth, max_depth, pkg, colors, done_deps=None):
>       if done_deps is None:
>           done_deps = []
>       if pkg in done_deps:
>           return
>       done_deps.append(pkg)
> +
>       if draw_graph:
>           print_attrs(outfile, pkg, dict_types[pkg], dict_versions[pkg], depth, colors)
>       elif depth != 0:
> @@ -231,9 +233,12 @@ def print_pkg_deps(outfile, dict_deps, dict_types, dict_versions, stop_list, exc
>                       break
>               if add:
>                   if draw_graph:
> -                    outfile.write("%s -> %s [dir=%s]\n" % (pkg_node_name(pkg), pkg_node_name(d), arrow_dir))
> +                    if direct:
> +                        outfile.write("%s -> %s [dir=%s]\n" % (pkg_node_name(pkg), pkg_node_name(d), "forward"))
> +                    else:
> +                        outfile.write("%s -> %s [dir=%s]\n" % (pkg_node_name(d), pkg_node_name(pkg), "forward"))
>                   print_pkg_deps(outfile, dict_deps, dict_types, dict_versions, stop_list, exclude_list,
> -                               arrow_dir, draw_graph, depth + 1, max_depth, d, colors, done_deps)
> +                               direct, draw_graph, depth + 1, max_depth, d, colors, done_deps)
>   
>   
>   def parse_args():
> @@ -246,6 +251,8 @@ def parse_args():
>                           help="Graph the dependencies of PACKAGE")
>       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("--rdepth", metavar="RDEPTH", dest="rdepth", type=int, default=0,
> +                        help="Limit the dependency graph to DEPTH levels; 0 means no limit.")
>       parser.add_argument("--stop-on", "-s", metavar="PACKAGE", dest="stop_list", action="append",
>                           help="Do not graph past this package (can be given multiple times)." +
>                           " Can be a package name or a glob, " +
> @@ -265,9 +272,9 @@ def parse_args():
>                           default=False)
>       parser.add_argument("--no-transitive", dest="transitive", action='store_false',
>                           help="Draw (do not draw) transitive dependencies")
> -    parser.add_argument("--direct", dest="direct", action='store_true', default=True,
> +    parser.add_argument("--direct", dest="direct", action='store_true', default=False,
>                           help="Draw direct dependencies (the default)")
> -    parser.add_argument("--reverse", dest="direct", action='store_false',
> +    parser.add_argument("--reverse", dest="reverse", action='store_true', default=False,
>                           help="Draw reverse dependencies")
>       parser.add_argument("--quiet", '-q', dest="quiet", action='store_true',
>                           help="Quiet")
> @@ -292,6 +299,9 @@ def main():
>               sys.exit(1)
>           outfile = open(args.outfile, "w")
>   
> +    if not args.direct and not args.reverse: # select default direct if none is specified.
> +        args.direct = True
> +
>       if args.package is None:
>           mode = MODE_FULL
>           rootpkg = 'all'
> @@ -312,13 +322,9 @@ def main():
>       if args.exclude_mandatory:
>           exclude_list += MANDATORY_DEPS
>   
> -    if args.direct:
> -        arrow_dir = "forward"
> -    else:
> -        if mode == MODE_FULL:
> -            logging.error("--reverse needs a package")
> -            sys.exit(1)
> -        arrow_dir = "back"
> +    if args.reverse and mode == MODE_FULL:
> +        logging.error("--reverse needs a package")
> +        sys.exit(1)
>   
>       draw_graph = not args.flat_list
>   
> @@ -330,23 +336,34 @@ def main():
>           logging.error("Error: incorrect color list '%s'" % args.colors)
>           sys.exit(1)
>   
> -    deps, rdeps, dict_types, dict_versions = brpkgutil.get_dependency_tree()
> -    dict_deps = deps if args.direct else rdeps
> -
> -    check_circular_deps(dict_deps)
> -    if check_only:
> -        sys.exit(0)
> -
> -    dict_deps = remove_extra_deps(dict_deps, rootpkg, args.transitive, arrow_dir)
>   
>       # Start printing the graph data
> -    if draw_graph:
> +    if not check_only and draw_graph:
>           outfile.write("digraph G {\n")
>   
> -    print_pkg_deps(outfile, dict_deps, dict_types, dict_versions, stop_list, exclude_list,
> -                   arrow_dir, draw_graph, 0, args.depth, rootpkg, colors)
> +    deps, rdeps, dict_types, dict_versions = brpkgutil.get_dependency_tree()
>   
> -    if draw_graph:
> +    # forward
> +    if args.direct:
> +        dict_deps = deps
> +        direct = True
> +        check_circular_deps(dict_deps)
> +        if not check_only:
> +            dict_deps = remove_extra_deps(dict_deps, rootpkg, args.transitive, direct)
> +            print_pkg_deps(outfile, dict_deps, dict_types, dict_versions, stop_list, exclude_list,
> +                           direct, draw_graph, 0, args.depth, rootpkg, colors)
> +
> +    # reverse
> +    if args.reverse:
> +        dict_deps = rdeps
> +        direct = False
> +        check_circular_deps(dict_deps)
> +        if not check_only:
> +            dict_deps = remove_extra_deps(dict_deps, rootpkg, args.transitive, direct)
> +            print_pkg_deps(outfile, dict_deps, dict_types, dict_versions, stop_list, exclude_list,
> +                           direct, draw_graph, 0, args.rdepth, rootpkg, colors)
> +
> +    if not check_only and draw_graph:
>           outfile.write("}\n")
>       else:
>           outfile.write("\n")
_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Buildroot] [PATCH 2/2] support/scripts/graph-depends allow for forward and reverse depends on same graph
  2023-01-23 23:12 [Buildroot] [PATCH 2/2] support/scripts/graph-depends allow for forward and reverse depends on same graph Steve Hay via buildroot
  2023-02-06  5:27 ` ʎɐH ǝʌǝʇS via buildroot
@ 2024-07-14 19:33 ` Arnout Vandecappelle via buildroot
  1 sibling, 0 replies; 9+ messages in thread
From: Arnout Vandecappelle via buildroot @ 2024-07-14 19:33 UTC (permalink / raw)
  To: Steve Hay, buildroot; +Cc: Thomas Petazzoni

  Hi ǝʌǝʇS,

On 24/01/2023 00:12, Steve Hay via buildroot wrote:
> The current implementation of buildroot depe dependency graphing
> either does forward- or reverse-dependency traversal.
> 
> This patch enables buildroot to graph forward and reverse dependencies on the
> graph for the same package: (Diagram Credit: Yann E. MORRIN)
> 
>      $ make pkg-d-graph-both-depends
> 
>      pkg A -.            .-> pkg E
>              \          /
>      pkg B ----> pkg D ----> pkg F
>              /          \
>      pkg C -'            '-> pkg G
> 
> In the above example a single graph shows pkg {A,B,C} are needed
> by pkg D, and pkg D is a dependency of pkg {E,F,G}.
> 
> The variables DEPTH and RDEPTH can be passed into the graphing functions to
> specify the maximum depths of direct and reverse dependencies to control graph
> size.
> 
> Makefile documentation is also updated.
> 
> Signed-off-by: Steve Hay <me@stevenhay.com>

  I _finally_ applied both to master. I did make the following changes to this 
patch:
      - remove DEPTH and RDEPTH, their functionality is already covered by
        BR2_GRAPH_DEPS_OPTS;
      - remove --rdepth, it was felt to not add sufficient added value;
      - add the new target to the manual;
      - fix flake8 errors.

  Regards,
  Arnout

> 
> ---
> Changes v1 -> v2:
>    - Enhanced patch description. (Yann)
>    - Added Makefile documentation. (Yann)
>    - Completed the implementation of graph-both-depends. (Yann)
>    - Added ability to control depth of the generated graph.
>    - Ensured both forward and reverse dependencies are checked for --check-only case. (Yann)
> ---
>   Makefile                      |  7 ++++
>   package/pkg-generic.mk        |  7 +++-
>   support/scripts/graph-depends | 69 ++++++++++++++++++++++-------------
>   3 files changed, 55 insertions(+), 28 deletions(-)
> 
> diff --git a/Makefile b/Makefile
> index 8517d563d5..e47544fd42 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -1163,7 +1163,14 @@ help:
>   	@echo '  <pkg>-show-recursive-rdepends'
>   	@echo '                         - Recursively list packages which have <pkg> as a dependency'
>   	@echo '  <pkg>-graph-depends    - Generate a graph of <pkg>'\''s dependencies'
> +	@echo '                             DEPTH, if set on the command line, is used to specify maximum'
> +	@echo '                               depth to graph dependencies.'
>   	@echo '  <pkg>-graph-rdepends   - Generate a graph of <pkg>'\''s reverse dependencies'
> +	@echo '                             RDEPTH, if set on the command line, is used to specify maximum'
> +	@echo '                               depth to graph reverse dependencies.'
> +	@echo '  <pkg>-graph-both-depends'
> +	@echo '                         - Generate a graph of both <pkg>'\''s forward and'
> +	@echo '                           reverse dependencies. DEPTH and RDEPTH work as described above.'
>   	@echo '  <pkg>-dirclean         - Remove <pkg> build directory'
>   	@echo '  <pkg>-reconfigure      - Restart the build from the configure step'
>   	@echo '  <pkg>-rebuild          - Restart the build from the build step'
> diff --git a/package/pkg-generic.mk b/package/pkg-generic.mk
> index 2f8ba39edf..6ddb304a12 100644
> --- a/package/pkg-generic.mk
> +++ b/package/pkg-generic.mk
> @@ -1031,10 +1031,13 @@ $(1)-show-info:
>   	$$(info $$(call clean-json,{ $$(call json-info,$(2)) }))
>   
>   $(1)-graph-depends: graph-depends-requirements
> -	$(call pkg-graph-depends,$(1),--direct)
> +	$(call pkg-graph-depends,$(1),--direct --depth $(or $(DEPTH),0))
>   
>   $(1)-graph-rdepends: graph-depends-requirements
> -	$(call pkg-graph-depends,$(1),--reverse)
> +	$(call pkg-graph-depends,$(1),--reverse --rdepth $(or $(RDEPTH),0))
> +
> +$(1)-graph-both-depends: graph-depends-requirements
> +	$(call pkg-graph-depends,$(1),--direct --reverse --depth $(or $(DEPTH),0) --rdepth $(or $(RDEPTH),0))
>   
>   $(1)-all-source:	$(1)-source
>   $(1)-all-source:	$$(foreach p,$$($(2)_FINAL_ALL_DEPENDENCIES),$$(p)-all-source)
> diff --git a/support/scripts/graph-depends b/support/scripts/graph-depends
> index 3e3373950f..0285afb46d 100755
> --- a/support/scripts/graph-depends
> +++ b/support/scripts/graph-depends
> @@ -159,11 +159,11 @@ def check_circular_deps(deps):
>   
>   # This functions trims down the dependency list of all packages.
>   # It applies in sequence all the dependency-elimination methods.
> -def remove_extra_deps(deps, rootpkg, transitive, arrow_dir):
> +def remove_extra_deps(deps, rootpkg, transitive, direct):
>       # For the direct dependencies, find and eliminate mandatory
>       # deps, and add them to the root package. Don't do it for a
>       # reverse graph, because mandatory deps are only direct deps.
> -    if arrow_dir == "forward":
> +    if direct:
>           for pkg in list(deps.keys()):
>               if not pkg == rootpkg:
>                   for d in get_mandatory_deps(pkg, deps):
> @@ -197,14 +197,16 @@ def print_attrs(outfile, pkg, pkg_type, pkg_version, depth, colors):
>       outfile.write("%s [color=%s,style=filled]\n" % (name, color))
>   
>   
> +
>   # Print the dependency graph of a package
>   def print_pkg_deps(outfile, dict_deps, dict_types, dict_versions, stop_list, exclude_list,
> -                   arrow_dir, draw_graph, depth, max_depth, pkg, colors, done_deps=None):
> +                   direct, draw_graph, depth, max_depth, pkg, colors, done_deps=None):
>       if done_deps is None:
>           done_deps = []
>       if pkg in done_deps:
>           return
>       done_deps.append(pkg)
> +
>       if draw_graph:
>           print_attrs(outfile, pkg, dict_types[pkg], dict_versions[pkg], depth, colors)
>       elif depth != 0:
> @@ -231,9 +233,12 @@ def print_pkg_deps(outfile, dict_deps, dict_types, dict_versions, stop_list, exc
>                       break
>               if add:
>                   if draw_graph:
> -                    outfile.write("%s -> %s [dir=%s]\n" % (pkg_node_name(pkg), pkg_node_name(d), arrow_dir))
> +                    if direct:
> +                        outfile.write("%s -> %s [dir=%s]\n" % (pkg_node_name(pkg), pkg_node_name(d), "forward"))
> +                    else:
> +                        outfile.write("%s -> %s [dir=%s]\n" % (pkg_node_name(d), pkg_node_name(pkg), "forward"))
>                   print_pkg_deps(outfile, dict_deps, dict_types, dict_versions, stop_list, exclude_list,
> -                               arrow_dir, draw_graph, depth + 1, max_depth, d, colors, done_deps)
> +                               direct, draw_graph, depth + 1, max_depth, d, colors, done_deps)
>   
>   
>   def parse_args():
> @@ -246,6 +251,8 @@ def parse_args():
>                           help="Graph the dependencies of PACKAGE")
>       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("--rdepth", metavar="RDEPTH", dest="rdepth", type=int, default=0,
> +                        help="Limit the dependency graph to DEPTH levels; 0 means no limit.")
>       parser.add_argument("--stop-on", "-s", metavar="PACKAGE", dest="stop_list", action="append",
>                           help="Do not graph past this package (can be given multiple times)." +
>                           " Can be a package name or a glob, " +
> @@ -265,9 +272,9 @@ def parse_args():
>                           default=False)
>       parser.add_argument("--no-transitive", dest="transitive", action='store_false',
>                           help="Draw (do not draw) transitive dependencies")
> -    parser.add_argument("--direct", dest="direct", action='store_true', default=True,
> +    parser.add_argument("--direct", dest="direct", action='store_true', default=False,
>                           help="Draw direct dependencies (the default)")
> -    parser.add_argument("--reverse", dest="direct", action='store_false',
> +    parser.add_argument("--reverse", dest="reverse", action='store_true', default=False,
>                           help="Draw reverse dependencies")
>       parser.add_argument("--quiet", '-q', dest="quiet", action='store_true',
>                           help="Quiet")
> @@ -292,6 +299,9 @@ def main():
>               sys.exit(1)
>           outfile = open(args.outfile, "w")
>   
> +    if not args.direct and not args.reverse: # select default direct if none is specified.
> +        args.direct = True
> +
>       if args.package is None:
>           mode = MODE_FULL
>           rootpkg = 'all'
> @@ -312,13 +322,9 @@ def main():
>       if args.exclude_mandatory:
>           exclude_list += MANDATORY_DEPS
>   
> -    if args.direct:
> -        arrow_dir = "forward"
> -    else:
> -        if mode == MODE_FULL:
> -            logging.error("--reverse needs a package")
> -            sys.exit(1)
> -        arrow_dir = "back"
> +    if args.reverse and mode == MODE_FULL:
> +        logging.error("--reverse needs a package")
> +        sys.exit(1)
>   
>       draw_graph = not args.flat_list
>   
> @@ -330,23 +336,34 @@ def main():
>           logging.error("Error: incorrect color list '%s'" % args.colors)
>           sys.exit(1)
>   
> -    deps, rdeps, dict_types, dict_versions = brpkgutil.get_dependency_tree()
> -    dict_deps = deps if args.direct else rdeps
> -
> -    check_circular_deps(dict_deps)
> -    if check_only:
> -        sys.exit(0)
> -
> -    dict_deps = remove_extra_deps(dict_deps, rootpkg, args.transitive, arrow_dir)
>   
>       # Start printing the graph data
> -    if draw_graph:
> +    if not check_only and draw_graph:
>           outfile.write("digraph G {\n")
>   
> -    print_pkg_deps(outfile, dict_deps, dict_types, dict_versions, stop_list, exclude_list,
> -                   arrow_dir, draw_graph, 0, args.depth, rootpkg, colors)
> +    deps, rdeps, dict_types, dict_versions = brpkgutil.get_dependency_tree()
>   
> -    if draw_graph:
> +    # forward
> +    if args.direct:
> +        dict_deps = deps
> +        direct = True
> +        check_circular_deps(dict_deps)
> +        if not check_only:
> +            dict_deps = remove_extra_deps(dict_deps, rootpkg, args.transitive, direct)
> +            print_pkg_deps(outfile, dict_deps, dict_types, dict_versions, stop_list, exclude_list,
> +                           direct, draw_graph, 0, args.depth, rootpkg, colors)
> +
> +    # reverse
> +    if args.reverse:
> +        dict_deps = rdeps
> +        direct = False
> +        check_circular_deps(dict_deps)
> +        if not check_only:
> +            dict_deps = remove_extra_deps(dict_deps, rootpkg, args.transitive, direct)
> +            print_pkg_deps(outfile, dict_deps, dict_types, dict_versions, stop_list, exclude_list,
> +                           direct, draw_graph, 0, args.rdepth, rootpkg, colors)
> +
> +    if not check_only and draw_graph:
>           outfile.write("}\n")
>       else:
>           outfile.write("\n")
_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2024-07-14 19:34 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-01-22 23:43 [Buildroot] [PATCH 1/2] support/scripts/graph-depends cleanup done_deps global Steve Hay via buildroot
2023-01-22 23:43 ` [Buildroot] [PATCH 2/2] support/scripts/graph-depends allow for forward and reverse depends on same graph Steve Hay via buildroot
2023-01-23  7:20   ` Yann E. MORIN
2023-01-23 23:06     ` ʎɐH ǝʌǝʇS via buildroot
2023-01-23  7:01 ` [Buildroot] [PATCH 1/2] support/scripts/graph-depends cleanup done_deps global Yann E. MORIN
     [not found]   ` <f1b4fdfa-786f-2b09-5396-33ad4e79b64f@stevenhay.com>
2023-01-23 20:15     ` ʎɐH ǝʌǝʇS via buildroot
  -- strict thread matches above, loose matches on Subject: below --
2023-01-23 23:12 [Buildroot] [PATCH 2/2] support/scripts/graph-depends allow for forward and reverse depends on same graph Steve Hay via buildroot
2023-02-06  5:27 ` ʎɐH ǝʌǝʇS via buildroot
2024-07-14 19:33 ` Arnout Vandecappelle via buildroot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox