diff --git a/tools/amalgam.py b/tools/amalgam.py
index d78370e6924475a132383a8f60453db99356d693..19291d19ac6771d78eda3b6bfd0f7440ab052b13 100755
--- a/tools/amalgam.py
+++ b/tools/amalgam.py
@@ -61,10 +61,11 @@ parser.add_argument('-I', default=".", dest='include_path', help='include path')
 parser.add_argument('sources', nargs='*', help='sources')
 
 class File(object):
-    def __init__(self, name):
+    def __init__(self, name, parent_name):
         self.name = name
+        self.parent_name = parent_name
         self.buf = StringIO()
-        emit_file(self.buf, self.name)
+        emit_file(self.buf, self.name, self.parent_name)
 
     def emit(self):
         print self.buf.getvalue(),
@@ -79,14 +80,22 @@ already_included = set()
 
 ignore_files = [i.strip() for i in args.ignore.split(',')]
 
-def should_ignore(name):
+def should_ignore(name, parent_name):
     return (name in already_included
-            or not (args.strict or os.path.exists(resolve(name)))
+            or not (args.strict or os.path.exists(resolve(name, parent_name)))
             or name in ignore_files)
 
-def resolve(path):
+def resolve(path, parent_name):
+    path_from_parent = None
+    if parent_name != None and not os.path.isabs(path):
+        # calculate the path relative to the "parent_name" file, i.e. to the file
+        # which includes the current one.
+        path_from_parent = os.path.join(os.path.dirname(parent_name), path)
+
     if os.path.isabs(path) or os.path.exists(path):
         p = path
+    elif path_from_parent != None and os.path.exists(path_from_parent):
+        p = path_from_parent
     else:
         p = os.path.join(args.include_path, path)
     if os.path.exists(p) and not args.norel:
@@ -94,40 +103,40 @@ def resolve(path):
     # print >>sys.stderr, '%s -> %s (cwd %s)' % (path, p, os.getcwd())
     return p
 
-def emit_line_directive(out, name):
+def emit_line_directive(out, name, parent_name):
     print >>out, '''#ifdef %(prefix)s_MODULE_LINES
 #line 1 "%(name)s"
 #endif''' % dict(
     prefix = args.prefix,
-    name = resolve(name),
+    name = resolve(name, parent_name),
 )
 
-def emit_body(out, name):
-    path = resolve(name)
-    if not args.strict and not os.path.exists(path):
+def emit_body(out, name, parent_name):
+    resolved_name = resolve(name, parent_name)
+    if not args.strict and not os.path.exists(resolved_name):
         print >>out, '#include "%s"' % (name,)
         return
 
-    with open(resolve(name)) as f:
+    with open(resolved_name) as f:
         for l in f:
             match = re.match('( *#include "(.*)")', l)
             if match:
-                all, path = match.groups()
+                all, path_to_include = match.groups()
                 if args.autoinc:
-                    if not should_ignore(path):
-                        already_included.add(path)
-                        includes.append(File(path))
+                    if not should_ignore(path_to_include, parent_name):
+                        already_included.add(path_to_include)
+                        includes.append(File(path_to_include, resolved_name))
                 print >>out, '/* Amalgamated: %s */' % (all,)
             else:
                 print >>out, l,
 
 
-def emit_file(out, name):
-    emit_line_directive(out, name)
-    emit_body(out, name)
+def emit_file(out, name, parent_name):
+    emit_line_directive(out, name, parent_name)
+    emit_body(out, name, parent_name)
 
 for i in args.sources:
-    sources.append(File(i))
+    sources.append(File(i, None))
 
 if args.first:
     for inc in reversed(args.first.split(',')):