summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt A. Tobin <email@mattatobin.com>2021-11-20 21:15:14 -0500
committerMoonchild <moonchild@palemoon.org>2022-04-07 15:42:57 +0200
commitb2ad7e8ed963768f53053bd0495e69f80c3a4c33 (patch)
treecfdd7fc05fed4e6c45094d687980d9ccbfd5519f
parent3b48d984b2a0524ed9ca26b48f09831d9d88fc2e (diff)
downloaduxp-b2ad7e8ed963768f53053bd0495e69f80c3a4c33.tar.gz
Issue #1847 - Updates to handle NSS
Bug 1295937
-rw-r--r--build/gyp.mozbuild37
-rw-r--r--build/gyp_base.mozbuild38
-rw-r--r--build/moz.configure/init.configure1
-rw-r--r--python/mozbuild/mozbuild/frontend/context.py9
-rw-r--r--python/mozbuild/mozbuild/frontend/gyp_reader.py214
-rw-r--r--python/mozbuild/mozbuild/frontend/reader.py6
6 files changed, 226 insertions, 79 deletions
diff --git a/build/gyp.mozbuild b/build/gyp.mozbuild
index ff04f6aac1..a0ddd6939c 100644
--- a/build/gyp.mozbuild
+++ b/build/gyp.mozbuild
@@ -4,7 +4,9 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-gyp_vars = {
+include('gyp_base.mozbuild')
+
+gyp_vars.update({
'lsan': 0,
'asan': 0,
'build_with_mozilla': 1,
@@ -69,16 +71,9 @@ gyp_vars = {
# linker to throw away uneeded bits.
'include_isac': 1,
'include_pcm16b': 1,
-}
-
-os = CONFIG['OS_TARGET']
+})
-if os == 'WINNT':
- gyp_vars.update(
- MSVS_VERSION=CONFIG['_MSVS_VERSION'],
- MSVS_OS_BITS=64 if CONFIG['HAVE_64BIT_BUILD'] else 32,
- )
-elif os == 'Android':
+if os == 'Android':
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
gyp_vars['build_with_gonk'] = 1
gyp_vars['moz_widget_toolkit_gonk'] = 1
@@ -92,28 +87,6 @@ elif os == 'Android':
android_toolchain=CONFIG.get('ANDROID_TOOLCHAIN', ''),
)
-flavors = {
- 'WINNT': 'win',
- 'Android': 'linux' if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' else 'android',
- 'Linux': 'linux',
- 'Darwin': 'mac' if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa' else 'ios',
- 'SunOS': 'solaris',
- 'GNU/kFreeBSD': 'freebsd',
- 'DragonFly': 'dragonfly',
- 'FreeBSD': 'freebsd',
- 'NetBSD': 'netbsd',
- 'OpenBSD': 'openbsd',
-}
-gyp_vars['OS'] = flavors.get(os)
-
-arches = {
- 'x86_64': 'x64',
- 'x86': 'ia32',
- 'aarch64': 'arm64',
-}
-
-gyp_vars['target_arch'] = arches.get(CONFIG['CPU_ARCH'], CONFIG['CPU_ARCH'])
-
if CONFIG['ARM_ARCH']:
if int(CONFIG['ARM_ARCH']) < 7:
gyp_vars['armv7'] = 0
diff --git a/build/gyp_base.mozbuild b/build/gyp_base.mozbuild
new file mode 100644
index 0000000000..bbdaa0c583
--- /dev/null
+++ b/build/gyp_base.mozbuild
@@ -0,0 +1,38 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+gyp_vars = {}
+
+os = CONFIG['OS_TARGET']
+
+if os == 'WINNT':
+ gyp_vars.update(
+ MSVS_VERSION=CONFIG['_MSVS_VERSION'],
+ MSVS_OS_BITS=64 if CONFIG['HAVE_64BIT_BUILD'] else 32,
+ )
+
+flavors = {
+ 'WINNT': 'win',
+ 'Android': 'linux' if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' else 'android',
+ 'Linux': 'linux',
+ 'Darwin': 'mac' if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa' else 'ios',
+ 'SunOS': 'solaris',
+ 'GNU/kFreeBSD': 'freebsd',
+ 'DragonFly': 'dragonfly',
+ 'FreeBSD': 'freebsd',
+ 'NetBSD': 'netbsd',
+ 'OpenBSD': 'openbsd',
+}
+gyp_vars['OS'] = flavors.get(os)
+
+arches = {
+ 'x86_64': 'x64',
+ 'x86': 'ia32',
+ 'aarch64': 'arm64',
+}
+
+gyp_vars['host_arch'] = arches.get(CONFIG['HOST_CPU_ARCH'], CONFIG['HOST_CPU_ARCH'])
+gyp_vars['target_arch'] = arches.get(CONFIG['CPU_ARCH'], CONFIG['CPU_ARCH'])
diff --git a/build/moz.configure/init.configure b/build/moz.configure/init.configure
index 8f275aee01..6c4f74c0d8 100644
--- a/build/moz.configure/init.configure
+++ b/build/moz.configure/init.configure
@@ -518,6 +518,7 @@ def host_variables(host):
HOST_OS_ARCH=os_arch,
)
+set_config('HOST_CPU_ARCH', delayed_getattr(host, 'cpu'))
set_config('HOST_OS_ARCH', delayed_getattr(host_variables, 'HOST_OS_ARCH'))
add_old_configure_assignment('HOST_OS_ARCH',
delayed_getattr(host_variables, 'HOST_OS_ARCH'))
diff --git a/python/mozbuild/mozbuild/frontend/context.py b/python/mozbuild/mozbuild/frontend/context.py
index f81665b52b..7c44a6836a 100644
--- a/python/mozbuild/mozbuild/frontend/context.py
+++ b/python/mozbuild/mozbuild/frontend/context.py
@@ -1567,7 +1567,10 @@ VARIABLES = {
'variables': dict,
'input': unicode,
'sandbox_vars': dict,
+ 'no_chromium': bool,
+ 'no_unified': bool,
'non_unified_sources': StrictOrderingOnAppendList,
+ 'action_overrides': dict,
}), list,
"""Defines a list of object directories handled by gyp configurations.
@@ -1582,9 +1585,15 @@ VARIABLES = {
- sandbox_vars, a dictionary containing variables and values to
pass to the mozbuild processor on top of those derived from gyp
configuration.
+ - no_chromium, a boolean which if set to True disables some
+ special handling that emulates gyp_chromium.
+ - no_unified, a boolean which if set to True disables source
+ file unification entirely.
- non_unified_sources, a list containing sources files, relative to
the current moz.build, that should be excluded from source file
unification.
+ - action_overrides, a dict of action_name to values of the `script`
+ attribute to use for GENERATED_FILES for the specified action.
Typical use looks like:
GYP_DIRS += ['foo', 'bar']
diff --git a/python/mozbuild/mozbuild/frontend/gyp_reader.py b/python/mozbuild/mozbuild/frontend/gyp_reader.py
index 459c553c3e..ef24c0dc42 100644
--- a/python/mozbuild/mozbuild/frontend/gyp_reader.py
+++ b/python/mozbuild/mozbuild/frontend/gyp_reader.py
@@ -5,6 +5,7 @@
from __future__ import absolute_import, unicode_literals
import gyp
+import gyp.msvs_emulation
import sys
import os
import types
@@ -12,6 +13,7 @@ import mozpack.path as mozpath
from mozpack.files import FileFinder
from .sandbox import alphabetical_sorted
from .context import (
+ ObjDirPath,
SourcePath,
TemplateContext,
VARIABLES,
@@ -38,13 +40,20 @@ chrome_src = mozpath.abspath(mozpath.join(mozpath.dirname(gyp.__file__),
'../../../..'))
script_dir = mozpath.join(chrome_src, 'build')
+
+def encode(value):
+ if isinstance(value, unicode):
+ return value.encode('utf-8')
+ return value
+
+
# Default variables gyp uses when evaluating gyp files.
generator_default_variables = {
}
-for dirname in ['INTERMEDIATE_DIR', 'SHARED_INTERMEDIATE_DIR', 'PRODUCT_DIR',
- 'LIB_DIR', 'SHARED_LIB_DIR']:
+for dirname in [b'INTERMEDIATE_DIR', b'SHARED_INTERMEDIATE_DIR', b'PRODUCT_DIR',
+ b'LIB_DIR', b'SHARED_LIB_DIR']:
# Some gyp steps fail if these are empty(!).
- generator_default_variables[dirname] = b'dir'
+ generator_default_variables[dirname] = b'$' + dirname
for unused in ['RULE_INPUT_PATH', 'RULE_INPUT_ROOT', 'RULE_INPUT_NAME',
'RULE_INPUT_DIRNAME', 'RULE_INPUT_EXT',
@@ -68,13 +77,37 @@ class GypContext(TemplateContext):
allowed_variables=VARIABLES, config=config)
-def encode(value):
- if isinstance(value, unicode):
- return value.encode('utf-8')
- return value
+def handle_actions(actions, context, action_overrides):
+ idir = '$INTERMEDIATE_DIR/'
+ for action in actions:
+ name = action['action_name']
+ if name not in action_overrides:
+ raise RuntimeError('GYP action %s not listed in action_overrides' % name)
+ outputs = action['outputs']
+ if len(outputs) > 1:
+ raise NotImplementedError('GYP actions with more than one output not supported: %s' % name)
+ output = outputs[0]
+ if not output.startswith(idir):
+ raise NotImplementedError('GYP actions outputting to somewhere other than <(INTERMEDIATE_DIR) not supported: %s' % output)
+ output = output[len(idir):]
+ context['GENERATED_FILES'] += [output]
+ g = context['GENERATED_FILES'][output]
+ g.script = action_overrides[name]
+ g.inputs = action['inputs']
+def handle_copies(copies, context):
+ dist = '$PRODUCT_DIR/dist/'
+ for copy in copies:
+ dest = copy['destination']
+ if not dest.startswith(dist):
+ raise NotImplementedError('GYP copies to somewhere other than <(PRODUCT_DIR)/dist not supported: %s' % dest)
+ dest_paths = dest[len(dist):].split('/')
+ exports = context['EXPORTS']
+ while dest_paths:
+ exports = getattr(exports, dest_paths.pop(0))
+ exports += sorted(copy['files'], key=lambda x: x.lower())
-def read_from_gyp(config, path, output, vars, non_unified_sources = set()):
+def read_from_gyp(config, path, output, vars, no_chromium, no_unified, action_overrides, non_unified_sources = set()):
"""Read a gyp configuration and emits GypContexts for the backend to
process.
@@ -84,10 +117,17 @@ def read_from_gyp(config, path, output, vars, non_unified_sources = set()):
processor.
"""
+ is_win = config.substs['OS_TARGET'] == 'WINNT'
+ is_msvc = bool(config.substs['_MSC_VER'])
# gyp expects plain str instead of unicode. The frontend code gives us
# unicode strings, so convert them.
path = encode(path)
str_vars = dict((name, encode(value)) for name, value in vars.items())
+ if is_msvc:
+ # This isn't actually used anywhere in this generator, but it's needed
+ # to override the registry detection of VC++ in gyp.
+ os.environ['GYP_MSVS_OVERRIDE_PATH'] = 'fake_path'
+ os.environ['GYP_MSVS_VERSION'] = config.substs['MSVS_VERSION']
params = {
b'parallel': False,
@@ -96,18 +136,23 @@ def read_from_gyp(config, path, output, vars, non_unified_sources = set()):
b'root_targets': None,
}
- # Files that gyp_chromium always includes
- includes = [encode(mozpath.join(script_dir, 'common.gypi'))]
- finder = FileFinder(chrome_src, find_executables=False)
- includes.extend(encode(mozpath.join(chrome_src, name))
- for name, _ in finder.find('*/supplement.gypi'))
+ if no_chromium:
+ includes = []
+ depth = mozpath.dirname(path)
+ else:
+ depth = chrome_src
+ # Files that gyp_chromium always includes
+ includes = [encode(mozpath.join(script_dir, 'common.gypi'))]
+ finder = FileFinder(chrome_src, find_executables=False)
+ includes.extend(encode(mozpath.join(chrome_src, name))
+ for name, _ in finder.find('*/supplement.gypi'))
# Read the given gyp file and its dependencies.
generator, flat_list, targets, data = \
gyp.Load([path], format=b'mozbuild',
default_variables=str_vars,
includes=includes,
- depth=encode(chrome_src),
+ depth=encode(depth),
params=params)
# Process all targets from the given gyp files and its dependencies.
@@ -146,60 +191,134 @@ def read_from_gyp(config, path, output, vars, non_unified_sources = set()):
'in %s' % (c, target_name, build_file))
target_conf = spec['configurations'][c]
+ if 'actions' in spec:
+ handle_actions(spec['actions'], context, action_overrides)
+ if 'copies' in spec:
+ handle_copies(spec['copies'], context)
+
+ use_libs = []
+ libs = []
+ def add_deps(s):
+ for t in s.get('dependencies', []) + s.get('dependencies_original', []):
+ ty = targets[t]['type']
+ if ty in ('static_library', 'shared_library'):
+ use_libs.append(targets[t]['target_name'])
+ # Manually expand out transitive dependencies--
+ # gyp won't do this for static libs or none targets.
+ if ty in ('static_library', 'none'):
+ add_deps(targets[t])
+ libs.extend(spec.get('libraries', []))
+ #XXX: this sucks, but webrtc breaks with this right now because
+ # it builds a library called 'gtest' and we just get lucky
+ # that it isn't in USE_LIBS by that name anywhere.
+ if no_chromium:
+ add_deps(spec)
+
+ os_libs = []
+ for l in libs:
+ if l.startswith('-'):
+ os_libs.append(l)
+ elif l.endswith('.lib'):
+ os_libs.append(l[:-4])
+ elif l:
+ # For library names passed in from moz.build.
+ use_libs.append(os.path.basename(l))
+
if spec['type'] == 'none':
+ if not ('actions' in spec or 'copies' in spec):
continue
- elif spec['type'] == 'static_library':
+ elif spec['type'] in ('static_library', 'shared_library', 'executable'):
# Remove leading 'lib' from the target_name if any, and use as
# library name.
name = spec['target_name']
- if name.startswith('lib'):
- name = name[3:]
- # The context expects an unicode string.
- context['LIBRARY_NAME'] = name.decode('utf-8')
+ if spec['type'] in ('static_library', 'shared_library'):
+ if name.startswith('lib'):
+ name = name[3:]
+ # The context expects an unicode string.
+ context['LIBRARY_NAME'] = name.decode('utf-8')
+ else:
+ context['PROGRAM'] = name.decode('utf-8')
+ if spec['type'] == 'shared_library':
+ context['FORCE_SHARED_LIB'] = True
+ elif spec['type'] == 'static_library' and spec.get('variables', {}).get('no_expand_libs', '0') == '1':
+ # PSM links a NSS static library, but our folded libnss
+ # doesn't actually export everything that all of the
+ # objects within would need, so that one library
+ # should be built as a real static library.
+ context['NO_EXPAND_LIBS'] = True
+ if use_libs:
+ context['USE_LIBS'] = sorted(use_libs, key=lambda s: s.lower())
+ if os_libs:
+ context['OS_LIBS'] = os_libs
# gyp files contain headers and asm sources in sources lists.
sources = []
unified_sources = []
extensions = set()
+ use_defines_in_asflags = False
for f in spec.get('sources', []):
ext = mozpath.splitext(f)[-1]
extensions.add(ext)
- s = SourcePath(context, f)
+ if f.startswith('$INTERMEDIATE_DIR/'):
+ s = ObjDirPath(context, f.replace('$INTERMEDIATE_DIR/', '!'))
+ else:
+ s = SourcePath(context, f)
if ext == '.h':
continue
- if ext != '.S' and s not in non_unified_sources:
+ if ext == '.def':
+ context['SYMBOLS_FILE'] = s
+ elif ext != '.S' and not no_unified and s not in non_unified_sources:
unified_sources.append(s)
else:
sources.append(s)
+ # The Mozilla build system doesn't use DEFINES for building
+ # ASFILES.
+ if ext == '.s':
+ use_defines_in_asflags = True
# The context expects alphabetical order when adding sources
context['SOURCES'] = alphabetical_sorted(sources)
context['UNIFIED_SOURCES'] = alphabetical_sorted(unified_sources)
- for define in target_conf.get('defines', []):
+ defines = target_conf.get('defines', [])
+ if is_msvc and no_chromium:
+ msvs_settings = gyp.msvs_emulation.MsvsSettings(spec, {})
+ defines.extend(msvs_settings.GetComputedDefines(c))
+ for define in defines:
if '=' in define:
name, value = define.split('=', 1)
context['DEFINES'][name] = value
else:
context['DEFINES'][define] = True
+ product_dir_dist = '$PRODUCT_DIR/dist/'
for include in target_conf.get('include_dirs', []):
- # moz.build expects all LOCAL_INCLUDES to exist, so ensure they do.
- #
- # NB: gyp files sometimes have actual absolute paths (e.g.
- # /usr/include32) and sometimes paths that moz.build considers
- # absolute, i.e. starting from topsrcdir. There's no good way
- # to tell them apart here, and the actual absolute paths are
- # likely bogus. In any event, actual absolute paths will be
- # filtered out by trying to find them in topsrcdir.
- if include.startswith('/'):
- resolved = mozpath.abspath(mozpath.join(config.topsrcdir, include[1:]))
+ if include.startswith(product_dir_dist):
+ # special-case includes of <(PRODUCT_DIR)/dist/ to match
+ # handle_copies above. This is used for NSS' exports.
+ include = '!/dist/include/' + include[len(product_dir_dist):]
+ elif include.startswith(config.topobjdir):
+ # NSPR_INCLUDE_DIR gets passed into the NSS build this way.
+ include = '!/' + mozpath.relpath(include, config.topobjdir)
else:
- resolved = mozpath.abspath(mozpath.join(mozpath.dirname(build_file), include))
- if not os.path.exists(resolved):
- continue
+ # moz.build expects all LOCAL_INCLUDES to exist, so ensure they do.
+ #
+ # NB: gyp files sometimes have actual absolute paths (e.g.
+ # /usr/include32) and sometimes paths that moz.build considers
+ # absolute, i.e. starting from topsrcdir. There's no good way
+ # to tell them apart here, and the actual absolute paths are
+ # likely bogus. In any event, actual absolute paths will be
+ # filtered out by trying to find them in topsrcdir.
+ if include.startswith('/'):
+ resolved = mozpath.abspath(mozpath.join(config.topsrcdir, include[1:]))
+ else:
+ resolved = mozpath.abspath(mozpath.join(mozpath.dirname(build_file), include))
+ if not os.path.exists(resolved):
+ continue
context['LOCAL_INCLUDES'] += [include]
context['ASFLAGS'] = target_conf.get('asflags_mozilla', [])
+ if use_defines_in_asflags and defines:
+ context['ASFLAGS'] += ['-D' + d for d in defines]
flags = target_conf.get('cflags_mozilla', [])
if flags:
suffix_map = {
@@ -227,22 +346,23 @@ def read_from_gyp(config, path, output, vars, non_unified_sources = set()):
else:
context[var].extend(f)
else:
- # Ignore other types than static_library because we don't have
+ # Ignore other types because we don't have
# anything using them, and we're not testing them. They can be
# added when that becomes necessary.
raise NotImplementedError('Unsupported gyp target type: %s' % spec['type'])
- # Add some features to all contexts. Put here in case LOCAL_INCLUDES
- # order matters.
- context['LOCAL_INCLUDES'] += [
- '!/ipc/ipdl/_ipdlheaders',
- '/ipc/chromium/src',
- '/ipc/glue',
- ]
- # These get set via VC project file settings for normal GYP builds.
- if config.substs['OS_TARGET'] == 'WINNT':
- context['DEFINES']['UNICODE'] = True
- context['DEFINES']['_UNICODE'] = True
+ if not no_chromium:
+ # Add some features to all contexts. Put here in case LOCAL_INCLUDES
+ # order matters.
+ context['LOCAL_INCLUDES'] += [
+ '!/ipc/ipdl/_ipdlheaders',
+ '/ipc/chromium/src',
+ '/ipc/glue',
+ ]
+ # These get set via VC project file settings for normal GYP builds.
+ if is_win:
+ context['DEFINES']['UNICODE'] = True
+ context['DEFINES']['_UNICODE'] = True
context['DISABLE_STL_WRAPPING'] = True
yield context
diff --git a/python/mozbuild/mozbuild/frontend/reader.py b/python/mozbuild/mozbuild/frontend/reader.py
index a7d7e8b71a..165a8b7119 100644
--- a/python/mozbuild/mozbuild/frontend/reader.py
+++ b/python/mozbuild/mozbuild/frontend/reader.py
@@ -1128,12 +1128,18 @@ class BuildReader(object):
raise SandboxValidationError('Cannot find %s.' % source,
context)
non_unified_sources.add(source)
+ action_overrides = {}
+ for action, script in gyp_dir.action_overrides.iteritems():
+ action_overrides[action] = SourcePath(context, script)
time_start = time.time()
for gyp_context in read_from_gyp(context.config,
mozpath.join(curdir, gyp_dir.input),
mozpath.join(context.objdir,
target_dir),
gyp_dir.variables,
+ gyp_dir.no_chromium,
+ gyp_dir.no_unified,
+ action_overrides,
non_unified_sources = non_unified_sources):
gyp_context.update(gyp_dir.sandbox_vars)
gyp_contexts.append(gyp_context)