build: check for circular build dependencies
authorAndrew Tridgell <tridge@samba.org>
Tue, 23 Feb 2010 02:04:34 +0000 (13:04 +1100)
committerAndrew Tridgell <tridge@samba.org>
Tue, 6 Apr 2010 10:26:36 +0000 (20:26 +1000)
lib/replace/wafsamba.py
source4/wscript_build

index e26d602db0604ea6f1d98c7313fe75adf2c2d96f..575e946c29bc76ec3941ff06a9abfcb325046354 100644 (file)
@@ -124,11 +124,10 @@ Build.BuildContext.set_rpath = set_rpath
 # return a named build cache dictionary, used to store
 # state inside the following functions
 def BUILD_CACHE(bld, name):
-    try:
-        cache = bld.name
-    except AttributeError:
-        bld.name = cache = {}
-    return cache
+    if name in bld.env:
+        return bld.env[name]
+    bld.env[name] = {}
+    return bld.env[name]
 
 
 #############################################################
@@ -220,6 +219,9 @@ def SAMBA_LIBRARY(bld, libname, source_list,
         )
     cache = BUILD_CACHE(bld, 'INCLUDE_LIST')
     cache[libname] = ilist
+
+    cache = BUILD_CACHE(bld, 'LIB_DEPS')
+    cache[libname] = deps.split()
 Build.BuildContext.SAMBA_LIBRARY = SAMBA_LIBRARY
 
 
@@ -240,6 +242,9 @@ def SAMBA_BINARY(bld, binname, source_list,
     ilist = bld.NORMPATH(ilist)
     ccflags = ''
 
+    cache = BUILD_CACHE(bld, 'LIB_DEPS')
+    cache[binname] = deps.split()
+
     cache = BUILD_CACHE(bld, 'INIT_FUNCTIONS')
     if modules is not None:
         for m in modules.split():
@@ -270,6 +275,10 @@ def SAMBA_PYTHON(bld, name, source_list,
                  deps='',
                  public_deps='',
                  realname=''):
+
+    cache = BUILD_CACHE(bld, 'LIB_DEPS')
+    cache[name] = deps.split()
+
     Logs.debug('runner: PYTHON_SAMBA not implemented')
     return
 Build.BuildContext.SAMBA_PYTHON = SAMBA_PYTHON
@@ -328,6 +337,34 @@ def BUILD_SUBDIR(bld, dir):
     bld.add_subdirs(dir)
 Build.BuildContext.BUILD_SUBDIR = BUILD_SUBDIR
 
+def CIRCULAR_DEPENDENCY(deps, path, cache, target):
+    if target not in cache:
+        return False
+    for t in cache[target]:
+        if t in deps:
+            print "Circular dependency on target %s: %s" % (t, path)
+            return True
+        if CIRCULAR_DEPENDENCY(deps,
+                               ("%s->%s" % (path, t)),
+                               cache, t):
+            return True
+        deps[t] = True
+    return False
+
+############################################################
+# check our build dependencies for circular dependencies
+def CHECK_DEPENDENCIES(bld):
+    cache = BUILD_CACHE(bld, 'LIB_DEPS')
+    print "Checking for circular dependencies"
+    for target in cache:
+        deps = {}
+        path = target
+        bld.ASSERT(not CIRCULAR_DEPENDENCY(deps, path, cache, target),
+                   "Circular dependency in target %s" % target)
+    print "No circular dependencies"
+
+Build.BuildContext.CHECK_DEPENDENCIES = CHECK_DEPENDENCIES
+
 
 ############################################################
 # this overrides the 'waf -v' debug output to be in a nice
index 9fdc6b9ecf207a4a5aeeec9ea9ed837dce67d286..e6841f3aec09b3ca5f3b8ac3ecbaca7780d34b90 100644 (file)
@@ -62,3 +62,6 @@ bld.BUILD_SUBDIR('../libcli/drsuapi')
 bld.BUILD_SUBDIR('../libcli/samsync')
 bld.BUILD_SUBDIR('../libgpo')
 bld.BUILD_SUBDIR('../libcli/named_pipe_auth')
+
+# check if we have any circular build dependencies
+bld.CHECK_DEPENDENCIES()