Merge branch 'master' of github.com:termux/termux-packages
[termux-packages] / scripts / buildorder.py
index fa02f7a..1890a0d 100755 (executable)
@@ -2,6 +2,7 @@
 # buildorder.py - script to generate a build order respecting package dependencies
 
 import os
+import re
 import sys
 
 from itertools import filterfalse
@@ -37,23 +38,26 @@ class TermuxBuildFile(object):
 
     def _get_dependencies(self):
         pkg_dep_prefix = 'TERMUX_PKG_DEPENDS='
+        pkg_build_dep_prefix = 'TERMUX_PKG_BUILD_DEPENDS='
         subpkg_dep_prefix = 'TERMUX_SUBPKG_DEPENDS='
 
-        with open(self.path) as f:
+        with open(self.path, encoding="utf-8") as f:
             prefix = None
             for line in f:
                 if line.startswith(pkg_dep_prefix):
                     prefix = pkg_dep_prefix
+                elif line.startswith(pkg_build_dep_prefix):
+                    prefix = pkg_build_dep_prefix
                 elif line.startswith(subpkg_dep_prefix):
                     prefix = subpkg_dep_prefix
                 else:
                     continue
 
-                comma_deps = line[len(prefix):].replace('"', '')
+                comma_deps = line[len(prefix):].replace('"', '').replace("'", '')
 
                 return set([
-                    dep.strip() for dep in comma_deps.split(',')
-                    if 'libandroid-support' not in dep
+                    # Replace parenthesis to handle version qualifiers, as in "gcc (>= 5.0)":
+                    re.sub(r'\(.*?\)', '', dep).replace('-dev', '').strip() for dep in comma_deps.split(',')
                 ])
 
         # no deps found
@@ -70,10 +74,13 @@ class TermuxPackage(object):
         # search package build.sh
         build_sh_path = os.path.join(self.dir, 'build.sh')
         if not os.path.isfile(build_sh_path):
-            raise Exception("build.sh not found")
+            raise Exception("build.sh not found for package '" + name + "'")
 
         self.buildfile = TermuxBuildFile(build_sh_path)
         self.deps = self.buildfile._get_dependencies()
+        if 'libandroid-support' not in self.deps and self.name != 'libandroid-support':
+            # Every package may depend on libandroid-support without declaring it:
+            self.deps.add('libandroid-support')
 
         # search subpackages
         self.subpkgs = []
@@ -163,9 +170,8 @@ def generate_full_buildorder():
     if not leaf_pkgs:
         die('No package without dependencies - where to start?')
 
-    # Sort alphabetically, but with libandroid-support first (since dependency on libandroid-support
-    # does not need to be declared explicitly, so anything might in theory depend on it to build):
-    pkg_queue = sorted(leaf_pkgs, key=lambda p: '' if p.name == 'libandroid-support' else p.name)
+    # Sort alphabetically:
+    pkg_queue = sorted(leaf_pkgs, key=lambda p: p.name)
 
     # Topological sorting
     visited = set()
@@ -215,6 +221,8 @@ def generate_targets_buildorder(targetnames):
     buildorder = []
 
     for pkgname in targetnames:
+        if not pkgname in pkgs_map:
+            die('Dependencies for ' + pkgname + ' could not be calculated (skip dependency check with -s)')
         buildorder += deps_then_me(pkgs_map[pkgname])
 
     return unique_everseen(buildorder)