--- a/python/mozbuild/mozbuild/backend/tup.py
+++ b/python/mozbuild/mozbuild/backend/tup.py
@@ -84,17 +84,16 @@ class BackendTupfile(object):
self.outputs = set()
self.delayed_generated_files = []
self.delayed_installed_files = []
self.per_source_flags = defaultdict(list)
self.local_flags = defaultdict(list)
self.sources = defaultdict(list)
self.host_sources = defaultdict(list)
self.variables = {}
- self.rust_library = None
self.static_lib = None
self.shared_lib = None
self.programs = []
self.host_programs = []
self.host_library = None
self.exports = set()
self._default_group = default_group
@@ -257,21 +256,29 @@ class TupBackend(CommonBackend):
self._installed_idls = '$(MOZ_OBJ_ROOT)/<installed-idls>'
self._installed_files = '$(MOZ_OBJ_ROOT)/<installed-files>'
self._rust_libs = '$(MOZ_OBJ_ROOT)/<rust-libs>'
# The preprocessor including source-repo.h and buildid.h creates
# dependencies that aren't specified by moz.build and cause errors
# in Tup. Express these as a group dependency.
self._early_generated_files = '$(MOZ_OBJ_ROOT)/<early-generated-files>'
+ self._shlibs = '$(MOZ_OBJ_ROOT)/<shlibs>'
+ self._gtests = '$(MOZ_OBJ_ROOT)/<gtest>'
+ self._default_group = '$(MOZ_OBJ_ROOT)/<default>'
+
+ # The two rust libraries in the tree share many prerequisites, so we need
+ # to prune common dependencies and therefore build all rust from the same
+ # Tupfile.
+ self._rust_outputs = set()
+ self._rust_backend_file = self._get_backend_file('toolkit/library/rust')
+
self._built_in_addons = set()
self._built_in_addons_file = 'dist/bin/browser/chrome/browser/content/browser/built_in_addons.json'
- self._shlibs = '$(MOZ_OBJ_ROOT)/<shlibs>'
- self._default_group = '$(MOZ_OBJ_ROOT)/<default>'
def _get_mozconfig_env(self, config):
env = {}
loader = MozconfigLoader(config.topsrcdir)
mozconfig = loader.read_mozconfig(config.substs['MOZCONFIG'])
make_extra = mozconfig['make_extra'] or []
env = {}
for line in make_extra:
@@ -327,18 +334,19 @@ class TupBackend(CommonBackend):
def _lib_paths(self, objdir, libs):
return [mozpath.relpath(mozpath.join(l.objdir, l.import_name), objdir)
for l in libs]
def _gen_shared_library(self, backend_file):
shlib = backend_file.shared_lib
- if backend_file.objdir.endswith('gtest') and shlib.name == 'libxul.so':
- return
+ output_group = self._shlibs
+ if 'toolkit/library/gtest' in backend_file.objdir:
+ output_group = self._gtests
if shlib.cxx_link:
mkshlib = (
[backend_file.environment.substs['CXX']] +
backend_file.local_flags['CXX_LDFLAGS']
)
else:
mkshlib = (
@@ -387,25 +395,25 @@ class TupBackend(CommonBackend):
[backend_file.environment.substs['OS_LIBS']] +
os_libs
)
backend_file.rule(
cmd=cmd,
inputs=inputs,
extra_inputs=extra_inputs,
outputs=[shlib.lib_name],
- output_group=self._shlibs,
+ output_group=output_group,
display='LINK %o'
)
backend_file.symlink_rule(mozpath.join(backend_file.objdir,
shlib.lib_name),
output=mozpath.join(self.environment.topobjdir,
shlib.install_target,
shlib.lib_name),
- output_group=self._shlibs)
+ output_group=output_group)
def _gen_programs(self, backend_file):
for p in backend_file.programs:
self._gen_program(backend_file, p)
def _gen_program(self, backend_file, prog):
cc_or_cxx = 'CXX' if prog.cxx_link else 'CC'
objs, _, shared_libs, os_libs, static_libs = self._expand_libs(prog)
@@ -580,17 +588,17 @@ class TupBackend(CommonBackend):
self._process_computed_flags(obj, backend_file)
elif isinstance(obj, (Sources, GeneratedSources)):
backend_file.sources[obj.canonical_suffix].extend(obj.files)
elif isinstance(obj, HostSources):
backend_file.host_sources[obj.canonical_suffix].extend(obj.files)
elif isinstance(obj, VariablePassthru):
backend_file.variables = obj.variables
elif isinstance(obj, RustLibrary):
- backend_file.rust_library = obj
+ self._gen_rust_rules(obj, backend_file)
elif isinstance(obj, StaticLibrary):
backend_file.static_lib = obj
elif isinstance(obj, SharedLibrary):
backend_file.shared_lib = obj
elif isinstance(obj, (HostProgram, HostSimpleProgram)):
backend_file.host_programs.append(obj)
elif isinstance(obj, HostLibrary):
backend_file.host_library = obj
@@ -618,18 +626,17 @@ class TupBackend(CommonBackend):
for objdir, backend_file in sorted(self._backend_files.items()):
backend_file.gen_sources_rules([self._installed_files])
for var, gen_method in ((backend_file.shared_lib, self._gen_shared_library),
(backend_file.static_lib and backend_file.static_lib.no_expand_lib,
self._gen_static_library),
(backend_file.programs, self._gen_programs),
(backend_file.host_programs, self._gen_host_programs),
- (backend_file.host_library, self._gen_host_library),
- (backend_file.rust_library, self._gen_rust)):
+ (backend_file.host_library, self._gen_host_library)):
if var:
backend_file.export_shell()
gen_method(backend_file)
for obj in backend_file.delayed_generated_files:
self._process_generated_file(backend_file, obj)
for path, output, output_group in backend_file.delayed_installed_files:
backend_file.symlink_rule(path, output=output, output_group=output_group)
with self._write_file(fh=backend_file):
@@ -674,18 +681,17 @@ class TupBackend(CommonBackend):
'--target=%s' % self.environment.substs['RUST_TARGET'],
]
if obj.features:
cargo_flags += [
'--features', ' '.join(obj.features)
]
return cargo_flags
- def _get_cargo_env(self, backend_file):
- lib = backend_file.rust_library
+ def _get_cargo_env(self, lib, backend_file):
env = {
'CARGO_TARGET_DIR': mozpath.normpath(mozpath.join(lib.objdir,
lib.target_dir)),
'RUSTC': self.environment.substs['RUSTC'],
'MOZ_SRC': self.environment.topsrcdir,
'MOZ_DIST': self.environment.substs['DIST'],
'LIBCLANG_PATH': self.environment.substs['MOZ_LIBCLANG_PATH'],
'CLANG_PATH': self.environment.substs['MOZ_CLANG_PATH'],
@@ -785,41 +791,40 @@ class TupBackend(CommonBackend):
header = 'RUSTC'
else:
inputs.add(invocation['program'])
header = 'RUN'
invocation['full-deps'] = set(inputs)
invocation['full-deps'].update(invocation['outputs'])
- backend_file.rule(
- command,
- inputs=sorted(inputs),
- outputs=outputs,
- output_group=self._rust_libs,
- extra_inputs=[self._installed_files],
- display='%s %s' % (header, display_name(invocation)),
- )
+ output_key = tuple(outputs)
+ if output_key not in self._rust_outputs:
+ self._rust_outputs.add(output_key)
+ self._rust_backend_file.rule(
+ command,
+ inputs=sorted(inputs),
+ outputs=outputs,
+ output_group=self._rust_libs,
+ extra_inputs=[self._installed_files],
+ display='%s %s' % (header, display_name(invocation)),
+ )
- for dst, link in invocation['links'].iteritems():
- backend_file.symlink_rule(link, dst, self._rust_libs)
+ for dst, link in invocation['links'].iteritems():
+ self._rust_outputs.add(output_key)
+ self._rust_backend_file.symlink_rule(link, dst,
+ self._rust_libs)
for val in enumerate(invocations):
_process(*val)
- def _gen_rust(self, backend_file):
- # TODO (bug 1468547): The gtest rust library depends on many of the same
- # libraries as the main rust library, so we'll need to handle these all
- # at once in order to build the gtest rust library.
- if 'toolkit/library/gtest' in backend_file.objdir:
- return
-
- cargo_flags = self._get_cargo_flags(backend_file.rust_library)
- cargo_env = self._get_cargo_env(backend_file)
+ def _gen_rust_rules(self, obj, backend_file):
+ cargo_flags = self._get_cargo_flags(obj)
+ cargo_env = self._get_cargo_env(obj, backend_file)
output_lines = []
def accumulate_output(line):
output_lines.append(line)
cargo_status = self._cmd.run_process(
[self.environment.substs['CARGO'], 'build'] + cargo_flags,
line_handler=accumulate_output,