diff --git a/python/mozbuild/mozbuild/backend/recursivemake.py b/python/mozbuild/mozbuild/backend/recursivemake.py index 7c9e4a0f618e..c8128e3349f9 100644 --- a/python/mozbuild/mozbuild/backend/recursivemake.py +++ b/python/mozbuild/mozbuild/backend/recursivemake.py @@ -16,6 +16,19 @@ from ..frontend.data import ( from ..util import FileAvoidWrite +STUB_MAKEFILE = ''' +# THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT MODIFY BY HAND. + +DEPTH := {depth} +topsrcdir := {topsrc} +srcdir := {src} +VPATH := {src} +relativesrcdir := {relsrc} + +include {topsrc}/config/rules.mk +'''.lstrip() + + class BackendMakeFile(object): """Represents a generated backend.mk file. @@ -73,9 +86,17 @@ class BackendMakeFile(object): self.fh.write('\n') self.fh.write('MOZBUILD_DERIVED := 1\n') - # SUBSTITUTE_FILES handles Makefile.in -> Makefile conversion. + # SUBSTITUTE_FILES handles Makefile.in -> Makefile conversion. This + # also doubles to handle the case where there is no Makefile.in. self.fh.write('NO_MAKEFILE_RULE := 1\n') + # We can't blindly have a SUBMAKEFILES rule because some of the + # Makefile may not have a corresponding Makefile.in. For the case + # where a new directory is added, the mozbuild file referencing that + # new directory will need updated. This will cause a full backend + # scan and build, installing the new Makefile. + self.fh.write('NO_SUBMAKEFILES_RULE := 1\n') + def write(self, buf): self.fh.write(buf) @@ -157,16 +178,29 @@ class RecursiveMakeBackend(BuildBackend): os.makedirs(bf.objdir) makefile_in = os.path.join(srcdir, 'Makefile.in') + makefile = os.path.join(bf.objdir, 'Makefile') - if not os.path.exists(makefile_in): - raise Exception('Could not find Makefile.in: %s' % makefile_in) + # If Makefile.in exists, use it as a template. Otherwise, create a + # stub. + if os.path.exists(makefile_in): + self.log(logging.DEBUG, 'substitute_makefile', + {'path': makefile}, 'Substituting makefile: {path}') + bf.environment.create_config_file(makefile) + bf.write('SUBSTITUTE_FILES += Makefile\n') + else: + self.log(logging.DEBUG, 'stub_makefile', + {'path': makefile}, 'Creating stub Makefile: {path}') - out_path = os.path.join(bf.objdir, 'Makefile') - self.log(logging.DEBUG, 'create_makefile', {'path': out_path}, - 'Generating makefile: {path}') - bf.environment.create_config_file(out_path) + params = { + 'topsrc': bf.environment.get_top_srcdir(makefile), + 'src': bf.environment.get_file_srcdir(makefile), + 'depth': bf.environment.get_depth(makefile), + 'relsrc': bf.environment.get_relative_srcdir(makefile), + } + + with FileAvoidWrite(makefile) as fh: + fh.write(STUB_MAKEFILE.format(**params)) - bf.write('SUBSTITUTE_FILES += Makefile\n') bf.close() def _process_directory_traversal(self, obj, backend_file): diff --git a/python/mozbuild/mozbuild/test/backend/data/stub0/dir2/Makefile.in b/python/mozbuild/mozbuild/test/backend/data/stub0/dir2/Makefile.in deleted file mode 100644 index a038825a9429..000000000000 --- a/python/mozbuild/mozbuild/test/backend/data/stub0/dir2/Makefile.in +++ /dev/null @@ -1,12 +0,0 @@ -# Any copyright is dedicated to the Public Domain. -# http://creativecommons.org/publicdomain/zero/1.0/ - -DEPTH := @DEPTH@ -topsrcdir := @top_srcdir@ -srcdir := @srcdir@ -VPATH = @srcdir@ - -include $(DEPTH)/config/autoconf.mk - -include $(topsrcdir)/config/rules.mk - diff --git a/python/mozbuild/mozbuild/test/backend/test_recursivemake.py b/python/mozbuild/mozbuild/test/backend/test_recursivemake.py index 65f30acc756a..cd678869cf19 100644 --- a/python/mozbuild/mozbuild/test/backend/test_recursivemake.py +++ b/python/mozbuild/mozbuild/test/backend/test_recursivemake.py @@ -31,11 +31,9 @@ class TestRecursiveMakeBackend(BackendTester): expected = ['', 'dir1', 'dir2'] for d in expected: - in_path = os.path.join(env.topsrcdir, d, 'Makefile.in') out_makefile = os.path.join(env.topobjdir, d, 'Makefile') out_backend = os.path.join(env.topobjdir, d, 'backend.mk') - self.assertTrue(os.path.exists(in_path)) self.assertTrue(os.path.exists(out_makefile)) self.assertTrue(os.path.exists(out_backend)) @@ -57,6 +55,18 @@ class TestRecursiveMakeBackend(BackendTester): 'include $(topsrcdir)/config/rules.mk' ]) + def test_missing_makefile_in(self): + """Ensure missing Makefile.in results in Makefile creation.""" + env = self._consume('stub0', RecursiveMakeBackend) + + p = os.path.join(env.topobjdir, 'dir2', 'Makefile') + self.assertTrue(os.path.exists(p)) + + lines = [l.strip() for l in open(p, 'rt').readlines()] + self.assertEqual(len(lines), 9) + + self.assertTrue(lines[0].startswith('# THIS FILE WAS AUTOMATICALLY')) + def test_backend_mk(self): """Ensure backend.mk file is written out properly.""" env = self._consume('stub0', RecursiveMakeBackend) @@ -67,6 +77,7 @@ class TestRecursiveMakeBackend(BackendTester): self.assertEqual(lines, [ 'MOZBUILD_DERIVED := 1', 'NO_MAKEFILE_RULE := 1', + 'NO_SUBMAKEFILES_RULE := 1', 'DIRS := dir1', 'PARALLEL_DIRS := dir2', 'TEST_DIRS := dir3', @@ -100,6 +111,7 @@ class TestRecursiveMakeBackend(BackendTester): self.assertEqual(lines, [ 'MOZBUILD_DERIVED := 1', 'NO_MAKEFILE_RULE := 1', + 'NO_SUBMAKEFILES_RULE := 1', 'DIRS := dir', 'PARALLEL_DIRS := p_dir', 'DIRS += external',