Bug 1293253 - part 9 - handle {Host,}RustProgram objects in the recursivemake backend; r=chmanchester
authorNathan Froyd <froydnj@mozilla.com>
Mon, 28 Nov 2016 11:20:39 -0500
changeset 324486 27c257be4c2e18221ee679c48e342b0b5b0ca9ed
parent 324485 b3505dd036cfa0db0c3a2c2047c1b3b6b458566e
child 324487 09f249970fc319f7810d80886d34de54175abf8a
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewerschmanchester
bugs1293253
milestone53.0a1
Bug 1293253 - part 9 - handle {Host,}RustProgram objects in the recursivemake backend; r=chmanchester
python/mozbuild/mozbuild/backend/recursivemake.py
python/mozbuild/mozbuild/test/backend/common.py
python/mozbuild/mozbuild/test/backend/data/rust-programs/Cargo.toml
python/mozbuild/mozbuild/test/backend/data/rust-programs/moz.build
python/mozbuild/mozbuild/test/backend/test_recursivemake.py
--- a/python/mozbuild/mozbuild/backend/recursivemake.py
+++ b/python/mozbuild/mozbuild/backend/recursivemake.py
@@ -43,28 +43,30 @@ from ..frontend.data import (
     ExternalLibrary,
     FinalTargetFiles,
     FinalTargetPreprocessedFiles,
     GeneratedFile,
     GeneratedSources,
     HostDefines,
     HostLibrary,
     HostProgram,
+    HostRustProgram,
     HostSimpleProgram,
     HostSources,
     InstallationTarget,
     JARManifest,
     JavaJarData,
     Library,
     LocalInclude,
     ObjdirFiles,
     ObjdirPreprocessedFiles,
     PerSourceFlag,
     Program,
     RustLibrary,
+    RustProgram,
     SharedLibrary,
     SimpleProgram,
     Sources,
     StaticLibrary,
     TestManifest,
     VariablePassthru,
     XPIDLFile,
 )
@@ -530,16 +532,25 @@ class RecursiveMakeBackend(CommonBackend
            backend=' backend.mk' if obj.flags else '',
            script=obj.script,
            method=obj.method))
 
         elif isinstance(obj, JARManifest):
             self._no_skip['libs'].add(backend_file.relobjdir)
             backend_file.write('JAR_MANIFEST := %s\n' % obj.path.full_path)
 
+        elif isinstance(obj, RustProgram):
+            # Note that for these and host Rust programs, we don't need to
+            # bother with linked libraries, because Cargo will take care of
+            # all of that for us.
+            self._process_rust_program(obj, backend_file)
+
+        elif isinstance(obj, HostRustProgram):
+            self._process_host_rust_program(obj, backend_file)
+
         elif isinstance(obj, Program):
             self._process_program(obj.program, backend_file)
             self._process_linked_libraries(obj, backend_file)
 
         elif isinstance(obj, HostProgram):
             self._process_host_program(obj.program, backend_file)
             self._process_linked_libraries(obj, backend_file)
 
@@ -1029,16 +1040,33 @@ class RecursiveMakeBackend(CommonBackend
         ))
 
     def _process_program(self, program, backend_file):
         backend_file.write('PROGRAM = %s\n' % program)
 
     def _process_host_program(self, program, backend_file):
         backend_file.write('HOST_PROGRAM = %s\n' % program)
 
+    def _process_rust_program_base(self, obj, backend_file,
+                                   target_variable,
+                                   target_cargo_variable):
+        backend_file.write_once('CARGO_FILE := %s\n' % obj.cargo_file)
+        backend_file.write('%s += %s\n' % (target_variable, obj.location))
+        backend_file.write('%s += %s\n' % (target_cargo_variable, obj.name))
+
+    def _process_rust_program(self, obj, backend_file):
+        self._process_rust_program_base(obj, backend_file,
+                                        'RUST_PROGRAMS',
+                                        'RUST_CARGO_PROGRAMS')
+
+    def _process_host_rust_program(self, obj, backend_file):
+        self._process_rust_program_base(obj, backend_file,
+                                        'HOST_RUST_PROGRAMS',
+                                        'HOST_RUST_CARGO_PROGRAMS')
+
     def _process_simple_program(self, obj, backend_file):
         if obj.is_unit_test:
             backend_file.write('CPP_UNIT_TESTS += %s\n' % obj.program)
         else:
             backend_file.write('SIMPLE_PROGRAMS += %s\n' % obj.program)
 
     def _process_host_simple_program(self, program, backend_file):
         backend_file.write('HOST_SIMPLE_PROGRAMS += %s\n' % program)
--- a/python/mozbuild/mozbuild/test/backend/common.py
+++ b/python/mozbuild/mozbuild/test/backend/common.py
@@ -47,16 +47,27 @@ CONFIGS = defaultdict(lambda: {
         'defines': {},
         'non_global_defines': [],
         'substs': {
             'LIB_PREFIX': 'lib',
             'LIB_SUFFIX': 'a',
             'COMPILE_ENVIRONMENT': '1',
         },
     },
+    'rust-programs': {
+        'defines': {},
+        'non_global_defines': [],
+        'substs': {
+            'COMPILE_ENVIRONMENT': '1',
+            'RUST_TARGET': 'i686-pc-windows-msvc',
+            'RUST_HOST_TARGET': 'i686-pc-windows-msvc',
+            'BIN_SUFFIX': '.exe',
+            'HOST_BIN_SUFFIX': '.exe',
+        },
+    },
     'sources': {
         'defines': {},
         'non_global_defines': [],
         'substs': {
             'LIB_PREFIX': 'lib',
             'LIB_SUFFIX': 'a',
         },
     },
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/rust-programs/Cargo.toml
@@ -0,0 +1,10 @@
+[package]
+authors = ["nobody <nobody@mozilla.org>"]
+name = "testing"
+version = "0.0.1"
+
+[[bin]]
+name = "target"
+
+[[bin]]
+name = "host"
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/rust-programs/moz.build
@@ -0,0 +1,6 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+RUST_PROGRAMS += ['target']
+HOST_RUST_PROGRAMS += ['host']
--- a/python/mozbuild/mozbuild/test/backend/test_recursivemake.py
+++ b/python/mozbuild/mozbuild/test/backend/test_recursivemake.py
@@ -730,16 +730,33 @@ class TestRecursiveMakeBackend(BackendTe
         expected = [
             'LOCAL_INCLUDES += -I$(CURDIR)/bar/baz',
             'LOCAL_INCLUDES += -I$(CURDIR)/foo',
         ]
 
         found = [str for str in lines if str.startswith('LOCAL_INCLUDES')]
         self.assertEqual(found, expected)
 
+    def test_rust_programs(self):
+        """Test that {HOST_,}RUST_PROGRAMS are written to backend.mk correctly."""
+        env = self._consume('rust-programs', RecursiveMakeBackend)
+
+        backend_path = mozpath.join(env.topobjdir, 'backend.mk')
+        lines = [l.strip() for l in open(backend_path, 'rt').readlines()[2:]]
+
+        expected = [
+            'CARGO_FILE := %s/Cargo.toml' % env.topsrcdir,
+            'RUST_PROGRAMS += i686-pc-windows-msvc/release/target.exe',
+            'RUST_CARGO_PROGRAMS += target',
+            'HOST_RUST_PROGRAMS += i686-pc-windows-msvc/release/host.exe',
+            'HOST_RUST_CARGO_PROGRAMS += host',
+        ]
+
+        self.assertEqual(lines, expected)
+
     def test_final_target(self):
         """Test that FINAL_TARGET is written to backend.mk correctly."""
         env = self._consume('final_target', RecursiveMakeBackend)
 
         final_target_rule = "FINAL_TARGET = $(if $(XPI_NAME),$(DIST)/xpi-stage/$(XPI_NAME),$(DIST)/bin)$(DIST_SUBDIR:%=/%)"
         expected = dict()
         expected[env.topobjdir] = []
         expected[mozpath.join(env.topobjdir, 'both')] = [