diff --git a/lib/bb/codeparser.py b/lib/bb/codeparser.py
index 9d66d3ae41..e7d7ebe048 100644
--- a/lib/bb/codeparser.py
+++ b/lib/bb/codeparser.py
@@ -36,6 +36,8 @@ from bb.cache import MultiProcessCache
 
 logger = logging.getLogger('BitBake.CodeParser')
 
+modulecode_deps = {}
+
 def bbhash(s):
     return hashlib.sha256(s.encode("utf-8")).hexdigest()
 
diff --git a/lib/bb/data.py b/lib/bb/data.py
index 22d314d6c2..ab1a5959ba 100644
--- a/lib/bb/data.py
+++ b/lib/bb/data.py
@@ -261,22 +261,9 @@ def emit_func_python(func, o=sys.__stdout__, d = init()):
                newdeps |= set((d.getVarFlag(dep, "vardeps") or "").split())
         newdeps -= seen
 
-def build_dependencies(key, keys, shelldeps, varflagsexcl, ignored_vars, d):
+def build_dependencies(key, keys, mod_funcs, shelldeps, varflagsexcl, ignored_vars, d):
     deps = set()
     try:
-        if key[-1] == ']':
-            vf = key[:-1].split('[')
-            if vf[1] == "vardepvalueexclude":
-                return deps, ""
-            value, parser = d.getVarFlag(vf[0], vf[1], False, retparser=True)
-            deps |= parser.references
-            deps = deps | (keys & parser.execs)
-            deps -= ignored_vars
-            return frozenset(deps), value
-        varflags = d.getVarFlags(key, ["vardeps", "vardepvalue", "vardepsexclude", "exports", "postfuncs", "prefuncs", "lineno", "filename"]) or {}
-        vardeps = varflags.get("vardeps")
-        exclusions = varflags.get("vardepsexclude", "").split()
-
         def handle_contains(value, contains, exclusions, d):
             newvalue = []
             if value:
@@ -294,6 +281,24 @@ def build_dependencies(key, keys, shelldeps, varflagsexcl, ignored_vars, d):
                         newvalue.append("\n%s{%s} = Set" % (k, item))
             return "".join(newvalue)
 
+        if key in mod_funcs:
+            exclusions = set()
+            moddep = bb.codeparser.modulecode_deps[key]
+            value = handle_contains("", moddep[3], exclusions, d)
+            return frozenset(moddep[0] - ignored_vars), value
+        if key[-1] == ']':
+            vf = key[:-1].split('[')
+            if vf[1] == "vardepvalueexclude":
+                return deps, ""
+            value, parser = d.getVarFlag(vf[0], vf[1], False, retparser=True)
+            deps |= parser.references
+            deps = deps | (keys & parser.execs)
+            deps -= ignored_vars
+            return frozenset(deps), value
+        varflags = d.getVarFlags(key, ["vardeps", "vardepvalue", "vardepsexclude", "exports", "postfuncs", "prefuncs", "lineno", "filename"]) or {}
+        vardeps = varflags.get("vardeps")
+        exclusions = varflags.get("vardepsexclude", "").split()
+
         def handle_remove(value, deps, removes, d):
             for r in sorted(removes):
                 r2 = d.expandWithRefs(r, None)
@@ -367,7 +372,8 @@ def build_dependencies(key, keys, shelldeps, varflagsexcl, ignored_vars, d):
 
 def generate_dependencies(d, ignored_vars):
 
-    keys = set(key for key in d if not key.startswith("__"))
+    mod_funcs = set(bb.codeparser.modulecode_deps.keys())
+    keys = set(key for key in d if not key.startswith("__")) | mod_funcs
     shelldeps = set(key for key in d.getVar("__exportlist", False) if d.getVarFlag(key, "export", False) and not d.getVarFlag(key, "unexport", False))
     varflagsexcl = d.getVar('BB_SIGNATURE_EXCLUDE_FLAGS')
 
@@ -376,7 +382,7 @@ def generate_dependencies(d, ignored_vars):
 
     tasklist = d.getVar('__BBTASKS', False) or []
     for task in tasklist:
-        deps[task], values[task] = build_dependencies(task, keys, shelldeps, varflagsexcl, ignored_vars, d)
+        deps[task], values[task] = build_dependencies(task, keys, mod_funcs, shelldeps, varflagsexcl, ignored_vars, d)
         newdeps = deps[task]
         seen = set()
         while newdeps:
@@ -385,7 +391,7 @@ def generate_dependencies(d, ignored_vars):
             newdeps = set()
             for dep in nextdeps:
                 if dep not in deps:
-                    deps[dep], values[dep] = build_dependencies(dep, keys, shelldeps, varflagsexcl, ignored_vars, d)
+                    deps[dep], values[dep] = build_dependencies(dep, keys, mod_funcs, shelldeps, varflagsexcl, ignored_vars, d)
                 newdeps |=  deps[dep]
             newdeps -= seen
         #print "For %s: %s" % (task, str(deps[task]))
diff --git a/lib/bb/parse/ast.py b/lib/bb/parse/ast.py
index 7bfee9ed67..7dbb1adfa8 100644
--- a/lib/bb/parse/ast.py
+++ b/lib/bb/parse/ast.py
@@ -10,6 +10,7 @@
 #
 
 import sys
+import inspect
 import bb
 from bb import methodpool
 from bb.parse import logger
@@ -284,7 +285,44 @@ class PyLibNode(AstNode):
             bb.utils._context[self.namespace] = __import__(self.namespace)
             toimport = getattr(bb.utils._context[self.namespace], "BBIMPORTS", [])
             for i in toimport:
-                bb.utils._context[i.split(".", 1)[0]] = __import__(i)
+                base = i.split(".", 1)[0]
+                bb.utils._context[base] = __import__(i)
+                if "." in i:
+                    mod = getattr(bb.utils._context[base], i.split(".", 1)[1])
+                    funcs = dir(mod)
+                    for f in funcs:
+                        if f.startswith("_"):
+                            continue
+                        fcall = getattr(mod, f)
+                        if not callable(fcall):
+                            continue
+                        src = inspect.getsource(fcall)
+                        name = "%s.%s" % (i, f)
+                        parser = bb.codeparser.PythonParser(name, logger)
+                        parser.parse_python(src, filename=inspect.getfile(fcall), lineno=1)
+                        execs = parser.execs
+                        # Expand internal module exec references
+                        for e in parser.execs:
+                            if e in funcs:
+                                execs.remove(e)
+                                execs.add(i + "." + e)
+                        bb.codeparser.modulecode_deps[name] = [parser.references.copy(), execs, parser.var_execs.copy(), parser.contains.copy()]
+                        #bb.warn("%s: %s\nRefs:%s Execs: %s %s %s" % (name, src, parser.references, parser.execs, parser.var_execs, parser.contains))
+
+            # Resolve intermodule references now, stack dependencies
+            found = True
+            while found:
+                found = False
+                funcs = set(bb.codeparser.modulecode_deps.keys())
+                for entry in bb.codeparser.modulecode_deps:
+                    for dup in (bb.codeparser.modulecode_deps[entry][1] & funcs):
+                        found = True
+                        bb.codeparser.modulecode_deps[entry][1].remove(dup)
+                        bb.codeparser.modulecode_deps[entry][0] |= bb.codeparser.modulecode_deps[dup][0]
+                        bb.codeparser.modulecode_deps[entry][1] |= bb.codeparser.modulecode_deps[dup][1]
+                        bb.codeparser.modulecode_deps[entry][2] |= bb.codeparser.modulecode_deps[dup][2]
+                        bb.codeparser.modulecode_deps[entry][3] |= bb.codeparser.modulecode_deps[dup][3]
+
         except AttributeError as e:
             bb.error("Error importing OE modules: %s" % str(e))
 
