# HG changeset patch
# User Chris Manchester <cmanchester@mozilla.com>
# Date 1521588665 25200
# Node ID decbe4a4cdc77b610f7b9bae8622dbfcd00f2694
# Parent  989c246b8606907c1e4218db7c254820c8d13fc7
Bug 1429875 - Add a unit test for linkage variables in the make backend. r=glandium

MozReview-Commit-ID: HREobMhWTwg

diff --git a/python/mozbuild/mozbuild/test/backend/common.py b/python/mozbuild/mozbuild/test/backend/common.py
--- a/python/mozbuild/mozbuild/test/backend/common.py
+++ b/python/mozbuild/mozbuild/test/backend/common.py
@@ -191,16 +191,27 @@ CONFIGS = defaultdict(lambda: {
     'program-paths': {
         'defines': {},
         'non_global_defines': [],
         'substs': {
             'COMPILE_ENVIRONMENT': '1',
             'BIN_SUFFIX': '.prog',
         },
     },
+    'linkage': {
+        'defines': {},
+        'non_global_defines': [],
+        'substs': {
+            'COMPILE_ENVIRONMENT': '1',
+            'LIB_SUFFIX': 'a',
+            'BIN_SUFFIX': '.exe',
+            'DLL_SUFFIX': '.so',
+            'OBJ_SUFFIX': 'o',
+        },
+    },
 })
 
 
 class BackendTester(unittest.TestCase):
     def setUp(self):
         self._old_env = dict(os.environ)
         os.environ.pop('MOZ_OBJDIR', None)
 
diff --git a/python/mozbuild/mozbuild/test/backend/data/linkage/moz.build b/python/mozbuild/mozbuild/test/backend/data/linkage/moz.build
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/linkage/moz.build
@@ -0,0 +1,11 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+include('templates.mozbuild')
+
+DIRS += [
+     'real',
+     'shared',
+     'prog',
+     'static',
+]
\ No newline at end of file
diff --git a/python/mozbuild/mozbuild/test/backend/data/linkage/prog/moz.build b/python/mozbuild/mozbuild/test/backend/data/linkage/prog/moz.build
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/linkage/prog/moz.build
@@ -0,0 +1,11 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+DIRS += ['qux']
+
+Program('MyProgram')
+
+USE_LIBS += [
+    'bar',
+    'baz',
+]
diff --git a/python/mozbuild/mozbuild/test/backend/data/linkage/prog/qux/moz.build b/python/mozbuild/mozbuild/test/backend/data/linkage/prog/qux/moz.build
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/linkage/prog/qux/moz.build
@@ -0,0 +1,6 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+SOURCES += ['qux1.c']
+
+SharedLibrary('qux')
\ No newline at end of file
diff --git a/python/mozbuild/mozbuild/test/backend/data/linkage/prog/qux/qux1.c b/python/mozbuild/mozbuild/test/backend/data/linkage/prog/qux/qux1.c
new file mode 100644
diff --git a/python/mozbuild/mozbuild/test/backend/data/linkage/real/foo/foo1.c b/python/mozbuild/mozbuild/test/backend/data/linkage/real/foo/foo1.c
new file mode 100644
diff --git a/python/mozbuild/mozbuild/test/backend/data/linkage/real/foo/foo2.c b/python/mozbuild/mozbuild/test/backend/data/linkage/real/foo/foo2.c
new file mode 100644
diff --git a/python/mozbuild/mozbuild/test/backend/data/linkage/real/foo/moz.build b/python/mozbuild/mozbuild/test/backend/data/linkage/real/foo/moz.build
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/linkage/real/foo/moz.build
@@ -0,0 +1,9 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+SOURCES += [
+    'foo1.c',
+    'foo2.c'
+]
+
+FINAL_LIBRARY = 'foo'
\ No newline at end of file
diff --git a/python/mozbuild/mozbuild/test/backend/data/linkage/real/moz.build b/python/mozbuild/mozbuild/test/backend/data/linkage/real/moz.build
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/linkage/real/moz.build
@@ -0,0 +1,14 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+DIRS += [
+    'foo',
+]
+
+NO_EXPAND_LIBS = True
+
+OS_LIBS += ['-lbaz']
+
+USE_LIBS += ['static:baz']
+
+Library('foo')
\ No newline at end of file
diff --git a/python/mozbuild/mozbuild/test/backend/data/linkage/shared/baz/baz1.c b/python/mozbuild/mozbuild/test/backend/data/linkage/shared/baz/baz1.c
new file mode 100644
diff --git a/python/mozbuild/mozbuild/test/backend/data/linkage/shared/baz/moz.build b/python/mozbuild/mozbuild/test/backend/data/linkage/shared/baz/moz.build
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/linkage/shared/baz/moz.build
@@ -0,0 +1,6 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+SOURCES += ['baz1.c']
+
+FINAL_LIBRARY = 'baz'
\ No newline at end of file
diff --git a/python/mozbuild/mozbuild/test/backend/data/linkage/shared/moz.build b/python/mozbuild/mozbuild/test/backend/data/linkage/shared/moz.build
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/linkage/shared/moz.build
@@ -0,0 +1,14 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+DIRS += [
+    'baz',
+]
+
+STATIC_LIBRARY_NAME = 'baz_s'
+FORCE_STATIC_LIB = True
+
+OS_LIBS += ['-lfoo']
+USE_LIBS += ['qux']
+
+SharedLibrary('baz')
\ No newline at end of file
diff --git a/python/mozbuild/mozbuild/test/backend/data/linkage/static/bar/bar1.cc b/python/mozbuild/mozbuild/test/backend/data/linkage/static/bar/bar1.cc
new file mode 100644
diff --git a/python/mozbuild/mozbuild/test/backend/data/linkage/static/bar/moz.build b/python/mozbuild/mozbuild/test/backend/data/linkage/static/bar/moz.build
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/linkage/static/bar/moz.build
@@ -0,0 +1,8 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+SOURCES += [
+    'bar1.cc',
+]
+
+FINAL_LIBRARY = 'bar'
\ No newline at end of file
diff --git a/python/mozbuild/mozbuild/test/backend/data/linkage/static/moz.build b/python/mozbuild/mozbuild/test/backend/data/linkage/static/moz.build
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/linkage/static/moz.build
@@ -0,0 +1,12 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+DIRS += [
+    'bar',
+]
+
+USE_LIBS += ['foo']
+
+OS_LIBS += ['-lbar']
+
+Library('bar')
diff --git a/python/mozbuild/mozbuild/test/backend/data/linkage/templates.mozbuild b/python/mozbuild/mozbuild/test/backend/data/linkage/templates.mozbuild
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/linkage/templates.mozbuild
@@ -0,0 +1,23 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+@template
+def Library(name):
+    LIBRARY_NAME = name
+
+@template
+def SharedLibrary(name):
+    FORCE_SHARED_LIB = True
+    LIBRARY_NAME = name
+
+@template
+def Binary():
+    # Add -lfoo for testing purposes.
+    OS_LIBS += ['foo']
+
+
+@template
+def Program(name):
+    PROGRAM = name
+
+    Binary()
\ No newline at end of file
diff --git a/python/mozbuild/mozbuild/test/backend/test_recursivemake.py b/python/mozbuild/mozbuild/test/backend/test_recursivemake.py
--- a/python/mozbuild/mozbuild/test/backend/test_recursivemake.py
+++ b/python/mozbuild/mozbuild/test/backend/test_recursivemake.py
@@ -982,16 +982,61 @@ class TestRecursiveMakeBackend(BackendTe
 
         with open(os.path.join(env.topobjdir, 'cxx-library', 'backend.mk'), 'rb') as fh:
             lines = fh.readlines()
             lines = [line.rstrip() for line in lines]
 
             for line in lines:
                 self.assertNotIn('LIB_IS_C_ONLY', line)
 
+    def test_linkage(self):
+        env = self._consume('linkage', RecursiveMakeBackend)
+        expected_linkage = {
+            'prog': {
+                'SHARED_LIBS': ['$(DEPTH)/shared/baz', '$(DEPTH)/prog/qux/qux'],
+                'STATIC_LIBS': ['$(DEPTH)/static/bar%s' % env.lib_suffix],
+                'OS_LIBS': ['-lfoo', '-lbaz', '-lbar'],
+            },
+            'shared': {
+                'OS_LIBS': ['-lfoo'],
+                'SHARED_LIBS': ['$(DEPTH)/prog/qux/qux'],
+                'STATIC_LIBS': ['$(DEPTH)/shared/baz/shared_baz%s' %
+                                env.lib_suffix],
+            },
+            'static': {
+                'STATIC_LIBS': [
+                    '$(DEPTH)/static/bar/static_bar.a',
+                    '$(DEPTH)/real/foo.a',
+                ],
+                'OS_LIBS': ['-lbar'],
+                'SHARED_LIBS': [],
+            },
+            'real': {
+                'STATIC_LIBS': [
+                    '$(DEPTH)/shared/baz_s%s' % env.lib_suffix,
+                    '$(DEPTH)/real/foo/real_foo%s' % env.lib_suffix,
+                ],
+                'SHARED_LIBS': [],
+                'OS_LIBS': ['-lbaz'],
+            }
+        }
+        actual_linkage = {}
+        for name in expected_linkage.keys():
+            with open(os.path.join(env.topobjdir, name, 'backend.mk'), 'rb') as fh:
+                actual_linkage[name] = [line.rstrip() for line in fh.readlines()]
+        for name in expected_linkage:
+            for var in expected_linkage[name]:
+                for val in expected_linkage[name][var]:
+                    line = '%s += %s' % (var, val)
+                    self.assertIn(line,
+                                  actual_linkage[name])
+                    actual_linkage[name].remove(line)
+                for line in actual_linkage[name]:
+                    self.assertNotIn('%s +=' % var, line)
+
     def test_jar_manifests(self):
         env = self._consume('jar-manifests', RecursiveMakeBackend)
 
         with open(os.path.join(env.topobjdir, 'backend.mk'), 'rb') as fh:
             lines = fh.readlines()
 
         lines = [line.rstrip() for line in lines]
 
