mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Bug 1300208 - Allow specifying multiple rust crates to mozbuild within the same FINAL_LIBRARY, r=froydnj
MozReview-Commit-ID: IIjV4Kg7wOv
This commit is contained in:
parent
eea6b5c9c8
commit
05bd5a1076
@ -21,6 +21,11 @@ def generate(args):
|
||||
else:
|
||||
raise Exception("File not found: %s" % arg)
|
||||
elif os.path.splitext(arg)[1] == conf.LIB_SUFFIX:
|
||||
# We want to skip static libraries with the name foo-rs-prelink
|
||||
# as they are individually linked for every final library, and
|
||||
# thus should not be included in the descriptor file
|
||||
if '-rs-prelink' in os.path.basename(arg):
|
||||
continue
|
||||
if os.path.exists(arg) or os.path.exists(arg + conf.LIBS_DESC_SUFFIX):
|
||||
desc['LIBS'].append(os.path.abspath(arg))
|
||||
else:
|
||||
|
@ -940,6 +940,30 @@ force-cargo-build:
|
||||
|
||||
$(RUST_LIBRARY_FILE): force-cargo-build
|
||||
endif # CARGO_FILE
|
||||
|
||||
ifdef RUST_PRELINK
|
||||
# Make target for building a prelinked rust library. This merges rust .rlibs
|
||||
# together into a single .a file which is used within the FINAL_LIBRARY.
|
||||
#
|
||||
# RUST_PRELINK_FLAGS, RUST_PRELINK_SRC, and RUST_PRELINK_DEPS are set in
|
||||
# recursivemake.py, and together tell rustc how to find the libraries to link
|
||||
# together, but we compute the optimization flags below
|
||||
|
||||
RUST_PRELINK_FLAGS += -g
|
||||
RUST_PRELINK_FLAGS += -C panic=abort
|
||||
|
||||
ifdef MOZ_DEBUG
|
||||
RUST_PRELINK_FLAGS += -C opt-level=1
|
||||
RUST_PRELINK_FLAGS += -C debug-assertions
|
||||
else
|
||||
RUST_PRELINK_FLAGS += -C opt-level=2
|
||||
RUST_PRELINK_FLAGS += -C lto
|
||||
endif
|
||||
|
||||
$(RUST_PRELINK): $(RUST_PRELINK_DEPS) $(RUST_PRELINK_SRC)
|
||||
$(REPORT_BUILD)
|
||||
$(RUSTC) -o $@ --crate-type staticlib --target $(RUST_TARGET) $(RUST_PRELINK_FLAGS) $(RUST_PRELINK_SRC)
|
||||
endif # RUST_PRELINK
|
||||
endif # MOZ_RUST
|
||||
|
||||
$(SOBJS):
|
||||
|
@ -1236,25 +1236,49 @@ class RecursiveMakeBackend(CommonBackend):
|
||||
# We have to link any Rust libraries after all intermediate static
|
||||
# libraries have been listed to ensure that the Rust libraries are
|
||||
# searched after the C/C++ objects that might reference Rust symbols.
|
||||
# Building Rust crates normally takes care of Rust->Rust linkage, but
|
||||
# we have to be careful: a savvy user might have specified that there
|
||||
# is a staticlib (that contains the Rust runtime) and several other
|
||||
# rlibs (which are plain archive files) to be linked into a given
|
||||
# library. We need to ensure that the staticlib comes after the
|
||||
# rlibs to ensure symbols are found correctly.
|
||||
if isinstance(obj, SharedLibrary) and any(isinstance(o, RustLibrary)
|
||||
for o in obj.linked_libraries):
|
||||
libs = [l for l in obj.linked_libraries if isinstance(l, RustLibrary)]
|
||||
def name_cmp(l1, l2):
|
||||
if l1.crate_type == 'staticlib':
|
||||
return 1
|
||||
if l2.crate_type == 'staticlib':
|
||||
return -1
|
||||
return cmp(l1.basename, l2.basename)
|
||||
libs.sort(cmp=name_cmp)
|
||||
for l in libs:
|
||||
relpath = pretty_relpath(l)
|
||||
backend_file.write('STATIC_LIBS += %s/%s\n' % (relpath, l.import_name))
|
||||
|
||||
def find_rlibs(obj):
|
||||
if isinstance(obj, RustLibrary):
|
||||
yield obj
|
||||
elif isinstance(obj, StaticLibrary) and not obj.no_expand_lib:
|
||||
for l in obj.linked_libraries:
|
||||
for rlib in find_rlibs(l):
|
||||
yield rlib
|
||||
|
||||
# Check if we have any rust libraries to prelink and include in our
|
||||
# final library. If we do, write out the RUST_PRELINK information
|
||||
rlibs = []
|
||||
if isinstance(obj, (SharedLibrary, StaticLibrary)):
|
||||
for l in obj.linked_libraries:
|
||||
rlibs += find_rlibs(l)
|
||||
if rlibs:
|
||||
prelink_libname = '%s/%s%s-rs-prelink%s' \
|
||||
% (relpath,
|
||||
obj.config.lib_prefix,
|
||||
obj.basename,
|
||||
obj.config.lib_suffix)
|
||||
backend_file.write('RUST_PRELINK := %s\n' % prelink_libname)
|
||||
backend_file.write_once('STATIC_LIBS += %s\n' % prelink_libname)
|
||||
|
||||
extern_crate_file = mozpath.join(
|
||||
obj.objdir, '%s-rs-prelink.rs' % obj.basename)
|
||||
with self._write_file(extern_crate_file) as f:
|
||||
f.write('// AUTOMATICALLY GENERATED. DO NOT EDIT.\n\n')
|
||||
for rlib in rlibs:
|
||||
f.write('extern crate %s;\n'
|
||||
% rlib.basename.replace('-', '_'))
|
||||
backend_file.write('RUST_PRELINK_SRC := %s\n' % extern_crate_file)
|
||||
|
||||
backend_file.write('RUST_PRELINK_FLAGS :=\n')
|
||||
backend_file.write('RUST_PRELINK_DEPS :=\n')
|
||||
for rlib in rlibs:
|
||||
rlib_relpath = pretty_relpath(rlib)
|
||||
backend_file.write('RUST_PRELINK_FLAGS += --extern %s=%s/%s\n'
|
||||
% (rlib.basename, rlib_relpath, rlib.import_name))
|
||||
backend_file.write('RUST_PRELINK_FLAGS += -L %s/%s\n'
|
||||
% (rlib_relpath, rlib.deps_path))
|
||||
backend_file.write('RUST_PRELINK_DEPS += %s/%s\n'
|
||||
% (rlib_relpath, rlib.import_name))
|
||||
|
||||
for lib in obj.linked_system_libs:
|
||||
if obj.KIND == 'target':
|
||||
|
@ -464,6 +464,7 @@ class RustLibrary(StaticLibrary):
|
||||
__slots__ = (
|
||||
'cargo_file',
|
||||
'crate_type',
|
||||
'deps_path',
|
||||
)
|
||||
|
||||
def __init__(self, context, basename, cargo_file, crate_type, **args):
|
||||
@ -474,23 +475,18 @@ class RustLibrary(StaticLibrary):
|
||||
# package names defined in Cargo.toml with underscores in actual
|
||||
# filenames. But we need to keep the basename consistent because
|
||||
# many other things in the build system depend on that.
|
||||
assert self.crate_type == 'staticlib'
|
||||
self.lib_name = '%s%s%s' % (
|
||||
context.config.lib_prefix,
|
||||
basename.replace('-', '_'),
|
||||
context.config.lib_suffix
|
||||
)
|
||||
assert self.crate_type == 'rlib'
|
||||
self.lib_name = 'lib%s.rlib' % basename.replace('-', '_')
|
||||
# cargo creates several directories and places its build artifacts
|
||||
# in those directories. The directory structure depends not only
|
||||
# on the target, but also what sort of build we are doing.
|
||||
rust_build_kind = 'release'
|
||||
if context.config.substs.get('MOZ_DEBUG'):
|
||||
rust_build_kind = 'debug'
|
||||
self.import_name = '%s/%s/%s' % (
|
||||
context.config.substs['RUST_TARGET'],
|
||||
rust_build_kind,
|
||||
self.lib_name,
|
||||
)
|
||||
build_dir = mozpath.join(context.config.substs['RUST_TARGET'],
|
||||
rust_build_kind)
|
||||
self.import_name = mozpath.join(build_dir, self.lib_name)
|
||||
self.deps_path = mozpath.join(build_dir, 'deps')
|
||||
|
||||
|
||||
class SharedLibrary(Library):
|
||||
|
@ -436,7 +436,7 @@ class TreeMetadataEmitter(LoggingMixin):
|
||||
context)
|
||||
|
||||
crate_type = crate_type[0]
|
||||
if crate_type != 'staticlib':
|
||||
if crate_type != 'rlib':
|
||||
raise SandboxValidationError(
|
||||
'crate-type %s is not permitted for %s' % (crate_type, libname),
|
||||
context)
|
||||
@ -659,17 +659,6 @@ class TreeMetadataEmitter(LoggingMixin):
|
||||
self._libs[libname].append(lib)
|
||||
self._linkage.append((context, lib, 'USE_LIBS'))
|
||||
|
||||
# Multiple staticlibs for a library means multiple copies
|
||||
# of the Rust runtime, which will result in linking errors
|
||||
# later on.
|
||||
if is_rust_library:
|
||||
staticlibs = [l for l in self._libs[libname]
|
||||
if isinstance(l, RustLibrary) and l.crate_type == 'staticlib']
|
||||
if len(staticlibs) > 1:
|
||||
raise SandboxValidationError(
|
||||
'Cannot have multiple Rust staticlibs in %s: %s' % (libname, ', '.join(l.basename for l in staticlibs)),
|
||||
context)
|
||||
|
||||
has_linkables = True
|
||||
|
||||
if lib_defines:
|
||||
|
@ -6,7 +6,7 @@ authors = [
|
||||
]
|
||||
|
||||
[lib]
|
||||
crate-type = ["staticlib"]
|
||||
crate-type = ["rlib"]
|
||||
|
||||
[dependencies]
|
||||
deep-crate = { version = "0.1.0", path = "the/depths" }
|
||||
|
@ -6,4 +6,4 @@ authors = [
|
||||
]
|
||||
|
||||
[lib]
|
||||
crate-type = ["staticlib"]
|
||||
crate-type = ["rlib"]
|
||||
|
@ -10,7 +10,7 @@ mp4parse-gtest = { path = "../../../../dom/media/gtest" }
|
||||
|
||||
[lib]
|
||||
path = "lib.rs"
|
||||
crate-type = ["staticlib"]
|
||||
crate-type = ["rlib"]
|
||||
test = false
|
||||
doctest = false
|
||||
bench = false
|
||||
|
@ -10,7 +10,7 @@ mp4parse_capi = { path = "../../../media/libstagefright/binding/mp4parse_capi" }
|
||||
|
||||
[lib]
|
||||
path = "lib.rs"
|
||||
crate-type = ["staticlib"]
|
||||
crate-type = ["rlib"]
|
||||
test = false
|
||||
doctest = false
|
||||
bench = false
|
||||
|
Loading…
Reference in New Issue
Block a user