2016-07-14 19:16:42 +03:00
|
|
|
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
2016-03-04 11:31:10 +03:00
|
|
|
# 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/.
|
|
|
|
|
2017-10-12 16:22:59 +03:00
|
|
|
|
2016-03-27 05:40:13 +03:00
|
|
|
@imports('sys')
|
2016-03-25 10:30:42 +03:00
|
|
|
def die(*args):
|
2016-03-17 18:04:12 +03:00
|
|
|
'Print an error and terminate configure.'
|
2016-03-25 10:30:42 +03:00
|
|
|
log.error(*args)
|
2016-03-04 11:31:10 +03:00
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
|
2016-03-27 05:40:13 +03:00
|
|
|
@imports(_from='mozbuild.configure', _import='ConfigureError')
|
2016-03-17 18:04:12 +03:00
|
|
|
def configure_error(message):
|
|
|
|
'''Raise a programming error and terminate configure.
|
|
|
|
Primarily for use in moz.configure templates to sanity check
|
|
|
|
their inputs from moz.configure usage.'''
|
|
|
|
raise ConfigureError(message)
|
|
|
|
|
2017-10-12 16:22:59 +03:00
|
|
|
|
Bug 1469088 - Relax the assumptions of --enable-lto, and make it work for macOS builds. r=ted
Currently, --enable-lto just implies --enable-linker=lld, which
essentially only works on Linux, and assumes one can't do lto with
anything other than lld. Which is not true. As a matter of fact, even
ld.bfd can do lto, as long as the gold plugin for llvm is available,
or when doing lto with GCC instead of clang.
Anyways, to allow more lto setups, we adapt the --enable-linker setup
to:
- work on macOS, which it currently doesn't, and add support for the mac
linker (ld64), which, unfortunately, doesn't have a clean way to be
detected, so work around that.
- default to lld if lto is enable, no linker was explicitly given, the
compiler is clang *and* the build target is not macOS.
--HG--
extra : rebase_source : 1dab2ad6230d18e7f4285943e76352e23b987d4e
2018-07-05 05:35:31 +03:00
|
|
|
# A wrapper to obtain a process' output and return code.
|
|
|
|
# Returns a tuple (retcode, stdout, stderr).
|
2018-10-10 02:15:13 +03:00
|
|
|
@imports('os')
|
2016-05-18 00:40:03 +03:00
|
|
|
@imports('subprocess')
|
|
|
|
@imports(_from='mozbuild.shellutil', _import='quote')
|
2019-08-20 19:43:15 +03:00
|
|
|
@imports(_from='mozbuild.util', _import='system_encoding')
|
Bug 1469088 - Relax the assumptions of --enable-lto, and make it work for macOS builds. r=ted
Currently, --enable-lto just implies --enable-linker=lld, which
essentially only works on Linux, and assumes one can't do lto with
anything other than lld. Which is not true. As a matter of fact, even
ld.bfd can do lto, as long as the gold plugin for llvm is available,
or when doing lto with GCC instead of clang.
Anyways, to allow more lto setups, we adapt the --enable-linker setup
to:
- work on macOS, which it currently doesn't, and add support for the mac
linker (ld64), which, unfortunately, doesn't have a clean way to be
detected, so work around that.
- default to lld if lto is enable, no linker was explicitly given, the
compiler is clang *and* the build target is not macOS.
--HG--
extra : rebase_source : 1dab2ad6230d18e7f4285943e76352e23b987d4e
2018-07-05 05:35:31 +03:00
|
|
|
def get_cmd_output(*args, **kwargs):
|
|
|
|
log.debug('Executing: `%s`', quote(*args))
|
|
|
|
proc = subprocess.Popen(args, stdout=subprocess.PIPE,
|
2018-10-10 02:15:13 +03:00
|
|
|
stderr=subprocess.PIPE,
|
|
|
|
# On Python 2 on Windows, close_fds prevents the
|
|
|
|
# process from inheriting stdout/stderr.
|
|
|
|
# Elsewhere, it simply prevents it from inheriting
|
|
|
|
# extra file descriptors, which is what we want.
|
|
|
|
close_fds=os.name != 'nt',
|
|
|
|
**kwargs)
|
Bug 1469088 - Relax the assumptions of --enable-lto, and make it work for macOS builds. r=ted
Currently, --enable-lto just implies --enable-linker=lld, which
essentially only works on Linux, and assumes one can't do lto with
anything other than lld. Which is not true. As a matter of fact, even
ld.bfd can do lto, as long as the gold plugin for llvm is available,
or when doing lto with GCC instead of clang.
Anyways, to allow more lto setups, we adapt the --enable-linker setup
to:
- work on macOS, which it currently doesn't, and add support for the mac
linker (ld64), which, unfortunately, doesn't have a clean way to be
detected, so work around that.
- default to lld if lto is enable, no linker was explicitly given, the
compiler is clang *and* the build target is not macOS.
--HG--
extra : rebase_source : 1dab2ad6230d18e7f4285943e76352e23b987d4e
2018-07-05 05:35:31 +03:00
|
|
|
stdout, stderr = proc.communicate()
|
2019-08-20 19:43:15 +03:00
|
|
|
stdout = stdout.decode(system_encoding, 'replace')
|
|
|
|
stderr = stderr.decode(system_encoding, 'replace')
|
Bug 1469088 - Relax the assumptions of --enable-lto, and make it work for macOS builds. r=ted
Currently, --enable-lto just implies --enable-linker=lld, which
essentially only works on Linux, and assumes one can't do lto with
anything other than lld. Which is not true. As a matter of fact, even
ld.bfd can do lto, as long as the gold plugin for llvm is available,
or when doing lto with GCC instead of clang.
Anyways, to allow more lto setups, we adapt the --enable-linker setup
to:
- work on macOS, which it currently doesn't, and add support for the mac
linker (ld64), which, unfortunately, doesn't have a clean way to be
detected, so work around that.
- default to lld if lto is enable, no linker was explicitly given, the
compiler is clang *and* the build target is not macOS.
--HG--
extra : rebase_source : 1dab2ad6230d18e7f4285943e76352e23b987d4e
2018-07-05 05:35:31 +03:00
|
|
|
return proc.wait(), stdout, stderr
|
|
|
|
|
|
|
|
|
|
|
|
# A wrapper to obtain a process' output that returns the output generated
|
|
|
|
# by running the given command if it exits normally, and streams that
|
|
|
|
# output to log.debug and calls die or the given error callback if it
|
|
|
|
# does not.
|
|
|
|
@imports(_from='mozbuild.configure.util', _import='LineIO')
|
|
|
|
@imports(_from='mozbuild.shellutil', _import='quote')
|
|
|
|
def check_cmd_output(*args, **kwargs):
|
|
|
|
onerror = kwargs.pop('onerror', None)
|
|
|
|
|
2016-05-18 00:40:03 +03:00
|
|
|
with log.queue_debug():
|
Bug 1469088 - Relax the assumptions of --enable-lto, and make it work for macOS builds. r=ted
Currently, --enable-lto just implies --enable-linker=lld, which
essentially only works on Linux, and assumes one can't do lto with
anything other than lld. Which is not true. As a matter of fact, even
ld.bfd can do lto, as long as the gold plugin for llvm is available,
or when doing lto with GCC instead of clang.
Anyways, to allow more lto setups, we adapt the --enable-linker setup
to:
- work on macOS, which it currently doesn't, and add support for the mac
linker (ld64), which, unfortunately, doesn't have a clean way to be
detected, so work around that.
- default to lld if lto is enable, no linker was explicitly given, the
compiler is clang *and* the build target is not macOS.
--HG--
extra : rebase_source : 1dab2ad6230d18e7f4285943e76352e23b987d4e
2018-07-05 05:35:31 +03:00
|
|
|
retcode, stdout, stderr = get_cmd_output(*args, **kwargs)
|
2016-05-18 00:40:03 +03:00
|
|
|
if retcode == 0:
|
|
|
|
return stdout
|
|
|
|
|
|
|
|
log.debug('The command returned non-zero exit status %d.',
|
|
|
|
retcode)
|
|
|
|
for out, desc in ((stdout, 'output'), (stderr, 'error output')):
|
|
|
|
if out:
|
|
|
|
log.debug('Its %s was:', desc)
|
2019-08-20 19:43:15 +03:00
|
|
|
with LineIO(lambda l: log.debug('| %s', l)) as o:
|
2016-05-18 00:40:03 +03:00
|
|
|
o.write(out)
|
|
|
|
if onerror:
|
|
|
|
return onerror()
|
|
|
|
die('Command `%s` failed with exit status %d.' %
|
|
|
|
(quote(*args), retcode))
|
2016-03-17 18:04:12 +03:00
|
|
|
|
2017-10-12 16:22:59 +03:00
|
|
|
|
2016-03-27 05:40:13 +03:00
|
|
|
@imports('os')
|
2016-03-04 11:31:10 +03:00
|
|
|
def is_absolute_or_relative(path):
|
|
|
|
if os.altsep and os.altsep in path:
|
|
|
|
return True
|
|
|
|
return os.sep in path
|
|
|
|
|
|
|
|
|
2016-03-27 05:40:13 +03:00
|
|
|
@imports(_import='mozpack.path', _as='mozpath')
|
2016-03-04 11:31:10 +03:00
|
|
|
def normsep(path):
|
|
|
|
return mozpath.normsep(path)
|
|
|
|
|
2016-07-29 17:16:05 +03:00
|
|
|
|
2016-08-16 04:11:48 +03:00
|
|
|
@imports('ctypes')
|
|
|
|
@imports(_from='ctypes', _import='wintypes')
|
|
|
|
@imports(_from='mozbuild.configure.constants', _import='WindowsBinaryType')
|
|
|
|
def windows_binary_type(path):
|
|
|
|
"""Obtain the type of a binary on Windows.
|
|
|
|
|
|
|
|
Returns WindowsBinaryType constant.
|
|
|
|
"""
|
|
|
|
GetBinaryTypeW = ctypes.windll.kernel32.GetBinaryTypeW
|
2017-10-12 16:22:59 +03:00
|
|
|
GetBinaryTypeW.argtypes = [wintypes.LPWSTR,
|
|
|
|
wintypes.POINTER(wintypes.DWORD)]
|
2016-08-16 04:11:48 +03:00
|
|
|
GetBinaryTypeW.restype = wintypes.BOOL
|
|
|
|
|
|
|
|
bin_type = wintypes.DWORD()
|
|
|
|
res = GetBinaryTypeW(path, ctypes.byref(bin_type))
|
|
|
|
if not res:
|
|
|
|
die('could not obtain binary type of %s' % path)
|
|
|
|
|
|
|
|
if bin_type.value == 0:
|
|
|
|
return WindowsBinaryType('win32')
|
|
|
|
elif bin_type.value == 6:
|
|
|
|
return WindowsBinaryType('win64')
|
|
|
|
# If we see another binary type, something is likely horribly wrong.
|
|
|
|
else:
|
|
|
|
die('unsupported binary type on %s: %s' % (path, bin_type))
|
|
|
|
|
|
|
|
|
2016-07-29 17:16:05 +03:00
|
|
|
@imports('ctypes')
|
|
|
|
@imports(_from='ctypes', _import='wintypes')
|
|
|
|
def get_GetShortPathNameW():
|
|
|
|
GetShortPathNameW = ctypes.windll.kernel32.GetShortPathNameW
|
|
|
|
GetShortPathNameW.argtypes = [wintypes.LPCWSTR, wintypes.LPWSTR,
|
|
|
|
wintypes.DWORD]
|
|
|
|
GetShortPathNameW.restype = wintypes.DWORD
|
|
|
|
return GetShortPathNameW
|
|
|
|
|
|
|
|
|
|
|
|
@template
|
|
|
|
@imports('ctypes')
|
|
|
|
@imports('platform')
|
|
|
|
@imports(_from='mozbuild.shellutil', _import='quote')
|
|
|
|
def normalize_path():
|
|
|
|
# Until the build system can properly handle programs that need quoting,
|
|
|
|
# transform those paths into their short version on Windows (e.g.
|
|
|
|
# c:\PROGRA~1...).
|
|
|
|
if platform.system() == 'Windows':
|
|
|
|
GetShortPathNameW = get_GetShortPathNameW()
|
|
|
|
|
|
|
|
def normalize_path(path):
|
|
|
|
path = normsep(path)
|
|
|
|
if quote(path) == path:
|
|
|
|
return path
|
|
|
|
size = 0
|
|
|
|
while True:
|
|
|
|
out = ctypes.create_unicode_buffer(size)
|
|
|
|
needed = GetShortPathNameW(path, out, size)
|
|
|
|
if size >= needed:
|
2016-11-01 02:06:40 +03:00
|
|
|
if ' ' in out.value:
|
2018-07-24 04:09:15 +03:00
|
|
|
die("GetShortPathName returned a long path name: `%s`. "
|
|
|
|
"Use `fsutil file setshortname' "
|
|
|
|
"to create a short name "
|
|
|
|
"for any components of this path "
|
|
|
|
"that have spaces.",
|
|
|
|
out.value)
|
2016-07-29 17:16:05 +03:00
|
|
|
return normsep(out.value)
|
|
|
|
size = needed
|
|
|
|
|
|
|
|
else:
|
|
|
|
def normalize_path(path):
|
|
|
|
return normsep(path)
|
|
|
|
|
|
|
|
return normalize_path
|
|
|
|
|
2017-10-12 16:22:59 +03:00
|
|
|
|
2016-07-29 17:16:05 +03:00
|
|
|
normalize_path = normalize_path()
|
|
|
|
|
|
|
|
|
2016-05-12 21:55:57 +03:00
|
|
|
# Locates the given program using which, or returns the given path if it
|
|
|
|
# exists.
|
|
|
|
# The `paths` parameter may be passed to search the given paths instead of
|
|
|
|
# $PATH.
|
2016-04-15 05:11:58 +03:00
|
|
|
@imports(_from='which', _import='which')
|
|
|
|
@imports(_from='which', _import='WhichError')
|
2016-05-12 21:55:57 +03:00
|
|
|
@imports('itertools')
|
2016-12-23 00:28:03 +03:00
|
|
|
@imports('sys')
|
2016-05-12 21:55:57 +03:00
|
|
|
@imports(_from='os', _import='pathsep')
|
2016-12-23 00:28:03 +03:00
|
|
|
@imports(_from='os', _import='environ')
|
2016-05-12 21:55:57 +03:00
|
|
|
def find_program(file, paths=None):
|
2016-12-23 00:28:03 +03:00
|
|
|
# The following snippet comes from `which` itself, with a slight
|
|
|
|
# modification to use lowercase extensions, because it's confusing rustup
|
|
|
|
# (on top of making results not really appealing to the eye).
|
|
|
|
|
|
|
|
# Windows has the concept of a list of extensions (PATHEXT env var).
|
|
|
|
if sys.platform.startswith("win"):
|
|
|
|
exts = [e.lower()
|
|
|
|
for e in environ.get("PATHEXT", "").split(pathsep)]
|
|
|
|
# If '.exe' is not in exts then obviously this is Win9x and
|
|
|
|
# or a bogus PATHEXT, then use a reasonable default.
|
2016-12-28 11:29:31 +03:00
|
|
|
if '.exe' not in exts:
|
2016-12-23 00:28:03 +03:00
|
|
|
exts = ['.com', '.exe', '.bat']
|
|
|
|
else:
|
|
|
|
exts = None
|
|
|
|
|
2016-03-04 11:31:10 +03:00
|
|
|
try:
|
2016-06-16 14:05:12 +03:00
|
|
|
if is_absolute_or_relative(file):
|
2016-07-29 17:16:05 +03:00
|
|
|
return normalize_path(which(os.path.basename(file),
|
2016-12-23 00:28:03 +03:00
|
|
|
[os.path.dirname(file)], exts=exts))
|
2016-05-12 21:55:57 +03:00
|
|
|
if paths:
|
|
|
|
if not isinstance(paths, (list, tuple)):
|
|
|
|
die("Paths provided to find_program must be a list of strings, "
|
|
|
|
"not %r", paths)
|
|
|
|
paths = list(itertools.chain(
|
|
|
|
*(p.split(pathsep) for p in paths if p)))
|
2019-01-29 04:17:43 +03:00
|
|
|
else:
|
|
|
|
paths = environ['PATH'].split(pathsep)
|
2016-12-23 00:28:03 +03:00
|
|
|
return normalize_path(which(file, path=paths, exts=exts))
|
2016-03-04 11:31:10 +03:00
|
|
|
except WhichError:
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
2016-07-27 01:27:19 +03:00
|
|
|
@imports('os')
|
|
|
|
@imports(_from='mozbuild.configure.util', _import='LineIO')
|
|
|
|
@imports(_from='tempfile', _import='mkstemp')
|
|
|
|
def try_invoke_compiler(compiler, language, source, flags=None, onerror=None):
|
|
|
|
flags = flags or []
|
|
|
|
|
|
|
|
if not isinstance(flags, (list, tuple)):
|
|
|
|
die("Flags provided to try_compile must be a list of strings, "
|
2019-02-08 19:56:13 +03:00
|
|
|
"not %r", flags)
|
2016-07-27 01:27:19 +03:00
|
|
|
|
|
|
|
suffix = {
|
|
|
|
'C': '.c',
|
|
|
|
'C++': '.cpp',
|
|
|
|
}[language]
|
|
|
|
|
|
|
|
fd, path = mkstemp(prefix='conftest.', suffix=suffix)
|
|
|
|
try:
|
|
|
|
source = source.encode('ascii', 'replace')
|
|
|
|
|
|
|
|
log.debug('Creating `%s` with content:', path)
|
|
|
|
with LineIO(lambda l: log.debug('| %s', l)) as out:
|
|
|
|
out.write(source)
|
|
|
|
|
|
|
|
os.write(fd, source)
|
|
|
|
os.close(fd)
|
|
|
|
cmd = compiler + list(flags) + [path]
|
|
|
|
kwargs = {'onerror': onerror}
|
|
|
|
return check_cmd_output(*cmd, **kwargs)
|
|
|
|
finally:
|
|
|
|
os.remove(path)
|
|
|
|
|
|
|
|
|
2016-03-04 12:02:39 +03:00
|
|
|
def unique_list(l):
|
|
|
|
result = []
|
|
|
|
for i in l:
|
|
|
|
if l not in result:
|
|
|
|
result.append(i)
|
|
|
|
return result
|
2016-03-09 11:41:40 +03:00
|
|
|
|
2016-07-22 09:51:34 +03:00
|
|
|
|
|
|
|
# Get values out of the Windows registry. This function can only be called on
|
|
|
|
# Windows.
|
|
|
|
# The `pattern` argument is a string starting with HKEY_ and giving the full
|
|
|
|
# "path" of the registry key to get the value for, with backslash separators.
|
|
|
|
# The string can contains wildcards ('*').
|
|
|
|
# The result of this functions is an enumerator yielding tuples for each
|
|
|
|
# match. Each of these tuples contains the key name matching wildcards
|
|
|
|
# followed by the value.
|
|
|
|
#
|
2017-07-22 13:32:24 +03:00
|
|
|
# The `get_32_and_64_bit` argument is a boolean, if True then it will return the
|
|
|
|
# values from the 32-bit and 64-bit registry views. This defaults to False,
|
|
|
|
# which will return the view depending on the bitness of python.
|
|
|
|
#
|
2016-07-22 09:51:34 +03:00
|
|
|
# Examples:
|
|
|
|
# get_registry_values(r'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\'
|
|
|
|
# r'Windows Kits\Installed Roots\KitsRoot*')
|
|
|
|
# yields e.g.:
|
|
|
|
# ('KitsRoot81', r'C:\Program Files (x86)\Windows Kits\8.1\')
|
|
|
|
# ('KitsRoot10', r'C:\Program Files (x86)\Windows Kits\10\')
|
|
|
|
#
|
|
|
|
# get_registry_values(r'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\'
|
|
|
|
# r'Windows Kits\Installed Roots\KitsRoot8.1')
|
|
|
|
# yields e.g.:
|
|
|
|
# (r'C:\Program Files (x86)\Windows Kits\8.1\',)
|
|
|
|
#
|
|
|
|
# get_registry_values(r'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\'
|
2017-07-22 13:32:24 +03:00
|
|
|
# r'Windows Kits\Installed Roots\KitsRoot8.1',
|
|
|
|
# get_32_and_64_bit=True)
|
|
|
|
# yields e.g.:
|
|
|
|
# (r'C:\Program Files (x86)\Windows Kits\8.1\',)
|
|
|
|
# (r'C:\Program Files\Windows Kits\8.1\',)
|
|
|
|
#
|
|
|
|
# get_registry_values(r'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\'
|
2016-07-22 09:51:34 +03:00
|
|
|
# r'Windows Kits\*\KitsRoot*')
|
|
|
|
# yields e.g.:
|
|
|
|
# ('Installed Roots', 'KitsRoot81',
|
|
|
|
# r'C:\Program Files (x86)\Windows Kits\8.1\')
|
|
|
|
# ('Installed Roots', 'KitsRoot10',
|
|
|
|
# r'C:\Program Files (x86)\Windows Kits\10\')
|
|
|
|
#
|
|
|
|
# get_registry_values(r'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\'
|
|
|
|
# r'VisualStudio\VC\*\x86\*\Compiler')
|
|
|
|
# yields e.g.:
|
|
|
|
# ('19.0', 'arm', r'C:\...\amd64_arm\cl.exe')
|
|
|
|
# ('19.0', 'x64', r'C:\...\amd64\cl.exe')
|
|
|
|
# ('19.0', 'x86', r'C:\...\amd64_x86\cl.exe')
|
|
|
|
@imports(_import='_winreg', _as='winreg')
|
|
|
|
@imports(_from='__builtin__', _import='WindowsError')
|
|
|
|
@imports(_from='fnmatch', _import='fnmatch')
|
2017-07-22 13:32:24 +03:00
|
|
|
def get_registry_values(pattern, get_32_and_64_bit=False):
|
2016-07-22 09:51:34 +03:00
|
|
|
def enum_helper(func, key):
|
|
|
|
i = 0
|
|
|
|
while True:
|
|
|
|
try:
|
|
|
|
yield func(key, i)
|
|
|
|
except WindowsError:
|
|
|
|
break
|
|
|
|
i += 1
|
|
|
|
|
2017-07-22 13:32:24 +03:00
|
|
|
def get_keys(key, pattern, access_mask):
|
2016-07-22 09:51:34 +03:00
|
|
|
try:
|
2017-07-22 13:32:24 +03:00
|
|
|
s = winreg.OpenKey(key, '\\'.join(pattern[:-1]), 0, access_mask)
|
2016-07-22 09:51:34 +03:00
|
|
|
except WindowsError:
|
|
|
|
return
|
|
|
|
for k in enum_helper(winreg.EnumKey, s):
|
|
|
|
if fnmatch(k, pattern[-1]):
|
|
|
|
try:
|
2017-07-22 13:32:24 +03:00
|
|
|
yield k, winreg.OpenKey(s, k, 0, access_mask)
|
2016-07-22 09:51:34 +03:00
|
|
|
except WindowsError:
|
|
|
|
pass
|
|
|
|
|
2017-07-22 13:32:24 +03:00
|
|
|
def get_values(key, pattern, access_mask):
|
2016-07-22 09:51:34 +03:00
|
|
|
try:
|
2017-07-22 13:32:24 +03:00
|
|
|
s = winreg.OpenKey(key, '\\'.join(pattern[:-1]), 0, access_mask)
|
2016-07-22 09:51:34 +03:00
|
|
|
except WindowsError:
|
|
|
|
return
|
|
|
|
for k, v, t in enum_helper(winreg.EnumValue, s):
|
|
|
|
if fnmatch(k, pattern[-1]):
|
|
|
|
yield k, v
|
|
|
|
|
|
|
|
def split_pattern(pattern):
|
|
|
|
subpattern = []
|
|
|
|
for p in pattern:
|
|
|
|
subpattern.append(p)
|
|
|
|
if '*' in p:
|
|
|
|
yield subpattern
|
|
|
|
subpattern = []
|
|
|
|
if subpattern:
|
|
|
|
yield subpattern
|
|
|
|
|
2017-07-22 13:32:24 +03:00
|
|
|
def get_all_values(keys, pattern, access_mask):
|
|
|
|
for i, p in enumerate(pattern):
|
|
|
|
next_keys = []
|
|
|
|
for base_key in keys:
|
|
|
|
matches = base_key[:-1]
|
|
|
|
base_key = base_key[-1]
|
|
|
|
if i == len(pattern) - 1:
|
|
|
|
want_name = '*' in p[-1]
|
|
|
|
for name, value in get_values(base_key, p, access_mask):
|
|
|
|
yield matches + ((name, value) if want_name else (value,))
|
|
|
|
else:
|
|
|
|
for name, k in get_keys(base_key, p, access_mask):
|
|
|
|
next_keys.append(matches + (name, k))
|
|
|
|
keys = next_keys
|
|
|
|
|
2016-07-22 09:51:34 +03:00
|
|
|
pattern = pattern.split('\\')
|
|
|
|
assert pattern[0].startswith('HKEY_')
|
|
|
|
keys = [(getattr(winreg, pattern[0]),)]
|
|
|
|
pattern = list(split_pattern(pattern[1:]))
|
2017-07-22 13:32:24 +03:00
|
|
|
if get_32_and_64_bit:
|
|
|
|
for match in get_all_values(keys, pattern, winreg.KEY_READ | winreg.KEY_WOW64_32KEY):
|
|
|
|
yield match
|
|
|
|
for match in get_all_values(keys, pattern, winreg.KEY_READ | winreg.KEY_WOW64_64KEY):
|
|
|
|
yield match
|
|
|
|
else:
|
|
|
|
for match in get_all_values(keys, pattern, winreg.KEY_READ):
|
|
|
|
yield match
|
2016-07-22 09:51:34 +03:00
|
|
|
|
|
|
|
|
2016-03-27 05:40:13 +03:00
|
|
|
@imports(_from='mozbuild.configure.util', _import='Version', _as='_Version')
|
2016-03-17 18:52:18 +03:00
|
|
|
def Version(v):
|
|
|
|
'A version number that can be compared usefully.'
|
|
|
|
return _Version(v)
|
2016-03-09 11:41:40 +03:00
|
|
|
|
|
|
|
# Denotes a deprecated option. Combines option() and @depends:
|
|
|
|
# @deprecated_option('--option')
|
|
|
|
# def option(value):
|
|
|
|
# ...
|
|
|
|
# @deprecated_option() takes the same arguments as option(), except `help`.
|
|
|
|
# The function may handle the option like a typical @depends function would,
|
|
|
|
# but it is recommended it emits a deprecation error message suggesting an
|
|
|
|
# alternative option to use if there is one.
|
2017-10-12 16:22:59 +03:00
|
|
|
|
|
|
|
|
2016-03-09 11:41:40 +03:00
|
|
|
@template
|
|
|
|
def deprecated_option(*args, **kwargs):
|
|
|
|
assert 'help' not in kwargs
|
|
|
|
kwargs['help'] = 'Deprecated'
|
|
|
|
opt = option(*args, **kwargs)
|
|
|
|
|
|
|
|
def decorator(func):
|
|
|
|
@depends(opt.option)
|
|
|
|
def deprecated(value):
|
|
|
|
if value.origin != 'default':
|
|
|
|
return func(value)
|
|
|
|
return deprecated
|
|
|
|
|
|
|
|
return decorator
|
Bug 1255305 - Move --host and --target to moz.configure. r=chmanchester
With all the things that still depend on all the variables derived from
--host and --target in both old-configure and moz.build, we still need
to keep variables such as OS_ARCH, OS_TARGET, CPU_ARCH, OS_TEST, etc.
Eventually, we'd settle on the output of split_triplet.
This /tries/ to preserve the current values for all these variables,
while also trying to make things a little more consistent. It also
effectively rejects OSes such as HPUX or AIX, because it is unclear
the decades old accumulated scripts related to them still do anything
useful, and we might as well have them start again from scratch, which,
in the coming weeks, will be even easier.
2016-03-11 16:57:15 +03:00
|
|
|
|
|
|
|
|
|
|
|
# from mozbuild.util import ReadOnlyNamespace as namespace
|
2016-03-27 05:40:13 +03:00
|
|
|
@imports(_from='mozbuild.util', _import='ReadOnlyNamespace')
|
Bug 1255305 - Move --host and --target to moz.configure. r=chmanchester
With all the things that still depend on all the variables derived from
--host and --target in both old-configure and moz.build, we still need
to keep variables such as OS_ARCH, OS_TARGET, CPU_ARCH, OS_TEST, etc.
Eventually, we'd settle on the output of split_triplet.
This /tries/ to preserve the current values for all these variables,
while also trying to make things a little more consistent. It also
effectively rejects OSes such as HPUX or AIX, because it is unclear
the decades old accumulated scripts related to them still do anything
useful, and we might as well have them start again from scratch, which,
in the coming weeks, will be even easier.
2016-03-11 16:57:15 +03:00
|
|
|
def namespace(**kwargs):
|
|
|
|
return ReadOnlyNamespace(**kwargs)
|
2016-03-22 08:21:32 +03:00
|
|
|
|
|
|
|
|
2016-08-09 09:54:20 +03:00
|
|
|
# Turn an object into an object that can be used as an argument to @depends.
|
|
|
|
# The given object can be a literal value, a function that takes no argument,
|
|
|
|
# or, for convenience, a @depends function.
|
|
|
|
@template
|
|
|
|
@imports(_from='inspect', _import='isfunction')
|
2016-10-13 06:45:24 +03:00
|
|
|
@imports(_from='mozbuild.configure', _import='SandboxDependsFunction')
|
2016-08-09 09:54:20 +03:00
|
|
|
def dependable(obj):
|
2016-10-13 06:45:24 +03:00
|
|
|
if isinstance(obj, SandboxDependsFunction):
|
2016-08-09 09:54:20 +03:00
|
|
|
return obj
|
|
|
|
if isfunction(obj):
|
2016-10-27 09:00:51 +03:00
|
|
|
return depends(when=True)(obj)
|
|
|
|
return depends(when=True)(lambda: obj)
|
2016-08-09 09:54:20 +03:00
|
|
|
|
|
|
|
|
|
|
|
always = dependable(True)
|
|
|
|
never = dependable(False)
|
|
|
|
|
|
|
|
|
2017-07-26 08:00:38 +03:00
|
|
|
# Create a decorator that will only execute the body of a function
|
|
|
|
# if the passed function returns True when passed all positional
|
|
|
|
# arguments.
|
2016-03-24 09:26:32 +03:00
|
|
|
@template
|
2017-07-26 08:00:38 +03:00
|
|
|
def depends_tmpl(eval_args_fn, *args, **kwargs):
|
2017-05-13 01:12:56 +03:00
|
|
|
if kwargs:
|
|
|
|
assert len(kwargs) == 1
|
|
|
|
when = kwargs['when']
|
|
|
|
else:
|
|
|
|
when = None
|
2017-10-12 16:22:59 +03:00
|
|
|
|
2016-03-24 09:26:32 +03:00
|
|
|
def decorator(func):
|
2017-05-13 01:12:56 +03:00
|
|
|
@depends(*args, when=when)
|
2016-03-24 09:26:32 +03:00
|
|
|
def wrapper(*args):
|
2017-07-26 08:00:38 +03:00
|
|
|
if eval_args_fn(args):
|
2016-03-24 09:26:32 +03:00
|
|
|
return func(*args)
|
|
|
|
return wrapper
|
|
|
|
return decorator
|
2016-05-18 00:40:03 +03:00
|
|
|
|
2017-07-26 08:00:38 +03:00
|
|
|
|
|
|
|
# Like @depends, but the decorated function is only called if one of the
|
|
|
|
# arguments it would be called with has a positive value (bool(value) is True)
|
|
|
|
@template
|
|
|
|
def depends_if(*args, **kwargs):
|
|
|
|
return depends_tmpl(any, *args, **kwargs)
|
|
|
|
|
|
|
|
|
|
|
|
# Like @depends, but the decorated function is only called if all of the
|
|
|
|
# arguments it would be called with have a positive value.
|
|
|
|
@template
|
|
|
|
def depends_all(*args, **kwargs):
|
|
|
|
return depends_tmpl(all, *args, **kwargs)
|
|
|
|
|
|
|
|
|
2016-11-15 08:35:22 +03:00
|
|
|
# Hacks related to old-configure
|
|
|
|
# ==============================
|
|
|
|
|
|
|
|
@dependable
|
|
|
|
def old_configure_assignments():
|
|
|
|
return []
|
|
|
|
|
2017-10-12 16:22:59 +03:00
|
|
|
|
2016-11-15 08:35:22 +03:00
|
|
|
@dependable
|
|
|
|
def extra_old_configure_args():
|
|
|
|
return []
|
|
|
|
|
2017-10-12 16:22:59 +03:00
|
|
|
|
2016-11-15 08:35:22 +03:00
|
|
|
@template
|
2018-10-04 16:54:18 +03:00
|
|
|
def add_old_configure_assignment(var, value, when=None):
|
2016-11-15 08:35:22 +03:00
|
|
|
var = dependable(var)
|
|
|
|
value = dependable(value)
|
|
|
|
|
2018-10-04 16:54:18 +03:00
|
|
|
@depends(old_configure_assignments, var, value, when=when)
|
2016-11-15 08:35:22 +03:00
|
|
|
@imports(_from='mozbuild.shellutil', _import='quote')
|
|
|
|
def add_assignment(assignments, var, value):
|
|
|
|
if var is None or value is None:
|
|
|
|
return
|
|
|
|
if value is True:
|
2019-01-17 02:06:41 +03:00
|
|
|
assignments.append((var, '1'))
|
2016-11-15 08:35:22 +03:00
|
|
|
elif value is False:
|
2019-01-17 02:06:41 +03:00
|
|
|
assignments.append((var, ''))
|
2016-11-15 08:35:22 +03:00
|
|
|
else:
|
|
|
|
if isinstance(value, (list, tuple)):
|
|
|
|
value = quote(*value)
|
2019-01-17 02:06:41 +03:00
|
|
|
assignments.append((var, str(value)))
|
2016-11-15 08:35:22 +03:00
|
|
|
|
2017-10-12 16:22:59 +03:00
|
|
|
|
2016-11-15 08:35:22 +03:00
|
|
|
@template
|
|
|
|
def add_old_configure_arg(arg):
|
|
|
|
@depends(extra_old_configure_args, arg)
|
|
|
|
def add_arg(args, arg):
|
|
|
|
if arg:
|
|
|
|
args.append(arg)
|