import os
import sys
+from itertools import filterfalse
-def die(msg):
- sys.exit('ERROR: ' + msg)
+
+# https://docs.python.org/3/library/itertools.html#itertools-recipes
+
+def unique_everseen(iterable, key=None):
+ "List unique elements, preserving order. Remember all elements ever seen."
+ # unique_everseen('AAAABBBCCDAABBB') --> A B C D
+ # unique_everseen('ABBCcAD', str.lower) --> A B C D
+ seen = set()
+ seen_add = seen.add
+ if key is None:
+ for element in filterfalse(seen.__contains__, iterable):
+ seen_add(element)
+ yield element
+ else:
+ for element in iterable:
+ k = key(element)
+ if k not in seen:
+ seen_add(k)
+ yield element
-if len(sys.argv) != 1:
- die('buildorder.py takes no arguments')
+def die(msg):
+ sys.exit('ERROR: ' + msg)
class TermuxBuildFile(object):
dep_pkg.needed_by.add(pkg)
-def buildorder():
+def generate_full_buildorder():
+ build_order = []
+
# List of all TermuxPackages without dependencies
leaf_pkgs = [pkg for name, pkg in pkgs_map.items() if not pkg.deps]
pkg_queue = sorted(leaf_pkgs, key=lambda p: '' if p.name == 'libandroid-support' else p.name)
# Topological sorting
- build_order = []
visited = set()
while pkg_queue:
pkg = pkg_queue.pop(0)
if pkg.name in visited:
continue
- visited.add(pkg.name)
# print("Processing {}:".format(pkg.name), pkg.needed_by)
-
+ visited.add(pkg.name)
build_order.append(pkg)
for other_pkg in sorted(pkg.needed_by, key=lambda p: p.name):
- # Mark this package as done
+ # Remove this pkg from deps
remaining_deps[other_pkg.name].discard(pkg.name)
-
# ... and all its subpackages
remaining_deps[other_pkg.name].difference_update(
[subpkg.name for subpkg in pkg.subpkgs]
)
- if not remaining_deps[other_pkg.name]: # all deps were pruned?
- pkg_queue.append(other_pkg)
-
- return build_order
-
-
-def generate_and_print_buildorder():
- build_order = buildorder()
+ if not remaining_deps[other_pkg.name]: # all deps were already appended?
+ pkg_queue.append(other_pkg) # should be processed
if set(pkgs_map.values()) != set(build_order):
print("ERROR: Cycle exists. Remaining: ")
sys.exit(1)
- for pkg in build_order:
- print(pkg.name)
+ return build_order
+
+
+def deps_then_me(pkg):
+ l = []
+
+ for dep in sorted(pkg.deps):
+ l += deps_then_me(pkgs_map[dep])
+ l += [pkg]
- sys.exit(0)
+ return l
+
+
+def generate_targets_buildorder(targetnames):
+ buildorder = []
+
+ for pkgname in targetnames:
+ buildorder += deps_then_me(pkgs_map[pkgname])
+
+ return unique_everseen(buildorder)
if __name__ == '__main__':
populate()
- generate_and_print_buildorder()
+
+ if len(sys.argv) == 1:
+ bo = generate_full_buildorder()
+ else:
+ bo = generate_targets_buildorder(sys.argv[1:])
+
+ for pkg in bo:
+ print(pkg.name)