mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 06:43:32 +00:00
Bug 1594867 - Add moz.build/backend bits to specify files that should be built as a sandboxed wasm library r=firefox-build-system-reviewers,mshal
Add backend stuff to build sandboxed wasm libraries. (Don't actually update any moz.build files to consume this yet.) Differential Revision: https://phabricator.services.mozilla.com/D54152 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
dbe0cfcbc5
commit
d5eb7d0ea5
@ -195,6 +195,10 @@ HOST_CXXFLAGS = $(COMPUTED_HOST_CXXFLAGS) $(_HOST_DEPEND_CFLAGS)
|
||||
HOST_C_LDFLAGS = $(COMPUTED_HOST_C_LDFLAGS)
|
||||
HOST_CXX_LDFLAGS = $(COMPUTED_HOST_CXX_LDFLAGS)
|
||||
|
||||
WASM_CFLAGS = $(COMPUTED_WASM_CFLAGS) $(PGO_CFLAGS) $(_DEPEND_CFLAGS) $(MK_COMPILE_DEFINES)
|
||||
WASM_CXXFLAGS = $(COMPUTED_WASM_CXXFLAGS) $(PGO_CFLAGS) $(_DEPEND_CFLAGS) $(MK_COMPILE_DEFINES)
|
||||
WASM_LDFLAGS = $(COMPUTED_WASM_LDFLAGS)
|
||||
|
||||
ifdef MOZ_LTO
|
||||
ifeq (Darwin,$(OS_TARGET))
|
||||
# When linking on macOS, debug info is not linked along with the final binary,
|
||||
@ -230,6 +234,9 @@ color_flags_vars := \
|
||||
COMPILE_CMFLAGS \
|
||||
COMPILE_CMMFLAGS \
|
||||
LDFLAGS \
|
||||
WASM_LDFLAGS \
|
||||
WASM_CFLAGS \
|
||||
WASM_CXXFLAGS \
|
||||
$(NULL)
|
||||
|
||||
ifdef MACH_STDOUT_ISATTY
|
||||
|
@ -178,20 +178,22 @@ endif
|
||||
|
||||
ifdef COMPILE_ENVIRONMENT
|
||||
ifndef TARGETS
|
||||
TARGETS = $(LIBRARY) $(SHARED_LIBRARY) $(PROGRAM) $(SIMPLE_PROGRAMS) $(HOST_PROGRAM) $(HOST_SIMPLE_PROGRAMS) $(HOST_SHARED_LIBRARY)
|
||||
TARGETS = $(LIBRARY) $(SHARED_LIBRARY) $(PROGRAM) $(SIMPLE_PROGRAMS) $(HOST_PROGRAM) $(HOST_SIMPLE_PROGRAMS) $(HOST_SHARED_LIBRARY) $(WASM_LIBRARY)
|
||||
endif
|
||||
|
||||
COBJS = $(notdir $(CSRCS:.c=.$(OBJ_SUFFIX)))
|
||||
CWASMOBJS = $(notdir $(WASM_CSRCS:.c=.$(WASM_OBJ_SUFFIX)))
|
||||
SOBJS = $(notdir $(SSRCS:.S=.$(OBJ_SUFFIX)))
|
||||
# CPPSRCS can have different extensions (eg: .cpp, .cc)
|
||||
CPPOBJS = $(notdir $(addsuffix .$(OBJ_SUFFIX),$(basename $(CPPSRCS))))
|
||||
CPPWASMOBJS = $(notdir $(addsuffix .$(WASM_OBJ_SUFFIX),$(basename $(WASM_CPPSRCS))))
|
||||
CMOBJS = $(notdir $(CMSRCS:.m=.$(OBJ_SUFFIX)))
|
||||
CMMOBJS = $(notdir $(CMMSRCS:.mm=.$(OBJ_SUFFIX)))
|
||||
# ASFILES can have different extensions (.s, .asm)
|
||||
ASOBJS = $(notdir $(addsuffix .$(OBJ_SUFFIX),$(basename $(ASFILES))))
|
||||
RS_STATICLIB_CRATE_OBJ = $(addprefix lib,$(notdir $(RS_STATICLIB_CRATE_SRC:.rs=.$(LIB_SUFFIX))))
|
||||
ifndef OBJS
|
||||
_OBJS = $(COBJS) $(SOBJS) $(CPPOBJS) $(CMOBJS) $(CMMOBJS) $(ASOBJS)
|
||||
_OBJS = $(COBJS) $(SOBJS) $(CPPOBJS) $(CMOBJS) $(CMMOBJS) $(ASOBJS) $(CWASMOBJS) $(CPPWASMOBJS)
|
||||
OBJS = $(strip $(_OBJS))
|
||||
endif
|
||||
|
||||
@ -214,8 +216,11 @@ SIMPLE_PROGRAMS :=
|
||||
HOST_SHARED_LIBRARY :=
|
||||
HOST_PROGRAM :=
|
||||
HOST_SIMPLE_PROGRAMS :=
|
||||
WASM_LIBRARY :=
|
||||
endif
|
||||
|
||||
WASM_ARCHIVE = $(addsuffix .$(WASM_OBJ_SUFFIX),$(WASM_LIBRARY))
|
||||
|
||||
ALL_TRASH = \
|
||||
$(GARBAGE) $(TARGETS) $(OBJS) $(PROGOBJS) LOGS TAGS a.out \
|
||||
$(filter-out $(ASFILES),$(OBJS:.$(OBJ_SUFFIX)=.s)) $(OBJS:.$(OBJ_SUFFIX)=.ii) \
|
||||
@ -227,7 +232,7 @@ ALL_TRASH = \
|
||||
$(PROGRAM:$(BIN_SUFFIX)=.exp) $(SIMPLE_PROGRAMS:$(BIN_SUFFIX)=.exp) \
|
||||
$(PROGRAM:$(BIN_SUFFIX)=.lib) $(SIMPLE_PROGRAMS:$(BIN_SUFFIX)=.lib) \
|
||||
$(SIMPLE_PROGRAMS:$(BIN_SUFFIX)=.$(OBJ_SUFFIX)) \
|
||||
$(wildcard gts_tmp_*) $(LIBRARY:%.a=.%.timestamp)
|
||||
$(WASM_ARCHIVE) $(wildcard gts_tmp_*) $(LIBRARY:%.a=.%.timestamp)
|
||||
ALL_TRASH_DIRS = \
|
||||
$(GARBAGE_DIRS) /no-such-file
|
||||
|
||||
@ -410,7 +415,7 @@ compile:: host target
|
||||
|
||||
host:: $(HOST_OBJS) $(HOST_PROGRAM) $(HOST_SIMPLE_PROGRAMS) $(HOST_RUST_PROGRAMS) $(HOST_RUST_LIBRARY_FILE) $(HOST_SHARED_LIBRARY)
|
||||
|
||||
target:: $(filter-out $(MOZBUILD_NON_DEFAULT_TARGETS),$(LIBRARY) $(SHARED_LIBRARY) $(PROGRAM) $(SIMPLE_PROGRAMS) $(RUST_LIBRARY_FILE) $(RUST_PROGRAMS))
|
||||
target:: $(filter-out $(MOZBUILD_NON_DEFAULT_TARGETS),$(LIBRARY) $(SHARED_LIBRARY) $(PROGRAM) $(SIMPLE_PROGRAMS) $(RUST_LIBRARY_FILE) $(RUST_PROGRAMS) $(WASM_LIBRARY))
|
||||
|
||||
ifndef LIBRARY
|
||||
ifdef OBJS
|
||||
@ -476,7 +481,7 @@ ifneq (,$(filter target,$(MAKECMDGOALS)))
|
||||
ifdef GNU_CC
|
||||
# Force rebuilding libraries and programs in both passes because each
|
||||
# pass uses different object files.
|
||||
$(PROGRAM) $(SHARED_LIBRARY) $(LIBRARY): FORCE
|
||||
$(PROGRAM) $(SHARED_LIBRARY) $(LIBRARY) $(WASM_LIBRARY): FORCE
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
@ -630,6 +635,15 @@ $(LIBRARY): $(OBJS) $(STATIC_LIBS) $(EXTRA_DEPS) $(GLOBAL_DEPS)
|
||||
$(RM) $(REAL_LIBRARY)
|
||||
$(AR) $(AR_FLAGS) $($@_$(OBJS_VAR_SUFFIX))
|
||||
|
||||
$(WASM_ARCHIVE): $(CWASMOBJS) $(CPPWASMOBJS) $(STATIC_LIBS) $(EXTRA_DEPS) $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD_VERBOSE)
|
||||
$(RM) $(WASM_LIBRARY).$(WASM_OBJ_SUFFIX)
|
||||
$(WASM_CXX) $(OUTOPTION)$@ -Wl,--export-all $(WASM_LDFLAGS) $(CWASMOBJS) $(CPPWASMOBJS)
|
||||
$(WASM_LIBRARY): $(WASM_LIBRARY).$(WASM_OBJ_SUFFIX)
|
||||
$(REPORT_BUILD)
|
||||
$(RM) $(WASM_LIBRARY)
|
||||
$(LUCETC) --bindings $(topsrcdir)/third_party/rust/lucet-wasi/bindings.json $(WASM_LIBRARY).$(WASM_OBJ_SUFFIX) --opt-level 2 -o $(WASM_LIBRARY)
|
||||
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
# Import libraries are created by the rules creating shared libraries.
|
||||
# The rules to copy them to $(DIST)/lib depend on $(IMPORT_LIBRARY),
|
||||
@ -699,6 +713,7 @@ $(basename $3$(notdir $1)).$2: $1 $$(call mkdir_deps,$$(MDDEPDIR))
|
||||
endef
|
||||
$(foreach f,$(CSRCS) $(SSRCS) $(CPPSRCS) $(CMSRCS) $(CMMSRCS) $(ASFILES),$(eval $(call src_objdep,$(f),$(OBJ_SUFFIX))))
|
||||
$(foreach f,$(HOST_CSRCS) $(HOST_CPPSRCS) $(HOST_CMSRCS) $(HOST_CMMSRCS),$(eval $(call src_objdep,$(f),$(_OBJ_SUFFIX),host_)))
|
||||
$(foreach f,$(WASM_CSRCS) $(WASM_CPPSRCS),$(eval $(call src_objdep,$(f),wasm)))
|
||||
|
||||
# The Rust compiler only outputs library objects, and so we need different
|
||||
# mangling to generate dependency rules for it.
|
||||
@ -730,6 +745,10 @@ $(COBJS):
|
||||
$(REPORT_BUILD_VERBOSE)
|
||||
$(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $($(notdir $<)_FLAGS) $<
|
||||
|
||||
$(CWASMOBJS):
|
||||
$(REPORT_BUILD_VERBOSE)
|
||||
$(WASM_CC) $(OUTOPTION)$@ -c $(WASM_CFLAGS) $($(notdir $<)_FLAGS) $<
|
||||
|
||||
ifdef ASFILES
|
||||
# The AS_DASH_C_FLAG is needed cause not all assemblers (Solaris) accept
|
||||
# a '-c' flag.
|
||||
@ -786,6 +805,11 @@ $(CPPOBJS):
|
||||
$(call BUILDSTATUS,OBJECT_FILE $@)
|
||||
$(CCC) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS) $($(notdir $<)_FLAGS) $<
|
||||
|
||||
$(CPPWASMOBJS):
|
||||
$(REPORT_BUILD_VERBOSE)
|
||||
$(call BUILDSTATUS,OBJECT_FILE $@)
|
||||
$(WASM_CXX) $(OUTOPTION)$@ -c $(WASM_CXXFLAGS) $($(notdir $<)_FLAGS) $<
|
||||
|
||||
$(CMMOBJS):
|
||||
$(REPORT_BUILD_VERBOSE)
|
||||
$(CCC) -o $@ -c $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $($(notdir $<)_FLAGS) $<
|
||||
@ -1276,6 +1300,7 @@ FREEZE_VARIABLES = \
|
||||
EXPORTS \
|
||||
DIRS \
|
||||
LIBRARY \
|
||||
WASM_LIBRARY \
|
||||
MODULE \
|
||||
$(NULL)
|
||||
|
||||
|
@ -247,6 +247,7 @@ add_old_configure_assignment('OBJ_SUFFIX', library_name_info.obj.suffix)
|
||||
set_config('IMPORT_LIB_SUFFIX', library_name_info.import_lib.suffix)
|
||||
set_define('MOZ_DLL_PREFIX', depends(library_name_info.dll.prefix)(lambda s: '"%s"' % s))
|
||||
set_define('MOZ_DLL_SUFFIX', depends(library_name_info.dll.suffix)(lambda s: '"%s"' % s))
|
||||
set_config('WASM_OBJ_SUFFIX', 'wasm')
|
||||
|
||||
include(include_project_configure)
|
||||
|
||||
|
@ -36,6 +36,7 @@ from mozbuild.frontend.data import (
|
||||
IPDLCollection,
|
||||
LocalizedPreprocessedFiles,
|
||||
LocalizedFiles,
|
||||
SandboxedWasmLibrary,
|
||||
SharedLibrary,
|
||||
StaticLibrary,
|
||||
UnifiedSources,
|
||||
@ -248,7 +249,8 @@ class CommonBackend(BuildBackend):
|
||||
no_pgo_objs.append(o)
|
||||
|
||||
def expand(lib, recurse_objs, system_libs):
|
||||
if isinstance(lib, (HostLibrary, StaticLibrary)):
|
||||
if isinstance(lib, (HostLibrary, StaticLibrary,
|
||||
SandboxedWasmLibrary)):
|
||||
if lib.no_expand_lib:
|
||||
static_libs.append(lib)
|
||||
recurse_objs = False
|
||||
@ -271,9 +273,11 @@ class CommonBackend(BuildBackend):
|
||||
|
||||
add_objs(input_bin)
|
||||
|
||||
system_libs = not isinstance(input_bin, (HostLibrary, StaticLibrary))
|
||||
system_libs = not isinstance(input_bin, (HostLibrary, StaticLibrary,
|
||||
SandboxedWasmLibrary))
|
||||
for lib in input_bin.linked_libraries:
|
||||
if isinstance(lib, (HostLibrary, StaticLibrary)):
|
||||
if isinstance(lib, (HostLibrary, StaticLibrary,
|
||||
SandboxedWasmLibrary)):
|
||||
expand(lib, True, system_libs)
|
||||
elif isinstance(lib, SharedLibrary):
|
||||
if lib not in seen_libs:
|
||||
|
@ -64,12 +64,15 @@ from ..frontend.data import (
|
||||
HostSharedLibrary,
|
||||
RustProgram,
|
||||
RustTests,
|
||||
SandboxedWasmLibrary,
|
||||
SharedLibrary,
|
||||
SimpleProgram,
|
||||
Sources,
|
||||
StaticLibrary,
|
||||
TestManifest,
|
||||
VariablePassthru,
|
||||
WasmGeneratedSources,
|
||||
WasmSources,
|
||||
XPIDLModule,
|
||||
)
|
||||
from ..util import (
|
||||
@ -513,6 +516,30 @@ class RecursiveMakeBackend(MakeBackend):
|
||||
backend_file.write('%s += %s\n' % (var, p))
|
||||
self._compile_graph[mozpath.join(
|
||||
backend_file.relobjdir, 'host-objects')]
|
||||
elif isinstance(obj, (WasmSources, WasmGeneratedSources)):
|
||||
suffix_map = {
|
||||
'.c': 'WASM_CSRCS',
|
||||
'.cpp': 'WASM_CPPSRCS',
|
||||
}
|
||||
variables = [suffix_map[obj.canonical_suffix]]
|
||||
if isinstance(obj, WasmGeneratedSources):
|
||||
variables.append('GARBAGE')
|
||||
base = backend_file.objdir
|
||||
cls = ObjDirPath
|
||||
prefix = '!'
|
||||
else:
|
||||
base = backend_file.srcdir
|
||||
cls = SourcePath
|
||||
prefix = ''
|
||||
for f in sorted(obj.files):
|
||||
p = self._pretty_path(
|
||||
cls(obj._context, prefix + mozpath.relpath(f, base)),
|
||||
backend_file,
|
||||
)
|
||||
for var in variables:
|
||||
backend_file.write('%s += %s\n' % (var, p))
|
||||
self._compile_graph[mozpath.join(
|
||||
backend_file.relobjdir, 'target-objects')]
|
||||
elif isinstance(obj, VariablePassthru):
|
||||
# Sorted so output is consistent and we don't bump mtimes.
|
||||
for k, v in sorted(obj.variables.items()):
|
||||
@ -624,6 +651,10 @@ class RecursiveMakeBackend(MakeBackend):
|
||||
self._process_static_library(obj, backend_file)
|
||||
self._process_linked_libraries(obj, backend_file)
|
||||
|
||||
elif isinstance(obj, SandboxedWasmLibrary):
|
||||
self._process_sandboxed_wasm_library(obj, backend_file)
|
||||
self._process_linked_libraries(obj, backend_file)
|
||||
|
||||
elif isinstance(obj, HostLibrary):
|
||||
self._process_linked_libraries(obj, backend_file)
|
||||
|
||||
@ -1280,6 +1311,9 @@ class RecursiveMakeBackend(MakeBackend):
|
||||
if libdef.no_expand_lib:
|
||||
backend_file.write('NO_EXPAND_LIBS := 1\n')
|
||||
|
||||
def _process_sandboxed_wasm_library(self, libdef, backend_file):
|
||||
backend_file.write('WASM_LIBRARY := %s\n' % libdef.lib_name)
|
||||
|
||||
def _process_rust_library(self, libdef, backend_file):
|
||||
backend_file.write_once('%s := %s\n' % (libdef.LIB_FILE_VAR, libdef.import_name))
|
||||
backend_file.write_once('CARGO_FILE := $(srcdir)/Cargo.toml\n')
|
||||
@ -1353,15 +1387,18 @@ class RecursiveMakeBackend(MakeBackend):
|
||||
# accommodates clang-plugin, where we would otherwise pass an
|
||||
# incorrect list file format to the host compiler as well as when
|
||||
# creating an archive with AR, which doesn't understand list files.
|
||||
if (objs == obj.objs and not isinstance(obj, (HostLibrary, StaticLibrary)) or
|
||||
isinstance(obj, StaticLibrary) and obj.no_expand_lib):
|
||||
if (objs == obj.objs and not isinstance(obj, (HostLibrary, StaticLibrary,
|
||||
SandboxedWasmLibrary)) or
|
||||
isinstance(obj, (StaticLibrary, SandboxedWasmLibrary)) and
|
||||
obj.no_expand_lib):
|
||||
backend_file.write_once('%s_OBJS := %s\n' % (obj.name,
|
||||
objs_ref))
|
||||
if profile_gen_objs:
|
||||
backend_file.write_once('%s_PGO_OBJS := %s\n' % (obj.name,
|
||||
pgo_objs_ref))
|
||||
write_obj_deps(obj_target, objs_ref, pgo_objs_ref)
|
||||
elif not isinstance(obj, (HostLibrary, StaticLibrary)):
|
||||
elif not isinstance(obj, (HostLibrary, StaticLibrary,
|
||||
SandboxedWasmLibrary)):
|
||||
list_file_path = '%s.list' % obj.name.replace('.', '_')
|
||||
list_file_ref = self._make_list_file(obj.KIND, obj.objdir, objs,
|
||||
list_file_path)
|
||||
|
@ -448,19 +448,20 @@ class TargetCompileFlags(BaseCompileFlags):
|
||||
"""Base class that encapsulates some common logic between CompileFlags and
|
||||
WasmCompileFlags.
|
||||
"""
|
||||
def __init__(self, context, prefix='', additionally=()):
|
||||
def __init__(self, context, prefix='', additionally=(), instead={}):
|
||||
# `prefix` is a string to be prepended to all dest_var names.
|
||||
# `additionally` is a sequence of (flat, default, dest_vars) to be added
|
||||
# to the flag_variables tuple.
|
||||
# `instead` is a string-to-string map that maps base dest_var names to
|
||||
# replacement names; e.g., if instead={'FOO':'BAR'}, then 'FOO' is
|
||||
# replaced with 'BAR' wherever it would occur in a dest_var.
|
||||
main_src_dir = mozpath.dirname(context.main_path)
|
||||
self._context = context
|
||||
|
||||
self.flag_variables = tuple(list(additionally) + [
|
||||
(flag, default, tuple(prefix + dest_var for dest_var in dest_vars))
|
||||
(flag, default, tuple(set(instead.get(prefix + dest_var, prefix + dest_var)
|
||||
for dest_var in dest_vars)))
|
||||
for flag, default, dest_vars in (
|
||||
('STL', context.config.substs.get('STL_FLAGS'),
|
||||
('CXXFLAGS',)),
|
||||
('DEFINES', None, ('CXXFLAGS', 'CFLAGS')),
|
||||
('LIBRARY_DEFINES', None, ('CXXFLAGS', 'CFLAGS')),
|
||||
('BASE_INCLUDES',
|
||||
['-I%s' % main_src_dir, '-I%s' % context.objdir],
|
||||
@ -550,6 +551,9 @@ class TargetCompileFlags(BaseCompileFlags):
|
||||
class CompileFlags(TargetCompileFlags):
|
||||
def __init__(self, context):
|
||||
TargetCompileFlags.__init__(self, context, prefix='', additionally=(
|
||||
('DEFINES', None, ('CXXFLAGS', 'CFLAGS')),
|
||||
('STL', context.config.substs.get('STL_FLAGS'),
|
||||
('CXXFLAGS',)),
|
||||
('VISIBILITY', context.config.substs.get('VISIBILITY_FLAGS'),
|
||||
('CXXFLAGS', 'CFLAGS')),
|
||||
('MOZ_HARDENING_CFLAGS',
|
||||
@ -574,9 +578,19 @@ class CompileFlags(TargetCompileFlags):
|
||||
class WasmFlags(TargetCompileFlags):
|
||||
def __init__(self, context):
|
||||
TargetCompileFlags.__init__(
|
||||
self, context, prefix='WASM_', additionally=tuple(
|
||||
(name, context.config.substs.get(name), (name,))
|
||||
for name in ('WASM_CFLAGS', 'WASM_CXXFLAGS', 'WASM_LDFLAGS')))
|
||||
self, context, prefix='WASM_', additionally=(
|
||||
tuple(
|
||||
(name, context.config.substs.get(name), (name,))
|
||||
for name in ('WASM_CFLAGS', 'WASM_CXXFLAGS', 'WASM_LDFLAGS')) +
|
||||
(('WASM_DEFINES', None, ('WASM_CFLAGS', 'WASM_CXXFLAGS')),
|
||||
('MOZBUILD_WASM_CFLAGS', None, ('WASM_CFLAGS',)),
|
||||
('MOZBUILD_WASM_CXXFLAGS', None, ('WASM_CXXFLAGS',)))),
|
||||
# Unlike target/host compilation, we don't distinguish between
|
||||
# LDFLAGS for C and C++.
|
||||
instead={
|
||||
'WASM_C_LDFLAGS': 'WASM_LDFLAGS',
|
||||
'WASM_CXX_LDFLAGS': 'WASM_LDFLAGS',
|
||||
})
|
||||
|
||||
|
||||
class FinalTargetValue(ContextDerivedValue, unicode):
|
||||
@ -1641,6 +1655,10 @@ VARIABLES = {
|
||||
with the host compiler.
|
||||
"""),
|
||||
|
||||
'WASM_SOURCES': (ContextDerivedTypedList(Path, StrictOrderingOnAppendList), list,
|
||||
"""Source code files to compile with the wasm compiler.
|
||||
"""),
|
||||
|
||||
'HOST_LIBRARY_NAME': (unicode, unicode,
|
||||
"""Name of target library generated when cross compiling.
|
||||
"""),
|
||||
@ -1671,6 +1689,11 @@ VARIABLES = {
|
||||
Implies FORCE_SHARED_LIB.
|
||||
"""),
|
||||
|
||||
'SANDBOXED_WASM_LIBRARY_NAME': (
|
||||
unicode, unicode,
|
||||
"""The name of the static sandboxed wasm library generated for a directory.
|
||||
"""),
|
||||
|
||||
'SHARED_LIBRARY_OUTPUT_CATEGORY': (unicode, unicode,
|
||||
"""The output category for this context's shared library. If set this will
|
||||
correspond to the build command that will build this shared library, and
|
||||
@ -2234,6 +2257,11 @@ VARIABLES = {
|
||||
appear in the moz.build file.
|
||||
"""),
|
||||
|
||||
'WASM_DEFINES': (InitializedDefines, dict,
|
||||
"""Dictionary of compiler defines to declare for wasm compilation.
|
||||
See ``DEFINES`` for specifics.
|
||||
"""),
|
||||
|
||||
'CMFLAGS': (List, list,
|
||||
"""Flags passed to the Objective-C compiler for all of the Objective-C
|
||||
source files declared in this directory.
|
||||
|
@ -242,6 +242,10 @@ class HostDefines(BaseDefines):
|
||||
pass
|
||||
|
||||
|
||||
class WasmDefines(BaseDefines):
|
||||
pass
|
||||
|
||||
|
||||
class WebIDLCollection(ContextDerived):
|
||||
"""Collects WebIDL info referenced during the build."""
|
||||
|
||||
@ -457,9 +461,13 @@ class Linkable(ContextDerived):
|
||||
|
||||
return [mozpath.join(self.objdir, '%s%s.%s' % (obj_prefix,
|
||||
mozpath.splitext(mozpath.basename(f))[0],
|
||||
self.config.substs.get('OBJ_SUFFIX', '')))
|
||||
self._obj_suffix()))
|
||||
for f in sources]
|
||||
|
||||
def _obj_suffix(self):
|
||||
"""Can be overridden by a base class for custom behavior."""
|
||||
return self.config.substs.get('OBJ_SUFFIX', '')
|
||||
|
||||
@property
|
||||
def no_pgo_objs(self):
|
||||
return self._get_objs(self.no_pgo_sources)
|
||||
@ -670,6 +678,20 @@ class StaticLibrary(Library):
|
||||
self.no_expand_lib = no_expand_lib
|
||||
|
||||
|
||||
class SandboxedWasmLibrary(Library):
|
||||
"""Context derived container object for a static sandboxed wasm library"""
|
||||
# This is a real static library; make it known to the build system.
|
||||
no_expand_lib = True
|
||||
KIND = 'wasm'
|
||||
|
||||
def __init__(self, context, basename, real_name=None):
|
||||
Library.__init__(self, context, basename, real_name)
|
||||
|
||||
def _obj_suffix(self):
|
||||
"""Can be overridden by a base class for custom behavior."""
|
||||
return self.config.substs.get('WASM_OBJ_SUFFIX', '')
|
||||
|
||||
|
||||
class BaseRustLibrary(object):
|
||||
slots = (
|
||||
'cargo_file',
|
||||
@ -1034,6 +1056,20 @@ class HostGeneratedSources(HostMixin, BaseSources):
|
||||
BaseSources.__init__(self, context, files, canonical_suffix)
|
||||
|
||||
|
||||
class WasmSources(BaseSources):
|
||||
"""Represents files to be compiled with the wasm compiler during the build."""
|
||||
|
||||
def __init__(self, context, files, canonical_suffix):
|
||||
BaseSources.__init__(self, context, files, canonical_suffix)
|
||||
|
||||
|
||||
class WasmGeneratedSources(BaseSources):
|
||||
"""Represents generated files to be compiled with the wasm compiler during the build."""
|
||||
|
||||
def __init__(self, context, files, canonical_suffix):
|
||||
BaseSources.__init__(self, context, files, canonical_suffix)
|
||||
|
||||
|
||||
class UnifiedSources(BaseSources):
|
||||
"""Represents files to be compiled in a unified fashion during the build."""
|
||||
|
||||
|
@ -62,6 +62,7 @@ from .data import (
|
||||
HostRustLibrary,
|
||||
RustProgram,
|
||||
RustTests,
|
||||
SandboxedWasmLibrary,
|
||||
SharedLibrary,
|
||||
SimpleProgram,
|
||||
Sources,
|
||||
@ -70,6 +71,9 @@ from .data import (
|
||||
TestManifest,
|
||||
UnifiedSources,
|
||||
VariablePassthru,
|
||||
WasmDefines,
|
||||
WasmGeneratedSources,
|
||||
WasmSources,
|
||||
XPCOMComponentManifests,
|
||||
XPIDLModule,
|
||||
)
|
||||
@ -124,6 +128,7 @@ class TreeMetadataEmitter(LoggingMixin):
|
||||
self._binaries = OrderedDict()
|
||||
self._compile_dirs = set()
|
||||
self._host_compile_dirs = set()
|
||||
self._wasm_compile_dirs = set()
|
||||
self._asm_compile_dirs = set()
|
||||
self._compile_flags = dict()
|
||||
self._compile_as_flags = dict()
|
||||
@ -295,7 +300,8 @@ class TreeMetadataEmitter(LoggingMixin):
|
||||
for o in obj.linked_libraries:
|
||||
if isinstance(o, (HostRustLibrary, RustLibrary)):
|
||||
libs.append(o)
|
||||
elif isinstance(o, (HostLibrary, StaticLibrary)):
|
||||
elif isinstance(o, (HostLibrary, StaticLibrary,
|
||||
SandboxedWasmLibrary)):
|
||||
libs.extend(rust_libraries(o))
|
||||
return libs
|
||||
|
||||
@ -354,16 +360,19 @@ class TreeMetadataEmitter(LoggingMixin):
|
||||
LIBRARY_NAME_VAR = {
|
||||
'host': 'HOST_LIBRARY_NAME',
|
||||
'target': 'LIBRARY_NAME',
|
||||
'wasm': 'SANDBOXED_WASM_LIBRARY_NAME',
|
||||
}
|
||||
|
||||
LIBSTDCXX_VAR = {
|
||||
'host': 'MOZ_LIBSTDCXX_HOST_VERSION',
|
||||
'target': 'MOZ_LIBSTDCXX_TARGET_VERSION',
|
||||
'wasm': 'MOZ_LIBSTDCXX_TARGET_VERSION',
|
||||
}
|
||||
|
||||
STDCXXCOMPAT_NAME = {
|
||||
'host': 'host_stdc++compat',
|
||||
'target': 'stdc++compat',
|
||||
'wasm': 'stdc++compat',
|
||||
}
|
||||
|
||||
def _link_libraries(self, context, obj, variable, extra_sources):
|
||||
@ -600,6 +609,7 @@ class TreeMetadataEmitter(LoggingMixin):
|
||||
def _handle_linkables(self, context, passthru, generated_files):
|
||||
linkables = []
|
||||
host_linkables = []
|
||||
wasm_linkables = []
|
||||
|
||||
def add_program(prog, var):
|
||||
if var.startswith('HOST_'):
|
||||
@ -706,6 +716,8 @@ class TreeMetadataEmitter(LoggingMixin):
|
||||
|
||||
lib_defines = context.get('LIBRARY_DEFINES')
|
||||
|
||||
wasm_lib = context.get('SANDBOXED_WASM_LIBRARY_NAME')
|
||||
|
||||
shared_args = {}
|
||||
static_args = {}
|
||||
|
||||
@ -849,10 +861,33 @@ class TreeMetadataEmitter(LoggingMixin):
|
||||
'LIBRARY_NAME to take effect', context)
|
||||
lib.lib_defines.update(lib_defines)
|
||||
|
||||
if wasm_lib:
|
||||
if wasm_lib == libname:
|
||||
raise SandboxValidationError(
|
||||
'SANDBOXED_WASM_LIBRARY_NAME and LIBRARY_NAME must have a '
|
||||
'different value.', context)
|
||||
if wasm_lib == host_libname:
|
||||
raise SandboxValidationError(
|
||||
'SANDBOXED_WASM_LIBRARY_NAME and HOST_LIBRARY_NAME must '
|
||||
'have a different value.', context)
|
||||
if wasm_lib == shared_name:
|
||||
raise SandboxValidationError(
|
||||
'SANDBOXED_WASM_LIBRARY_NAME and SHARED_NAME must have a '
|
||||
'different value.', context)
|
||||
if wasm_lib == static_name:
|
||||
raise SandboxValidationError(
|
||||
'SANDBOXED_WASM_LIBRARY_NAME and STATIC_NAME must have a '
|
||||
'different value.', context)
|
||||
lib = SandboxedWasmLibrary(context, libname, real_name=wasm_lib)
|
||||
self._libs[libname].append(lib)
|
||||
self._linkage.append((context, lib, 'USE_LIBS'))
|
||||
wasm_linkables.append(lib)
|
||||
self._wasm_compile_dirs.add(context.objdir)
|
||||
|
||||
# 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):
|
||||
if not (linkables or host_linkables or wasm_linkables):
|
||||
return
|
||||
|
||||
self._compile_dirs.add(context.objdir)
|
||||
@ -868,7 +903,7 @@ class TreeMetadataEmitter(LoggingMixin):
|
||||
sources = defaultdict(list)
|
||||
gen_sources = defaultdict(list)
|
||||
all_flags = {}
|
||||
for symbol in ('SOURCES', 'HOST_SOURCES', 'UNIFIED_SOURCES'):
|
||||
for symbol in ('SOURCES', 'HOST_SOURCES', 'UNIFIED_SOURCES', 'WASM_SOURCES'):
|
||||
srcs = sources[symbol]
|
||||
gen_srcs = gen_sources[symbol]
|
||||
context_srcs = context.get(symbol, [])
|
||||
@ -941,6 +976,12 @@ class TreeMetadataEmitter(LoggingMixin):
|
||||
HOST_SOURCES=(HostSources, HostGeneratedSources, ['.c', '.mm', '.cpp']),
|
||||
UNIFIED_SOURCES=(UnifiedSources, None, ['.c', '.mm', '.cpp']),
|
||||
)
|
||||
# Only include a WasmSources or WasmGeneratedSources context if there
|
||||
# are any WASM_SOURCES. (This is going to matter later because we inject
|
||||
# an extra .c file to compile with the wasm compiler if, and only if,
|
||||
# there are any WASM sources.)
|
||||
if sources['WASM_SOURCES'] or gen_sources['WASM_SOURCES']:
|
||||
varmap['WASM_SOURCES'] = (WasmSources, WasmGeneratedSources, ['.c', '.cpp'])
|
||||
# Track whether there are any C++ source files.
|
||||
# Technically this won't do the right thing for SIMPLE_PROGRAMS in
|
||||
# a directory with mixed C and C++ source, but it's not that important.
|
||||
@ -963,6 +1004,12 @@ class TreeMetadataEmitter(LoggingMixin):
|
||||
for srcs, cls in ((sources[variable], klass),
|
||||
(gen_sources[variable], gen_klass)):
|
||||
# Now sort the files to let groupby work.
|
||||
srcs = list(srcs)
|
||||
if cls is WasmSources:
|
||||
srcs.append(
|
||||
mozpath.join(self.config.topsrcdir,
|
||||
('third_party/rust/rlbox_lucet_sandbox/'
|
||||
'c_src/lucet_sandbox_wrapper.c')))
|
||||
sorted_files = sorted(srcs, key=canonical_suffix_for_file)
|
||||
for canonical_suffix, files in itertools.groupby(
|
||||
sorted_files, canonical_suffix_for_file):
|
||||
@ -974,7 +1021,7 @@ class TreeMetadataEmitter(LoggingMixin):
|
||||
if variable.startswith('UNIFIED_'):
|
||||
arglist.append(context.get('FILES_PER_UNIFIED_FILE', 16))
|
||||
obj = cls(*arglist)
|
||||
srcs = obj.files
|
||||
srcs = list(obj.files)
|
||||
if isinstance(obj, UnifiedSources) and obj.have_unified_mapping:
|
||||
srcs = dict(obj.unified_source_mapping).keys()
|
||||
ctxt_sources[variable][canonical_suffix] += sorted(srcs)
|
||||
@ -992,6 +1039,9 @@ class TreeMetadataEmitter(LoggingMixin):
|
||||
for host_linkable in host_linkables:
|
||||
for suffix, srcs in ctxt_sources['HOST_SOURCES'].items():
|
||||
host_linkable.sources[suffix] += srcs
|
||||
for wasm_linkable in wasm_linkables:
|
||||
for suffix, srcs in ctxt_sources['WASM_SOURCES'].items():
|
||||
wasm_linkable.sources[suffix] += srcs
|
||||
|
||||
for f, flags in sorted(all_flags.iteritems()):
|
||||
if flags.flags:
|
||||
@ -1036,6 +1086,7 @@ class TreeMetadataEmitter(LoggingMixin):
|
||||
computed_link_flags = ComputedFlags(context, context['LINK_FLAGS'])
|
||||
computed_host_flags = ComputedFlags(context, context['HOST_COMPILE_FLAGS'])
|
||||
computed_as_flags = ComputedFlags(context, context['ASM_FLAGS'])
|
||||
computed_wasm_flags = ComputedFlags(context, context['WASM_FLAGS'])
|
||||
|
||||
# Proxy some variables as-is until we have richer classes to represent
|
||||
# them. We should aim to keep this set small because it violates the
|
||||
@ -1072,6 +1123,10 @@ class TreeMetadataEmitter(LoggingMixin):
|
||||
if v in context and context[v]:
|
||||
computed_flags.resolve_flags('MOZBUILD_%s' % v, context[v])
|
||||
|
||||
for v in ['WASM_CFLAGS', 'WASM_CXXFLAGS', 'WASM_LDFLAGS']:
|
||||
if v in context and context[v]:
|
||||
computed_wasm_flags.resolve_flags('MOZBUILD_%s' % v, context[v])
|
||||
|
||||
for v in ['HOST_CXXFLAGS', 'HOST_CFLAGS']:
|
||||
if v in context and context[v]:
|
||||
computed_host_flags.resolve_flags('MOZBUILD_%s' % v, context[v])
|
||||
@ -1123,6 +1178,7 @@ class TreeMetadataEmitter(LoggingMixin):
|
||||
computed_flags.resolve_flags('RTL', [rtl_flag])
|
||||
if not context.config.substs.get('CROSS_COMPILE'):
|
||||
computed_host_flags.resolve_flags('RTL', [rtl_flag])
|
||||
computed_wasm_flags.resolve_flags('RTL', [rtl_flag])
|
||||
|
||||
generated_files = set()
|
||||
localized_generated_files = set()
|
||||
@ -1139,11 +1195,10 @@ class TreeMetadataEmitter(LoggingMixin):
|
||||
generated_files.add(str(sub.relpath))
|
||||
yield sub
|
||||
|
||||
for defines_var, cls, backend_flags in (('DEFINES', Defines,
|
||||
(computed_flags, computed_as_flags)),
|
||||
('HOST_DEFINES', HostDefines,
|
||||
(computed_host_flags,))
|
||||
):
|
||||
for defines_var, cls, backend_flags in (
|
||||
('DEFINES', Defines, (computed_flags, computed_as_flags,)),
|
||||
('HOST_DEFINES', HostDefines, (computed_host_flags,)),
|
||||
('WASM_DEFINES', WasmDefines, (computed_wasm_flags,))):
|
||||
defines = context.get(defines_var)
|
||||
if defines:
|
||||
defines_obj = cls(context, defines)
|
||||
@ -1205,6 +1260,7 @@ class TreeMetadataEmitter(LoggingMixin):
|
||||
computed_flags.resolve_flags('LOCAL_INCLUDES', ['-I%s' % p for p in local_includes])
|
||||
computed_as_flags.resolve_flags('LOCAL_INCLUDES', ['-I%s' % p for p in local_includes])
|
||||
computed_host_flags.resolve_flags('LOCAL_INCLUDES', ['-I%s' % p for p in local_includes])
|
||||
computed_wasm_flags.resolve_flags('LOCAL_INCLUDES', ['-I%s' % p for p in local_includes])
|
||||
|
||||
for obj in self._handle_linkables(context, passthru, generated_files):
|
||||
yield obj
|
||||
@ -1384,6 +1440,9 @@ class TreeMetadataEmitter(LoggingMixin):
|
||||
if context.objdir in self._host_compile_dirs:
|
||||
yield computed_host_flags
|
||||
|
||||
if context.objdir in self._wasm_compile_dirs:
|
||||
yield computed_wasm_flags
|
||||
|
||||
def _create_substitution(self, cls, context, path):
|
||||
sub = cls(context)
|
||||
sub.input_path = '%s.in' % path.full_path
|
||||
|
@ -19,3 +19,6 @@ SOURCES += ['bar.c', 'foo.c']
|
||||
SOURCES += ['bar.mm', 'foo.mm']
|
||||
|
||||
SOURCES += ['baz.S', 'foo.S']
|
||||
|
||||
WASM_SOURCES += ['bar.cpp']
|
||||
WASM_SOURCES += ['bar.c']
|
||||
|
@ -342,7 +342,7 @@ class TestRecursiveMakeBackend(BackendTester):
|
||||
self.assertEqual(found, val)
|
||||
|
||||
def test_sources(self):
|
||||
"""Ensure SOURCES and HOST_SOURCES are handled properly."""
|
||||
"""Ensure SOURCES, HOST_SOURCES and WASM_SOURCES are handled properly."""
|
||||
env = self._consume('sources', RecursiveMakeBackend)
|
||||
|
||||
backend_path = mozpath.join(env.topobjdir, 'backend.mk')
|
||||
@ -373,6 +373,14 @@ class TestRecursiveMakeBackend(BackendTester):
|
||||
'SSRCS += $(srcdir)/baz.S',
|
||||
'SSRCS += $(srcdir)/foo.S',
|
||||
],
|
||||
'WASM_CSRCS': [
|
||||
'WASM_CSRCS += $(srcdir)/bar.c',
|
||||
('WASM_CSRCS += $(srcdir)/third_party/rust/rlbox_lucet_sandbox/'
|
||||
'c_src/lucet_sandbox_wrapper.c'),
|
||||
],
|
||||
'WASM_CPPSRCS': [
|
||||
'WASM_CPPSRCS += $(srcdir)/bar.cpp',
|
||||
],
|
||||
}
|
||||
|
||||
for var, val in expected.items():
|
||||
|
@ -0,0 +1,20 @@
|
||||
# Any copyright is dedicated to the Public Domain.
|
||||
# http://creativecommons.org/publicdomain/zero/1.0/
|
||||
|
||||
SANDBOXED_WASM_LIBRARY_NAME = 'dummy'
|
||||
|
||||
WASM_SOURCES += ['test1.c']
|
||||
|
||||
value = 'xyz'
|
||||
WASM_DEFINES = {
|
||||
'FOO': True,
|
||||
}
|
||||
|
||||
WASM_DEFINES['BAZ'] = '"abcd"'
|
||||
WASM_DEFINES.update({
|
||||
'BAR': 7,
|
||||
'VALUE': value,
|
||||
'QUX': False,
|
||||
})
|
||||
|
||||
WASM_CFLAGS += ['-funroll-loops', '-wasm-arg']
|
@ -0,0 +1,15 @@
|
||||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# Any copyright is dedicated to the Public Domain.
|
||||
# http://creativecommons.org/publicdomain/zero/1.0/
|
||||
|
||||
SANDBOXED_WASM_LIBRARY_NAME = 'wasmSources'
|
||||
|
||||
WASM_SOURCES += [
|
||||
'a.cpp',
|
||||
'b.cc',
|
||||
'c.cxx',
|
||||
]
|
||||
|
||||
WASM_SOURCES += [
|
||||
'd.c',
|
||||
]
|
@ -42,6 +42,7 @@ from mozbuild.frontend.data import (
|
||||
TestManifest,
|
||||
UnifiedSources,
|
||||
VariablePassthru,
|
||||
WasmSources,
|
||||
)
|
||||
from mozbuild.frontend.emitter import TreeMetadataEmitter
|
||||
from mozbuild.frontend.reader import (
|
||||
@ -79,6 +80,8 @@ class TestEmitterBasic(unittest.TestCase):
|
||||
VISIBILITY_FLAGS=['-include',
|
||||
'$(topsrcdir)/config/gcc_hidden.h'],
|
||||
OBJ_SUFFIX='obj',
|
||||
WASM_OBJ_SUFFIX='wasm',
|
||||
WASM_CFLAGS=['-foo'],
|
||||
)
|
||||
if extra_substs:
|
||||
substs.update(extra_substs)
|
||||
@ -1334,6 +1337,41 @@ class TestEmitterBasic(unittest.TestCase):
|
||||
reader.config.substs['OBJ_SUFFIX'])),
|
||||
linkable.objs)
|
||||
|
||||
def test_wasm_sources(self):
|
||||
"""Test that HOST_SOURCES works properly."""
|
||||
reader = self.reader('wasm-sources')
|
||||
objs = list(self.read_topsrcdir(reader))
|
||||
|
||||
# The second to last object is a linkable.
|
||||
linkable = objs[-2]
|
||||
# Other than that, we only care about the WasmSources objects.
|
||||
objs = objs[:2]
|
||||
for o in objs:
|
||||
self.assertIsInstance(o, WasmSources)
|
||||
|
||||
suffix_map = {obj.canonical_suffix: obj for obj in objs}
|
||||
self.assertEqual(len(suffix_map), 2)
|
||||
|
||||
expected = {
|
||||
'.cpp': ['a.cpp', 'b.cc', 'c.cxx'],
|
||||
'.c': ['d.c'],
|
||||
}
|
||||
for suffix, files in expected.items():
|
||||
sources = suffix_map[suffix]
|
||||
self.assertEqual(
|
||||
sources.files,
|
||||
[mozpath.join(reader.config.topsrcdir, f) for f in files] +
|
||||
([mozpath.join(
|
||||
reader.config.topsrcdir,
|
||||
'third_party/rust/rlbox_lucet_sandbox/c_src/lucet_sandbox_wrapper.c')]
|
||||
if suffix == '.c' else []))
|
||||
for f in files:
|
||||
self.assertIn(mozpath.join(
|
||||
reader.config.topobjdir,
|
||||
'%s.%s' % (mozpath.splitext(f)[0],
|
||||
reader.config.substs['WASM_OBJ_SUFFIX'])),
|
||||
linkable.objs)
|
||||
|
||||
def test_unified_sources(self):
|
||||
"""Test that UNIFIED_SOURCES works properly."""
|
||||
reader = self.reader('unified-sources')
|
||||
@ -1679,6 +1717,17 @@ class TestEmitterBasic(unittest.TestCase):
|
||||
):
|
||||
self.read_topsrcdir(reader)
|
||||
|
||||
def test_wasm_compile_flags(self):
|
||||
reader = self.reader('wasm-compile-flags')
|
||||
flags = list(self.read_topsrcdir(reader))[2]
|
||||
self.assertIsInstance(flags, ComputedFlags)
|
||||
self.assertEqual(flags.flags['WASM_CFLAGS'],
|
||||
reader.config.substs['WASM_CFLAGS'])
|
||||
self.assertEqual(flags.flags['MOZBUILD_WASM_CFLAGS'],
|
||||
['-funroll-loops', '-wasm-arg'])
|
||||
self.assertEqual(set(flags.flags['WASM_DEFINES']),
|
||||
set(['-DFOO', '-DBAZ="abcd"', '-UQUX', '-DBAR=7', '-DVALUE=xyz']))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
@ -1848,20 +1848,25 @@ def wasm_cxx_with_flags(wasm_cxx, provided_wasm_cxx, wasi_sysroot):
|
||||
set_config('WASM_CXX', wasm_cxx_with_flags, when=requires_wasm_sandboxing)
|
||||
|
||||
|
||||
wasm_compile_flags = dependable(['-fno-exceptions', '-fno-strict-aliasing', '-Qunused-arguments'])
|
||||
option(env='WASM_CFLAGS', nargs=1, help='Options to pass to WASM_CC',
|
||||
when=requires_wasm_sandboxing)
|
||||
@depends('WASM_CFLAGS', when=requires_wasm_sandboxing)
|
||||
def wasm_cflags(value):
|
||||
@depends('WASM_CFLAGS', wasm_compile_flags, when=requires_wasm_sandboxing)
|
||||
def wasm_cflags(value, wasm_compile_flags):
|
||||
if value:
|
||||
return value
|
||||
return wasm_compile_flags + value
|
||||
else:
|
||||
return wasm_compile_flags
|
||||
set_config('WASM_CFLAGS', wasm_cflags, when=requires_wasm_sandboxing)
|
||||
|
||||
option(env='WASM_CXXFLAGS', nargs=1, help='Options to pass to WASM_CXX',
|
||||
when=requires_wasm_sandboxing)
|
||||
@depends('WASM_CXXFLAGS', when=requires_wasm_sandboxing)
|
||||
def wasm_cxxflags(value):
|
||||
@depends('WASM_CXXFLAGS', wasm_compile_flags, when=requires_wasm_sandboxing)
|
||||
def wasm_cxxflags(value, wasm_compile_flags):
|
||||
if value:
|
||||
return value
|
||||
return wasm_compile_flags + value
|
||||
else:
|
||||
return wasm_compile_flags
|
||||
set_config('WASM_CXXFLAGS', wasm_cxxflags, when=requires_wasm_sandboxing)
|
||||
|
||||
option(env='WASM_LDFLAGS', nargs=1,
|
||||
|
Loading…
Reference in New Issue
Block a user