Bug 1414370 - Emit ldflags in directories containing only rust compilation for the benefit of cargo. r=froydnj
authorChris Manchester <cmanchester@mozilla.com>
Fri, 03 Nov 2017 12:16:39 -0700
changeset 434922 82e2afb4d9046d7113ba0cdc19588a79575e84d5
parent 434921 f993b9f8f20c13aa55c5abc9d39a22c92f68bf3a
child 434923 b7990b68f2716889e1f1e030ee5b00578a419824
push id117
push userfmarier@mozilla.com
push dateTue, 28 Nov 2017 20:17:16 +0000
reviewersfroydnj
bugs1414370
milestone58.0a1
Bug 1414370 - Emit ldflags in directories containing only rust compilation for the benefit of cargo. r=froydnj MozReview-Commit-ID: 9AuU3mjKR8V
python/mozbuild/mozbuild/frontend/emitter.py
python/mozbuild/mozbuild/test/frontend/test_emitter.py
--- a/python/mozbuild/mozbuild/frontend/emitter.py
+++ b/python/mozbuild/mozbuild/frontend/emitter.py
@@ -127,16 +127,17 @@ class TreeMetadataEmitter(LoggingMixin):
             if isinstance(k, unicode):
                 k = k.encode('ascii')
             self.info[k] = v
 
         self._libs = OrderedDefaultDict(list)
         self._binaries = OrderedDict()
         self._compile_dirs = set()
         self._host_compile_dirs = set()
+        self._rust_compile_dirs = set()
         self._compile_flags = dict()
         self._linkage = []
         self._static_linking_shared = set()
         self._crate_verified_local = set()
         self._crate_directories = dict()
 
         # Keep track of external paths (third party build systems), starting
         # from what we run a subconfigure in. We'll eliminate some directories
@@ -769,19 +770,23 @@ class TreeMetadataEmitter(LoggingMixin):
         # Only emit sources if we have linkables defined in the same context.
         # Note the linkables are not emitted in this function, but much later,
         # after aggregation (because of e.g. USE_LIBS processing).
         if not (linkables or host_linkables):
             return
 
         # Avoid emitting compile flags for directories only containing rust
         # libraries. Emitted compile flags are only relevant to C/C++ sources
-        # for the time being.
+        # for the time being, however ldflags must be emitted for the benefit
+        # of cargo.
         if not all(isinstance(l, (RustLibrary)) for l in linkables):
             self._compile_dirs.add(context.objdir)
+        elif linkables:
+            self._rust_compile_dirs.add(context.objdir)
+
         if host_linkables and not all(isinstance(l, HostRustLibrary) for l in host_linkables):
             self._host_compile_dirs.add(context.objdir)
             # TODO: objdirs with only host things in them shouldn't need target
             # flags, but there's at least one Makefile.in (in
             # build/unix/elfhack) that relies on the value of LDFLAGS being
             # passed to one-off rules.
             self._compile_dirs.add(context.objdir)
 
@@ -1196,16 +1201,19 @@ class TreeMetadataEmitter(LoggingMixin):
             yield AndroidExtraPackages(context, android_extra_packages)
 
         if passthru.variables:
             yield passthru
 
         if context.objdir in self._compile_dirs:
             self._compile_flags[context.objdir] = computed_flags
             yield computed_link_flags
+        elif context.objdir in self._rust_compile_dirs:
+            yield computed_link_flags
+
         if context.objdir in self._host_compile_dirs:
             yield computed_host_flags
 
 
     def _create_substitution(self, cls, context, path):
         sub = cls(context)
         sub.input_path = '%s.in' % path.full_path
         sub.output_path = path.translated
--- a/python/mozbuild/mozbuild/test/frontend/test_emitter.py
+++ b/python/mozbuild/mozbuild/test/frontend/test_emitter.py
@@ -1260,18 +1260,18 @@ class TestEmitterBasic(unittest.TestCase
             self.read_topsrcdir(reader)
 
     def test_rust_library_dash_folding(self):
         '''Test that on-disk names of RustLibrary objects convert dashes to underscores.'''
         reader = self.reader('rust-library-dash-folding',
                              extra_substs=dict(RUST_TARGET='i686-pc-windows-msvc'))
         objs = self.read_topsrcdir(reader)
 
-        self.assertEqual(len(objs), 1)
-        lib = objs[0]
+        ldflags, lib = objs
+        self.assertIsInstance(ldflags, ComputedFlags)
         self.assertIsInstance(lib, RustLibrary)
         self.assertRegexpMatches(lib.lib_name, "random_crate")
         self.assertRegexpMatches(lib.import_name, "random_crate")
         self.assertRegexpMatches(lib.basename, "random-crate")
 
     def test_multiple_rust_libraries(self):
         '''Test that linking multiple Rust libraries throws an error'''
         reader = self.reader('multiple-rust-libraries',
@@ -1280,18 +1280,18 @@ class TestEmitterBasic(unittest.TestCase
              'Cannot link multiple Rust libraries'):
             self.read_topsrcdir(reader)
 
     def test_rust_library_features(self):
         '''Test that RustLibrary features are correctly emitted.'''
         reader = self.reader('rust-library-features',
                              extra_substs=dict(RUST_TARGET='i686-pc-windows-msvc'))
         objs = self.read_topsrcdir(reader)
-        self.assertEqual(len(objs), 1)
-        lib = objs[0]
+        ldflags, lib = objs
+        self.assertIsInstance(ldflags, ComputedFlags)
         self.assertIsInstance(lib, RustLibrary)
         self.assertEqual(lib.features, ['musthave', 'cantlivewithout'])
 
     def test_rust_library_duplicate_features(self):
         '''Test that duplicate RustLibrary features are rejected.'''
         reader = self.reader('rust-library-duplicate-features')
         with self.assertRaisesRegexp(SandboxValidationError,
              'features for .* should not contain duplicates'):
@@ -1361,18 +1361,19 @@ class TestEmitterBasic(unittest.TestCase
         self.assertRegexpMatches(objs[0].import_name, 'host_lib')
 
     def test_crate_dependency_path_resolution(self):
         '''Test recursive dependencies resolve with the correct paths.'''
         reader = self.reader('crate-dependency-path-resolution',
                              extra_substs=dict(RUST_TARGET='i686-pc-windows-msvc'))
         objs = self.read_topsrcdir(reader)
 
-        self.assertEqual(len(objs), 1)
-        self.assertIsInstance(objs[0], RustLibrary)
+        ldflags, lib = objs
+        self.assertIsInstance(ldflags, ComputedFlags)
+        self.assertIsInstance(lib, RustLibrary)
 
     def test_android_res_dirs(self):
         """Test that ANDROID_RES_DIRS works properly."""
         reader = self.reader('android-res-dirs')
         objs = self.read_topsrcdir(reader)
 
         self.assertEqual(len(objs), 1)
         self.assertIsInstance(objs[0], AndroidResDirs)