diff --git a/python/mozbuild/mozbuild/backend/android_eclipse.py b/python/mozbuild/mozbuild/backend/android_eclipse.py
new file mode 100644
index 000000000000..31da09a71096
--- /dev/null
+++ b/python/mozbuild/mozbuild/backend/android_eclipse.py
@@ -0,0 +1,190 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+from __future__ import unicode_literals
+
+import itertools
+import os
+import xml.etree.ElementTree as ET
+
+from mozpack.copier import FileCopier
+from mozpack.files import (FileFinder, PreprocessedFile)
+from mozpack.manifests import InstallManifest
+import mozpack.path as mozpath
+
+from .common import CommonBackend
+from ..frontend.data import (
+ AndroidEclipseProjectData,
+ SandboxDerived,
+ SandboxWrapped,
+)
+from ..makeutil import Makefile
+from ..util import ensureParentDir
+
+
+class AndroidEclipseBackend(CommonBackend):
+ """Backend that generates Android Eclipse project files.
+ """
+
+ def _init(self):
+ CommonBackend._init(self)
+
+
+ def consume_object(self, obj):
+ """Write out Android Eclipse project files."""
+
+ if not isinstance(obj, SandboxDerived):
+ return
+
+ CommonBackend.consume_object(self, obj)
+
+ # If CommonBackend acknowledged the object, we're done with it.
+ if obj._ack:
+ return
+
+ # We don't want to handle most things, so we just acknowledge all objects...
+ obj.ack()
+
+ # ... and handle the one case we care about specially.
+ if isinstance(obj, SandboxWrapped) and isinstance(obj.wrapped, AndroidEclipseProjectData):
+ self._process_android_eclipse_project_data(obj.wrapped, obj.srcdir, obj.objdir)
+
+ def consume_finished(self):
+ """The common backend handles WebIDL and test files. We don't handle
+ these, so we don't call our superclass.
+ """
+
+ def _Element_for_classpathentry(self, cpe):
+ """Turn a ClassPathEntry into an XML Element, like one of:
+
+
+
+
+
+
+
+ """
+ e = ET.Element('classpathentry')
+ e.set('kind', 'src')
+ e.set('including', '**/*.java')
+ e.set('path', cpe.path)
+ if cpe.exclude_patterns:
+ e.set('excluding', '|'.join(sorted(cpe.exclude_patterns)))
+ if cpe.ignore_warnings:
+ attrs = ET.SubElement(e, 'attributes')
+ attr = ET.SubElement(attrs, 'attribute')
+ attr.set('name', 'ignore_optional_problems')
+ attr.set('value', 'true')
+ return e
+
+ def _Element_for_referenced_project(self, name):
+ """Turn a referenced project name into an XML Element, like:
+
+ """
+ e = ET.Element('classpathentry')
+ e.set('kind', 'src')
+ e.set('combineaccessrules', 'false')
+ # All project directories are in the same root; this
+ # reference is absolute in the Eclipse namespace.
+ e.set('path', '/' + name)
+ return e
+
+ def _Element_for_extra_jar(self, name):
+ """Turn a referenced JAR name into an XML Element, like:
+
+ """
+ e = ET.Element('classpathentry')
+ e.set('kind', 'lib')
+ # All project directories are in the same root; this
+ # reference is absolute in the Eclipse namespace.
+ e.set('path', 'libs/' + name)
+ return e
+
+ def _manifest_for_project(self, srcdir, project):
+ manifest = InstallManifest()
+
+ if project.manifest:
+ manifest.add_copy(mozpath.join(srcdir, project.manifest), 'AndroidManifest.xml')
+
+ if project.res:
+ manifest.add_symlink(mozpath.join(srcdir, project.res), 'res')
+
+ if project.assets:
+ manifest.add_symlink(mozpath.join(srcdir, project.assets), 'assets')
+
+ for cpe in project._classpathentries:
+ manifest.add_symlink(mozpath.join(srcdir, cpe.srcdir), cpe.dstdir)
+
+ # JARs and native libraries go in the same place. This
+ # wouldn't be a problem, except we only know the contents of
+ # (a subdirectory of) libs/ after a successful build and
+ # package, which is after build-backend time. So we use a
+ # pattern symlink that is resolved at manifest install time.
+ if project.libs:
+ manifest.add_pattern_copy(mozpath.join(srcdir, project.libs), '**', 'libs')
+
+ for extra_jar in sorted(project.extra_jars):
+ manifest.add_copy(mozpath.join(srcdir, extra_jar), mozpath.join('libs', os.path.basename(extra_jar)))
+
+ return manifest
+
+ def _process_android_eclipse_project_data(self, data, srcdir, objdir):
+ # This can't be relative to the environment's topsrcdir,
+ # because during testing topsrcdir is faked.
+ template_directory = os.path.abspath(mozpath.join(os.path.dirname(__file__),
+ 'templates', 'android_eclipse'))
+
+ project_directory = mozpath.join(self.environment.topobjdir, 'android_eclipse', data.name)
+ manifest_path = mozpath.join(self.environment.topobjdir, 'android_eclipse', '%s.manifest' % data.name)
+
+ manifest = self._manifest_for_project(srcdir, data)
+ ensureParentDir(manifest_path)
+ manifest.write(path=manifest_path)
+
+ classpathentries = []
+ for cpe in sorted(data._classpathentries, key=lambda x: x.path):
+ e = self._Element_for_classpathentry(cpe)
+ classpathentries.append(ET.tostring(e))
+
+ for name in sorted(data.referenced_projects):
+ e = self._Element_for_referenced_project(name)
+ classpathentries.append(ET.tostring(e))
+
+ for name in sorted(data.extra_jars):
+ e = self._Element_for_extra_jar(os.path.basename(name))
+ classpathentries.append(ET.tostring(e))
+
+ defines = {}
+ defines['IDE_OBJDIR'] = objdir
+ defines['IDE_TOPOBJDIR'] = self.environment.topobjdir
+ defines['IDE_SRCDIR'] = srcdir
+ defines['IDE_TOPSRCDIR'] = self.environment.topsrcdir
+ defines['IDE_PROJECT_NAME'] = data.name
+ defines['IDE_PACKAGE_NAME'] = data.package_name
+ defines['IDE_PROJECT_DIRECTORY'] = project_directory
+ defines['IDE_RELSRCDIR'] = mozpath.relpath(srcdir, self.environment.topsrcdir)
+ defines['IDE_CLASSPATH_ENTRIES'] = '\n'.join('\t' + cpe for cpe in classpathentries)
+ defines['IDE_RECURSIVE_MAKE_TARGETS'] = ' '.join(sorted(data.recursive_make_targets))
+ # Like android.library=true
+ defines['IDE_PROJECT_LIBRARY_SETTING'] = 'android.library=true' if data.is_library else ''
+ # Like android.library.reference.1=FennecBrandingResources
+ defines['IDE_PROJECT_LIBRARY_REFERENCES'] = '\n'.join(
+ 'android.library.reference.%s=%s' % (i + 1, ref)
+ for i, ref in enumerate(sorted(data.included_projects)))
+
+ copier = FileCopier()
+ finder = FileFinder(template_directory)
+ for input_filename, f in itertools.chain(finder.find('**'), finder.find('.**')):
+ if input_filename == 'AndroidManifest.xml' and not data.is_library:
+ # Main projects supply their own manifests.
+ continue
+ copier.add(input_filename, PreprocessedFile(
+ mozpath.join(finder.base, input_filename),
+ depfile_path=None,
+ marker='#',
+ defines=defines,
+ extra_depends={mozpath.join(finder.base, input_filename)}))
+
+ # When we re-create the build backend, we kill everything that was there.
+ copier.copy(project_directory, skip_if_older=False, remove_unaccounted=True)
diff --git a/python/mozbuild/mozbuild/test/backend/data/android_eclipse/library1/resources/values/strings.xml b/python/mozbuild/mozbuild/test/backend/data/android_eclipse/library1/resources/values/strings.xml
new file mode 100644
index 000000000000..a7337c554091
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/android_eclipse/library1/resources/values/strings.xml
@@ -0,0 +1 @@
+library1
diff --git a/python/mozbuild/mozbuild/test/backend/data/android_eclipse/main1/AndroidManifest.xml b/python/mozbuild/mozbuild/test/backend/data/android_eclipse/main1/AndroidManifest.xml
new file mode 100644
index 000000000000..7a906454df83
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/android_eclipse/main1/AndroidManifest.xml
@@ -0,0 +1 @@
+
diff --git a/python/mozbuild/mozbuild/test/backend/data/android_eclipse/main2/AndroidManifest.xml b/python/mozbuild/mozbuild/test/backend/data/android_eclipse/main2/AndroidManifest.xml
new file mode 100644
index 000000000000..7a906454df83
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/android_eclipse/main2/AndroidManifest.xml
@@ -0,0 +1 @@
+
diff --git a/python/mozbuild/mozbuild/test/backend/data/android_eclipse/main2/assets/dummy.txt b/python/mozbuild/mozbuild/test/backend/data/android_eclipse/main2/assets/dummy.txt
new file mode 100644
index 000000000000..c32a9599326a
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/android_eclipse/main2/assets/dummy.txt
@@ -0,0 +1 @@
+# Placeholder.
\ No newline at end of file
diff --git a/python/mozbuild/mozbuild/test/backend/data/android_eclipse/main2/extra.jar b/python/mozbuild/mozbuild/test/backend/data/android_eclipse/main2/extra.jar
new file mode 100644
index 000000000000..c32a9599326a
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/android_eclipse/main2/extra.jar
@@ -0,0 +1 @@
+# Placeholder.
\ No newline at end of file
diff --git a/python/mozbuild/mozbuild/test/backend/data/android_eclipse/main2/res/values/strings.xml b/python/mozbuild/mozbuild/test/backend/data/android_eclipse/main2/res/values/strings.xml
new file mode 100644
index 000000000000..0b28bf41ecf6
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/android_eclipse/main2/res/values/strings.xml
@@ -0,0 +1 @@
+main1
diff --git a/python/mozbuild/mozbuild/test/backend/data/android_eclipse/main3/AndroidManifest.xml b/python/mozbuild/mozbuild/test/backend/data/android_eclipse/main3/AndroidManifest.xml
new file mode 100644
index 000000000000..7a906454df83
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/android_eclipse/main3/AndroidManifest.xml
@@ -0,0 +1 @@
+
diff --git a/python/mozbuild/mozbuild/test/backend/data/android_eclipse/main3/a/A.java b/python/mozbuild/mozbuild/test/backend/data/android_eclipse/main3/a/A.java
new file mode 100644
index 000000000000..0ab867d3d75a
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/android_eclipse/main3/a/A.java
@@ -0,0 +1 @@
+package a.a;
diff --git a/python/mozbuild/mozbuild/test/backend/data/android_eclipse/main3/b/B.java b/python/mozbuild/mozbuild/test/backend/data/android_eclipse/main3/b/B.java
new file mode 100644
index 000000000000..66eb44c15027
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/android_eclipse/main3/b/B.java
@@ -0,0 +1 @@
+package b;
diff --git a/python/mozbuild/mozbuild/test/backend/data/android_eclipse/main3/c/C.java b/python/mozbuild/mozbuild/test/backend/data/android_eclipse/main3/c/C.java
new file mode 100644
index 000000000000..ca474ff33a4e
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/android_eclipse/main3/c/C.java
@@ -0,0 +1 @@
+package d.e;
diff --git a/python/mozbuild/mozbuild/test/backend/data/android_eclipse/main4 b/python/mozbuild/mozbuild/test/backend/data/android_eclipse/main4
new file mode 100644
index 000000000000..7a906454df83
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/android_eclipse/main4
@@ -0,0 +1 @@
+
diff --git a/python/mozbuild/mozbuild/test/backend/data/android_eclipse/moz.build b/python/mozbuild/mozbuild/test/backend/data/android_eclipse/moz.build
new file mode 100644
index 000000000000..955148bc29ac
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/android_eclipse/moz.build
@@ -0,0 +1,37 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+
+p = add_android_eclipse_library_project('library1')
+p.package_name = 'org.mozilla.test.library1'
+p.res = 'library1/resources'
+
+p = add_android_eclipse_library_project('library2')
+p.package_name = 'org.mozilla.test.library2'
+
+p = add_android_eclipse_project('main1', 'main1/AndroidManifest.xml')
+p.package_name = 'org.mozilla.test.main1'
+p.recursive_make_targets += ['target1', 'target2']
+
+p = add_android_eclipse_project('main2', 'main2/AndroidManifest.xml')
+p.package_name = 'org.mozilla.test.main2'
+p.res = 'main2/res'
+p.assets = 'main2/assets'
+p.extra_jars = ['main2/extra.jar']
+
+p = add_android_eclipse_project('main3', 'main3/AndroidManifest.xml')
+p.package_name = 'org.mozilla.test.main3'
+cpe = p.add_classpathentry('a', 'main3/a', dstdir='a/a')
+cpe = p.add_classpathentry('b', 'main3/b', dstdir='b')
+cpe.exclude_patterns += ['b/Excludes.java', 'b/Excludes2.java']
+cpe = p.add_classpathentry('c', 'main3/c', dstdir='d/e')
+cpe.ignore_warnings = True
+
+p = add_android_eclipse_project('main4', 'main3/AndroidManifest.xml')
+p.package_name = 'org.mozilla.test.main3'
+p.referenced_projects += ['library1']
+p.included_projects += ['library2']
+p.recursive_make_targets += ['target3', 'target4']
+
+DIRS += ['subdir']
diff --git a/python/mozbuild/mozbuild/test/backend/data/android_eclipse/subdir/moz.build b/python/mozbuild/mozbuild/test/backend/data/android_eclipse/subdir/moz.build
new file mode 100644
index 000000000000..064a339d01b1
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/android_eclipse/subdir/moz.build
@@ -0,0 +1,13 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+DEFINES['FOO'] = 'FOO'
+
+p = add_android_eclipse_library_project('sublibrary')
+p.package_name = 'org.mozilla.test.sublibrary'
+p.is_library = True
+
+p = add_android_eclipse_project('submain', 'submain/AndroidManifest.xml')
+p.package_name = 'org.mozilla.test.submain'
+p.recursive_make_targets += ['subtarget1', 'subtarget2']
diff --git a/python/mozbuild/mozbuild/test/backend/data/android_eclipse/subdir/submain/AndroidManifest.xml b/python/mozbuild/mozbuild/test/backend/data/android_eclipse/subdir/submain/AndroidManifest.xml
new file mode 100644
index 000000000000..7a906454df83
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/android_eclipse/subdir/submain/AndroidManifest.xml
@@ -0,0 +1 @@
+
diff --git a/python/mozbuild/mozbuild/test/backend/test_android_eclipse.py b/python/mozbuild/mozbuild/test/backend/test_android_eclipse.py
new file mode 100644
index 000000000000..9d345d2a7fd7
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/test_android_eclipse.py
@@ -0,0 +1,151 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+from __future__ import unicode_literals
+
+import json
+import os
+import unittest
+
+from mozbuild.backend.android_eclipse import AndroidEclipseBackend
+from mozbuild.frontend.emitter import TreeMetadataEmitter
+from mozbuild.frontend.reader import BuildReader
+from mozbuild.test.backend.common import BackendTester
+from mozpack.manifests import InstallManifest
+from mozunit import main
+
+import mozpack.path as mozpath
+
+class TestAndroidEclipseBackend(BackendTester):
+ def __init__(self, *args, **kwargs):
+ BackendTester.__init__(self, *args, **kwargs)
+ self.env = None
+
+ def assertExists(self, *args):
+ p = mozpath.join(self.env.topobjdir, 'android_eclipse', *args)
+ self.assertTrue(os.path.exists(p), "Path %s exists" % p)
+
+ def assertNotExists(self, *args):
+ p = mozpath.join(self.env.topobjdir, 'android_eclipse', *args)
+ self.assertFalse(os.path.exists(p), "Path %s does not exist" % p)
+
+ def test_library_project_files(self):
+ """Ensure we generate reasonable files for library projects."""
+ self.env = self._consume('android_eclipse', AndroidEclipseBackend)
+ for f in ['.classpath',
+ '.project',
+ '.settings',
+ 'AndroidManifest.xml',
+ 'project.properties']:
+ self.assertExists('library1', f)
+
+ def test_main_project_files(self):
+ """Ensure we generate reasonable files for main (non-library) projects."""
+ self.env = self._consume('android_eclipse', AndroidEclipseBackend)
+ for f in ['.classpath',
+ '.externalToolBuilders',
+ '.project',
+ '.settings',
+ 'build.xml',
+ 'gen',
+ 'lint.xml',
+ 'project.properties']:
+ self.assertExists('main1', f)
+
+ def test_library_manifest(self):
+ """Ensure we generate manifest for library projects."""
+ self.env = self._consume('android_eclipse', AndroidEclipseBackend)
+ self.assertExists('library1', 'AndroidManifest.xml')
+
+ def test_classpathentries(self):
+ """Ensure we produce reasonable classpathentries."""
+ self.env = self._consume('android_eclipse', AndroidEclipseBackend)
+ self.assertExists('main3', '.classpath')
+ # This is brittle but simple.
+ with open(mozpath.join(self.env.topobjdir, 'android_eclipse', 'main3', '.classpath'), 'rt') as fh:
+ lines = fh.readlines()
+ lines = [line.strip() for line in lines]
+ self.assertIn('', lines)
+ self.assertIn('', lines)
+ self.assertIn('', lines)
+
+ def test_library_project_setting(self):
+ """Ensure we declare a library project correctly."""
+ self.env = self._consume('android_eclipse', AndroidEclipseBackend)
+
+ self.assertExists('library1', 'project.properties')
+ with open(mozpath.join(self.env.topobjdir, 'android_eclipse', 'library1', 'project.properties'), 'rt') as fh:
+ lines = fh.readlines()
+ lines = [line.strip() for line in lines]
+ self.assertIn('android.library=true', lines)
+
+ self.assertExists('main1', 'project.properties')
+ with open(mozpath.join(self.env.topobjdir, 'android_eclipse', 'main1', 'project.properties'), 'rt') as fh:
+ lines = fh.readlines()
+ lines = [line.strip() for line in lines]
+ self.assertNotIn('android.library=true', lines)
+
+ def test_referenced_projects(self):
+ """Ensure we reference another project correctly."""
+ self.env = self._consume('android_eclipse', AndroidEclipseBackend)
+ self.assertExists('main4', '.classpath')
+ # This is brittle but simple.
+ with open(mozpath.join(self.env.topobjdir, 'android_eclipse', 'main4', '.classpath'), 'rt') as fh:
+ lines = fh.readlines()
+ lines = [line.strip() for line in lines]
+ self.assertIn('', lines)
+
+ def test_included_projects(self):
+ """Ensure we include another project correctly."""
+ self.env = self._consume('android_eclipse', AndroidEclipseBackend)
+ self.assertExists('main4', 'project.properties')
+ # This is brittle but simple.
+ with open(mozpath.join(self.env.topobjdir, 'android_eclipse', 'main4', 'project.properties'), 'rt') as fh:
+ lines = fh.readlines()
+ lines = [line.strip() for line in lines]
+ self.assertIn('android.library.reference.1=library2', lines)
+
+ def assertInManifest(self, project_name, *args):
+ manifest_path = mozpath.join(self.env.topobjdir, 'android_eclipse', '%s.manifest' % project_name)
+ manifest = InstallManifest(manifest_path)
+ for arg in args:
+ self.assertIn(arg, manifest, '%s in manifest for project %s' % (arg, project_name))
+
+ def assertNotInManifest(self, project_name, *args):
+ manifest_path = mozpath.join(self.env.topobjdir, 'android_eclipse', '%s.manifest' % project_name)
+ manifest = InstallManifest(manifest_path)
+ for arg in args:
+ self.assertNotIn(arg, manifest, '%s not in manifest for project %s' % (arg, project_name))
+
+ def test_manifest_main_manifest(self):
+ """Ensure we symlink manifest if asked to for main projects."""
+ self.env = self._consume('android_eclipse', AndroidEclipseBackend)
+ self.assertInManifest('main1', 'AndroidManifest.xml')
+
+ def test_manifest_res(self):
+ """Ensure we symlink res/ iff asked to."""
+ self.env = self._consume('android_eclipse', AndroidEclipseBackend)
+ self.assertInManifest('library1', 'res')
+ self.assertNotInManifest('library2', 'res')
+
+ def test_manifest_classpathentries(self):
+ """Ensure we symlink classpathentries correctly."""
+ self.env = self._consume('android_eclipse', AndroidEclipseBackend)
+ self.assertInManifest('main3', 'a/a', 'b', 'd/e')
+
+ def test_manifest_assets(self):
+ """Ensure we symlink assets/ iff asked to."""
+ self.env = self._consume('android_eclipse', AndroidEclipseBackend)
+ self.assertNotInManifest('main1', 'assets')
+ self.assertInManifest('main2', 'assets')
+
+ def test_manifest_extra_jars(self):
+ """Ensure we symlink extra jars iff asked to."""
+ self.env = self._consume('android_eclipse', AndroidEclipseBackend)
+ self.assertNotInManifest('main1', 'libs')
+ self.assertInManifest('main2', 'libs/extra.jar')
+
+
+if __name__ == '__main__':
+ main()
diff --git a/python/mozbuild/mozbuild/test/backend/test_recursivemake.py b/python/mozbuild/mozbuild/test/backend/test_recursivemake.py
index dd151c3c6e2a..91ea41d5e919 100644
--- a/python/mozbuild/mozbuild/test/backend/test_recursivemake.py
+++ b/python/mozbuild/mozbuild/test/backend/test_recursivemake.py
@@ -616,6 +616,39 @@ class TestRecursiveMakeBackend(BackendTester):
self.assertIn('JAR_MANIFEST := %s/jar.mn' % env.topsrcdir, lines)
+ def test_android_eclipse(self):
+ env = self._consume('android_eclipse', RecursiveMakeBackend)
+
+ with open(mozpath.join(env.topobjdir, 'backend.mk'), 'rb') as fh:
+ lines = fh.readlines()
+
+ lines = [line.rstrip() for line in lines]
+
+ # Dependencies first.
+ self.assertIn('ANDROID_ECLIPSE_PROJECT_main1: target1 target2', lines)
+ self.assertIn('ANDROID_ECLIPSE_PROJECT_main4: target3 target4', lines)
+
+ command_template = '\t$(call py_action,process_install_manifest,' + \
+ '--no-remove --no-remove-all-directory-symlinks ' + \
+ '--no-remove-empty-directories %s %s.manifest)'
+ # Commands second.
+ for project_name in ['main1', 'main2', 'library1', 'library2']:
+ stem = '%s/android_eclipse/%s' % (env.topobjdir, project_name)
+ self.assertIn(command_template % (stem, stem), lines)
+
+ # Projects declared in subdirectories.
+ with open(mozpath.join(env.topobjdir, 'subdir', 'backend.mk'), 'rb') as fh:
+ lines = fh.readlines()
+
+ lines = [line.rstrip() for line in lines]
+
+ self.assertIn('ANDROID_ECLIPSE_PROJECT_submain: subtarget1 subtarget2', lines)
+
+ for project_name in ['submain', 'sublibrary']:
+ # Destination and install manifest are relative to topobjdir.
+ stem = '%s/android_eclipse/%s' % (env.topobjdir, project_name)
+ self.assertIn(command_template % (stem, stem), lines)
+
if __name__ == '__main__':
main()