Browse Source

frg rebased patches plus new

Frank-Rainer Grahl 4 years ago
parent
commit
55ddcffbfc

+ 33 - 0
rel-257/frg/1496610-64a1.patch

@@ -0,0 +1,33 @@
+# HG changeset patch
+# User Adam Gashlin <agashlin@mozilla.com>
+# Date 1538704507 25200
+# Node ID 874a07fdb045b725edc2aaa656a8620ff439ec10
+# Parent  85ac938c7c465de05292420422df9282743047f3
+Bug 1496610: Don't treat ~ (tilde) in paths as special. r=glandium
+
+This fixes treatment of Windows paths, where tilde is not special,
+particularly in short file names.
+
+diff --git a/python/mozbuild/mozbuild/shellutil.py b/python/mozbuild/mozbuild/shellutil.py
+--- a/python/mozbuild/mozbuild/shellutil.py
++++ b/python/mozbuild/mozbuild/shellutil.py
+@@ -21,17 +21,17 @@ def _tokens2re(**tokens):
+     # The final pattern matches either the above pattern, or an escaped
+     # backslash, captured in the "escape" match group.
+     return re.compile('(?:%s|%s)' % (nonescaped, r'(?P<escape>\\\\)'))
+ 
+ UNQUOTED_TOKENS_RE = _tokens2re(
+   whitespace=r'[\t\r\n ]+',
+   quote=r'[\'"]',
+   comment='#',
+-  special=r'[<>&|`~(){}$;\*\?]',
++  special=r'[<>&|`(){}$;\*\?]',
+   backslashed=r'\\[^\\]',
+ )
+ 
+ DOUBLY_QUOTED_TOKENS_RE = _tokens2re(
+   quote='"',
+   backslashedquote=r'\\"',
+   special='\$',
+   backslashed=r'\\[^\\"]',
+

+ 468 - 0
rel-257/frg/1515528-3-66a1.patch

@@ -0,0 +1,468 @@
+# HG changeset patch
+# User Mike Hommey <mh+mozilla@glandium.org>
+# Date 1547166031 0
+# Node ID f1ec67ff78066b5a20fab4e1900166b005b46d46
+# Parent  fa4cdfbb91fab65c3bd8f606b5b3ce3076f24b07
+Bug 1515528 - Detect MSVC paths separately for host and target. r=chmanchester
+
+Because MSVC compilers only support one architecture, we need to search
+"cl" in different toolchain search paths for each of the host and
+target, especially when they are different.
+
+Likewise for the library paths for the linker. Ideally we'd pass
+-LIBPATH both for host and target, but that has implications for rust
+that I don't want to have to figure just now.
+
+Depends on D15263
+
+Differential Revision: https://phabricator.services.mozilla.com/D15264
+
+diff --git a/build/moz.configure/toolchain.configure b/build/moz.configure/toolchain.configure
+--- a/build/moz.configure/toolchain.configure
++++ b/build/moz.configure/toolchain.configure
+@@ -609,90 +609,113 @@ js_option('--with-visual-studio-version'
+ 
+ 
+ @depends('--with-visual-studio-version')
+ def vs_major_version(value):
+     if value:
+         return {'2017': 15}[value[0]]
+ 
+ 
+-@depends(host, target, vs_major_version, check_build_environment, '--with-visual-studio-version')
+-@imports(_from='__builtin__', _import='sorted')
+-@imports(_from='operator', _import='itemgetter')
+-@imports('platform')
+-def vc_compiler_path(host, target, vs_major_version, env, vs_release_name):
+-    if host.kernel != 'WINNT':
+-        return
+-    vc_target = {
+-        'x86': 'x86',
+-        'x86_64': 'x64',
+-        'arm': 'arm',
+-        'aarch64': 'arm64'
+-    }.get(target.cpu)
+-    if vc_target is None:
+-        return
++@template
++def vc_compiler_path_for(host_or_target):
++    @depends(host, host_or_target, vs_major_version, check_build_environment,
++             '--with-visual-studio-version')
++    @imports(_from='__builtin__', _import='sorted')
++    @imports(_from='operator', _import='itemgetter')
++    @imports('platform')
++    def vc_compiler_path(host, target, vs_major_version, env, vs_release_name):
++        if host.kernel != 'WINNT':
++            return
++        vc_target = {
++            'x86': 'x86',
++            'x86_64': 'x64',
++            'arm': 'arm',
++            'aarch64': 'arm64'
++        }.get(target.cpu)
++        if vc_target is None:
++            return
+ 
+-    all_versions = sorted(get_vc_paths(env.topsrcdir), key=itemgetter(0))
+-    if not all_versions:
+-        return
+-    if vs_major_version:
+-        versions = [d for (v, d) in all_versions if v.major ==
+-                    vs_major_version]
+-        if not versions:
+-            die('Visual Studio %s could not be found!' % vs_release_name)
+-        data = versions[0]
+-    else:
+-        # Choose the newest version.
+-        data = all_versions[-1][1]
+-    paths = data.get(vc_target)
+-    if not paths:
+-        return
+-    return paths
++        all_versions = sorted(get_vc_paths(env.topsrcdir), key=itemgetter(0))
++        if not all_versions:
++            return
++        if vs_major_version:
++            versions = [d for (v, d) in all_versions if v.major ==
++                        vs_major_version]
++            if not versions:
++                die('Visual Studio %s could not be found!' % vs_release_name)
++            data = versions[0]
++        else:
++            # Choose the newest version.
++            data = all_versions[-1][1]
++        paths = data.get(vc_target)
++        if not paths:
++            return
++        return paths
++    return vc_compiler_path
++
++
++vc_compiler_path = vc_compiler_path_for(target)
++host_vc_compiler_path = vc_compiler_path_for(host)
+ 
+ 
+ @dependable
+ @imports('os')
+ @imports(_from='os', _import='environ')
+ def original_path():
+     return environ['PATH'].split(os.pathsep)
+ 
+ 
+-@depends(vc_compiler_path, original_path)
+-@imports('os')
+-@imports(_from='os', _import='environ')
+-def toolchain_search_path(vc_compiler_path, original_path):
+-    result = list(original_path)
++@template
++def toolchain_search_path_for(host_or_target):
++    vc_path = {
++        host: host_vc_compiler_path,
++        target: vc_compiler_path,
++    }[host_or_target]
+ 
+-    if vc_compiler_path:
+-        # The second item, if there is one, is necessary to have in $PATH for
+-        # Windows to load the required DLLs from there.
+-        if len(vc_compiler_path) > 1:
+-            environ['PATH'] = os.pathsep.join(result + vc_compiler_path[1:])
++    @depends(vc_path, original_path)
++    @imports('os')
++    @imports(_from='os', _import='environ')
++    def toolchain_search_path(vc_compiler_path, original_path):
++        result = list(original_path)
+ 
+-        # The first item is where the programs are going to be
+-        result.append(vc_compiler_path[0])
++        if vc_compiler_path:
++            # The second item, if there is one, is necessary to have in $PATH for
++            # Windows to load the required DLLs from there.
++            if len(vc_compiler_path) > 1:
++                environ['PATH'] = os.pathsep.join(result + vc_compiler_path[1:])
++
++            # The first item is where the programs are going to be
++            result.append(vc_compiler_path[0])
+ 
+-    # Also add in the location to which `mach bootstrap` or
+-    # `mach artifact toolchain` installs clang.
+-    mozbuild_state_dir = environ.get('MOZBUILD_STATE_PATH',
+-                                     os.path.expanduser(os.path.join('~', '.mozbuild')))
+-    bootstrap_clang_path = os.path.join(mozbuild_state_dir, 'clang', 'bin')
+-    result.append(bootstrap_clang_path)
++        # Also add in the location to which `mach bootstrap` or
++        # `mach artifact toolchain` installs clang.
++        mozbuild_state_dir = environ.get('MOZBUILD_STATE_PATH',
++                                         os.path.expanduser(os.path.join('~', '.mozbuild')))
++        bootstrap_clang_path = os.path.join(mozbuild_state_dir, 'clang', 'bin')
++        result.append(bootstrap_clang_path)
+ 
+-    return result
++        return result
++    return toolchain_search_path
++
++
++toolchain_search_path = toolchain_search_path_for(target)
++host_toolchain_search_path = toolchain_search_path_for(host)
+ 
+ 
+ # As a workaround until bug 1516228 and bug 1516253 are fixed, set the PATH
+ # variable for the build to contain the toolchain search path.
+-@depends(toolchain_search_path)
++@depends(toolchain_search_path, host_toolchain_search_path)
+ @imports('os')
+ @imports(_from='os', _import='environ')
+-def altered_path(toolchain_search_path):
++def altered_path(toolchain_search_path, host_toolchain_search_path):
+     path = environ['PATH'].split(os.pathsep)
+     altered_path = list(toolchain_search_path)
++    for p in host_toolchain_search_path:
++        if p not in altered_path:
++            altered_path.append(p)
+     for p in path:
+         if p not in altered_path:
+             altered_path.append(p)
+     return os.pathsep.join(altered_path)
+ 
+ 
+ set_config('PATH', altered_path)
+ 
+@@ -734,16 +757,20 @@ def default_c_compilers(host_or_target, 
+                     # If the target C compiler is GCC, and it can't be used with
+                     # -m32/-m64 for the host, it's probably toolchain-prefixed,
+                     # so we prioritize a raw 'gcc' instead.
+                     prioritized = info.type
+             elif info.type == 'clang' and android_clang_compiler:
+                 # Android NDK clangs do not function as host compiler, so
+                 # prioritize a raw 'clang' instead.
+                 prioritized = info.type
++            elif info.type == 'msvc' and target.cpu != host_or_target.cpu:
++                # MSVC compilers only support one architecture, so we'll
++                # want a cl in another (detected) path.
++                prioritized = 'cl'
+ 
+             types = [prioritized] + [t for t in types if t != info.type]
+ 
+         gcc = ('gcc',)
+         if toolchain_prefix and host_or_target is target:
+             gcc = tuple('%sgcc' % p for p in toolchain_prefix) + gcc
+ 
+         result = []
+@@ -877,23 +904,28 @@ def compiler(language, host_or_target, c
+     what = 'the %s %s compiler' % (host_or_target_str, language)
+ 
+     option(env=var, nargs=1, help='Path to %s' % what)
+ 
+     # Handle the compiler given by the user through one of the CC/CXX/HOST_CC/
+     # HOST_CXX variables.
+     provided_compiler = provided_program(var)
+ 
++    search_path = {
++        host: host_toolchain_search_path,
++        target: toolchain_search_path,
++    }[host_or_target]
++
+     # Normally, we'd use `var` instead of `_var`, but the interaction with
+     # old-configure complicates things, and for now, we a) can't take the plain
+     # result from check_prog as CC/CXX/HOST_CC/HOST_CXX and b) have to let
+     # old-configure AC_SUBST it (because it's autoconf doing it, not us)
+     compiler = check_prog('_%s' % var, what=what, progs=default_compilers,
+                           input=provided_compiler.program,
+-                          paths=toolchain_search_path)
++                          paths=search_path)
+ 
+     @depends(compiler, provided_compiler, compiler_wrapper, host_or_target)
+     @checking('whether %s can be used' % what, lambda x: bool(x))
+     @imports(_from='mozbuild.shellutil', _import='quote')
+     def valid_compiler(compiler, provided_compiler, compiler_wrapper,
+                        host_or_target):
+         wrapper = list(compiler_wrapper or ())
+         if provided_compiler:
+diff --git a/build/moz.configure/windows.configure b/build/moz.configure/windows.configure
+--- a/build/moz.configure/windows.configure
++++ b/build/moz.configure/windows.configure
+@@ -329,76 +329,101 @@ def include_path(vc_path, windows_sdk_di
+     includes = os.pathsep.join(includes)
+     os.environ['INCLUDE'] = includes
+     return includes
+ 
+ 
+ set_config('INCLUDE', include_path)
+ 
+ 
+-@depends(target, c_compiler, vc_path, valid_windows_sdk_dir, valid_ucrt_sdk_dir, dia_sdk_dir)
+-@imports('os')
+-def lib_path(target, c_compiler, vc_path, windows_sdk_dir, ucrt_sdk_dir, dia_sdk_dir):
+-    if not vc_path:
+-        return
+-    sdk_target = {
+-        'x86': 'x86',
+-        'x86_64': 'x64',
+-        'arm': 'arm',
+-        'aarch64': 'arm64',
+-    }.get(target.cpu)
++@template
++def lib_path_for(host_or_target):
++    compiler = {
++        host: host_c_compiler,
++        target: c_compiler,
++    }[host_or_target]
++
++    @depends(host_or_target, dependable(host_or_target is host), compiler, vc_path,
++             valid_windows_sdk_dir, valid_ucrt_sdk_dir, dia_sdk_dir)
++    @imports('os')
++    def lib_path(target, is_host, c_compiler, vc_path, windows_sdk_dir, ucrt_sdk_dir, dia_sdk_dir):
++        if not vc_path:
++            return
++        sdk_target = {
++            'x86': 'x86',
++            'x86_64': 'x64',
++            'arm': 'arm',
++            'aarch64': 'arm64',
++        }.get(target.cpu)
+ 
+-    old_target = {
+-        'x86': '',
+-        'x86_64': 'amd64',
+-        'arm': 'arm',
+-        'aarch64': 'arm64'
+-    }.get(target.cpu)
+-    if old_target is None:
+-        return
+-    # As old_target can be '', and os.path.join will happily use the empty
+-    # string, leading to a string ending with a backslash, that Make will
+-    # interpret as a "string continues on next line" indicator, use variable
+-    # args.
+-    old_target = (old_target,) if old_target else ()
+-    if c_compiler.version < '19.10':
+-        # MSVC2015
+-        vc_target = old_target
+-    else:
+-        # MSVC2017 switched to use the same target naming as the sdk.
+-        vc_target = (sdk_target,)
++        old_target = {
++            'x86': '',
++            'x86_64': 'amd64',
++            'arm': 'arm',
++            'aarch64': 'arm64'
++        }.get(target.cpu)
++        if old_target is None:
++            return
++        # As old_target can be '', and os.path.join will happily use the empty
++        # string, leading to a string ending with a backslash, that Make will
++        # interpret as a "string continues on next line" indicator, use variable
++        # args.
++        old_target = (old_target,) if old_target else ()
++        if c_compiler.version < '19.10':
++            # MSVC2015
++            vc_target = old_target
++        else:
++            # MSVC2017 switched to use the same target naming as the sdk.
++            vc_target = (sdk_target,)
+ 
+-    atlmfc_dir = os.path.join(vc_path, 'atlmfc', 'lib', *vc_target)
+-    if not os.path.isdir(atlmfc_dir):
+-        die('Cannot find the ATL/MFC libraries in the Visual C++ directory '
+-            '(%s). Please install them.' % vc_path)
++        atlmfc_dir = os.path.join(vc_path, 'atlmfc', 'lib', *vc_target)
++        if not os.path.isdir(atlmfc_dir):
++            die('Cannot find the ATL/MFC libraries in the Visual C++ directory '
++                '(%s). Please install them.' % vc_path)
+ 
+-    libs = []
+-    lib_env = os.environ.get('LIB')
+-    if lib_env:
+-        libs.append(lib_env)
+-    libs.extend((
+-        os.path.join(vc_path, 'lib', *vc_target),
+-        atlmfc_dir,
+-        os.path.join(windows_sdk_dir.lib, 'um', sdk_target),
+-        os.path.join(ucrt_sdk_dir.lib, 'ucrt', sdk_target),
+-    ))
+-    if dia_sdk_dir:
+-        # For some reason the DIA SDK still uses the old-style targets
+-        # even in a newer MSVC.
+-        libs.append(os.path.join(dia_sdk_dir, 'lib', *old_target))
++        libs = []
++        lib_env = os.environ.get('LIB')
++        if lib_env and not is_host:
++            libs.extend(lib_env.split(os.pathsep))
++        libs.extend((
++            os.path.join(vc_path, 'lib', *vc_target),
++            atlmfc_dir,
++            os.path.join(windows_sdk_dir.lib, 'um', sdk_target),
++            os.path.join(ucrt_sdk_dir.lib, 'ucrt', sdk_target),
++        ))
++        if dia_sdk_dir:
++            # For some reason the DIA SDK still uses the old-style targets
++            # even in a newer MSVC.
++            libs.append(os.path.join(dia_sdk_dir, 'lib', *old_target))
++        return libs
++
++    return lib_path
++
++
++@depends(lib_path_for(target))
++@imports('os')
++def lib_path(libs):
+     # Set in the environment for old-configure
+     libs = os.pathsep.join(libs)
+     os.environ['LIB'] = libs
+     return libs
+ 
+ 
+ set_config('LIB', lib_path)
+ 
+ 
++@depends(lib_path_for(host))
++@imports(_from='mozbuild.shellutil', _import='quote')
++def host_linker_libpaths(libs):
++    return ['-LIBPATH:%s' % quote(l) for l in libs]
++
++
++set_config('HOST_LINKER_LIBPATHS', host_linker_libpaths)
++
++
+ option(env='MT', nargs=1, help='Path to the Microsoft Manifest Tool')
+ 
+ 
+ @depends(valid_windows_sdk_dir, valid_ucrt_sdk_dir)
+ @imports(_from='os', _import='environ')
+ @imports('platform')
+ def sdk_bin_path(valid_windows_sdk_dir, valid_ucrt_sdk_dir):
+     if not valid_windows_sdk_dir:
+@@ -461,14 +486,14 @@ def linker_progs_for(host_or_target):
+             return ('lld-link', 'link')
+     return linker_progs
+ 
+ 
+ link = check_prog('LINKER', linker_progs_for(target),
+                   paths=toolchain_search_path)
+ 
+ host_link = check_prog('HOST_LINKER', linker_progs_for(host),
+-                       paths=toolchain_search_path)
++                       paths=host_toolchain_search_path)
+ 
+ add_old_configure_assignment('LINKER', link)
+ 
+ 
+ check_prog('MAKECAB', ('makecab.exe',))
+diff --git a/config/rules.mk b/config/rules.mk
+--- a/config/rules.mk
++++ b/config/rules.mk
+@@ -576,17 +576,17 @@ ifdef ENABLE_STRIP
+ endif
+ ifdef MOZ_POST_PROGRAM_COMMAND
+ 	$(MOZ_POST_PROGRAM_COMMAND) $@
+ endif
+ 
+ $(HOST_PROGRAM): $(HOST_PROGOBJS) $(HOST_LIBS) $(HOST_EXTRA_DEPS) $(GLOBAL_DEPS)
+ 	$(REPORT_BUILD)
+ ifeq (_WINNT,$(GNU_CC)_$(HOST_OS_ARCH))
+-	$(HOST_LINKER) -NOLOGO -OUT:$@ -PDB:$(HOST_PDBFILE) $($(notdir $@)_OBJS) $(WIN32_EXE_LDFLAGS) $(HOST_LDFLAGS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
++	$(HOST_LINKER) -NOLOGO -OUT:$@ -PDB:$(HOST_PDBFILE) $($(notdir $@)_OBJS) $(WIN32_EXE_LDFLAGS) $(HOST_LDFLAGS) $(HOST_LINKER_LIBPATHS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
+ ifdef MSMANIFEST_TOOL
+ 	@if test -f $@.manifest; then \
+ 		if test -f '$(srcdir)/$@.manifest'; then \
+ 			echo 'Embedding manifest from $(srcdir)/$@.manifest and $@.manifest'; \
+ 			$(MT) -NOLOGO -MANIFEST '$(win_srcdir)/$@.manifest' $@.manifest -OUTPUTRESOURCE:$@\;1; \
+ 		else \
+ 			echo 'Embedding manifest from $@.manifest'; \
+ 			$(MT) -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \
+@@ -635,17 +635,17 @@ ifdef ENABLE_STRIP
+ endif
+ ifdef MOZ_POST_PROGRAM_COMMAND
+ 	$(MOZ_POST_PROGRAM_COMMAND) $@
+ endif
+ 
+ $(HOST_SIMPLE_PROGRAMS): host_%$(HOST_BIN_SUFFIX): $(HOST_LIBS) $(HOST_EXTRA_DEPS) $(GLOBAL_DEPS)
+ 	$(REPORT_BUILD)
+ ifeq (WINNT_,$(HOST_OS_ARCH)_$(GNU_CC))
+-	$(HOST_LINKER) -NOLOGO -OUT:$@ -PDB:$(HOST_PDBFILE) $($(notdir $@)_OBJS) $(WIN32_EXE_LDFLAGS) $(HOST_LDFLAGS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
++	$(HOST_LINKER) -NOLOGO -OUT:$@ -PDB:$(HOST_PDBFILE) $($(notdir $@)_OBJS) $(WIN32_EXE_LDFLAGS) $(HOST_LDFLAGS) $(HOST_LINKER_LIBPATHS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
+ else
+ ifneq (,$(HOST_CPPSRCS)$(USE_HOST_CXX))
+ 	$(HOST_CXX) $(HOST_OUTOPTION)$@ $(HOST_CXX_LDFLAGS) $($(notdir $@)_OBJS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
+ else
+ 	$(HOST_CC) $(HOST_OUTOPTION)$@ $(HOST_C_LDFLAGS) $($(notdir $@)_OBJS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
+ endif
+ endif
+ ifndef CROSS_COMPILE
+@@ -667,17 +667,17 @@ ifeq ($(OS_ARCH),WINNT)
+ # See bug 795204.
+ $(IMPORT_LIBRARY): $(SHARED_LIBRARY) ;
+ endif
+ 
+ $(HOST_SHARED_LIBRARY): Makefile
+ 	$(REPORT_BUILD)
+ 	$(RM) $@
+ ifdef _MSC_VER
+-	$(HOST_LINKER) -NOLOGO -DLL -OUT:$@ $($(notdir $@)_OBJS) $(HOST_CXX_LDFLAGS) $(HOST_LDFLAGS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
++	$(HOST_LINKER) -NOLOGO -DLL -OUT:$@ $($(notdir $@)_OBJS) $(HOST_CXX_LDFLAGS) $(HOST_LDFLAGS) $(HOST_LINKER_LIBPATHS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
+ else
+ 	$(HOST_CXX) $(HOST_OUTOPTION)$@ $($(notdir $@)_OBJS) $(HOST_CXX_LDFLAGS) $(HOST_LDFLAGS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
+ endif
+ 
+ # On Darwin (Mac OS X), dwarf2 debugging uses debug info left in .o files,
+ # so instead of deleting .o files after repacking them into a dylib, we make
+ # symlinks back to the originals. The symlinks are a no-op for stabs debugging,
+ # so no need to conditionalize on OS version or debugging format.

+ 119 - 0
rel-257/frg/1515577-66a1.patch

@@ -0,0 +1,119 @@
+# HG changeset patch
+# User Mike Hommey <mh+mozilla@glandium.org>
+# Date 1545350732 0
+# Node ID 2cb3a85f0a64c571495768b9a432c4210eb85fbc
+# Parent  28c8818e06b81f0ee302a6fec2582902bfaa1741
+Bug 1515577 - Don't quote shell strings when they contain a ~, except in first position. r=ted
+
+We only need to quote strings that would be treated specially by the
+shell, and "foo~bar" doesn't get any sort of expansion, while "~foo"
+gets a user expansion, and to avoid that expansion, those latter strings
+need to be quoted, but not the former.
+
+Differential Revision: https://phabricator.services.mozilla.com/D15065
+
+diff --git a/python/mozbuild/mozbuild/shellutil.py b/python/mozbuild/mozbuild/shellutil.py
+--- a/python/mozbuild/mozbuild/shellutil.py
++++ b/python/mozbuild/mozbuild/shellutil.py
+@@ -36,17 +36,17 @@ DOUBLY_QUOTED_TOKENS_RE = _tokens2re(
+   special='\$',
+   backslashed=r'\\[^\\"]',
+ )
+ 
+ ESCAPED_NEWLINES_RE = re.compile(r'\\\n')
+ 
+ # This regexp contains the same characters as all those listed in
+ # UNQUOTED_TOKENS_RE. Please keep in sync.
+-SHELL_QUOTE_RE = re.compile(r'[\\\t\r\n \'\"#<>&|`~(){}$;\*\?]')
++SHELL_QUOTE_RE = re.compile(r'[\\\t\r\n \'\"#<>&|`(){}$;\*\?]')
+ 
+ 
+ class MetaCharacterException(Exception):
+     def __init__(self, char):
+         self.char = char
+ 
+ 
+ class _ClineSplitter(object):
+@@ -179,17 +179,17 @@ def _quote(s):
+ 
+     As a special case, if given an int, returns a string containing the int,
+     not enclosed in quotes.
+     '''
+     if type(s) == int:
+         return '%d' % s
+ 
+     # Empty strings need to be quoted to have any significance
+-    if s and not SHELL_QUOTE_RE.search(s):
++    if s and not SHELL_QUOTE_RE.search(s) and not s.startswith('~'):
+         return s
+ 
+     # Single quoted strings can contain any characters unescaped except the
+     # single quote itself, which can't even be escaped, so the string needs to
+     # be closed, an escaped single quote added, and reopened.
+     t = type(s)
+     return t("'%s'") % s.replace(t("'"), t("'\\''"))
+ 
+diff --git a/python/mozbuild/mozbuild/test/configure/test_checks_configure.py b/python/mozbuild/mozbuild/test/configure/test_checks_configure.py
+--- a/python/mozbuild/mozbuild/test/configure/test_checks_configure.py
++++ b/python/mozbuild/mozbuild/test/configure/test_checks_configure.py
+@@ -15,16 +15,17 @@ from mozunit import (
+     MockedOpen,
+ )
+ 
+ from mozbuild.configure import (
+     ConfigureError,
+     ConfigureSandbox,
+ )
+ from mozbuild.util import exec_
++from mozbuild.shellutil import quote as shell_quote
+ from mozpack import path as mozpath
+ 
+ from buildconfig import topsrcdir
+ from common import (
+     ConfigureTestSandbox,
+     ensure_exe_extension,
+     fake_short_path,
+ )
+@@ -179,18 +180,18 @@ class TestChecksConfigure(unittest.TestC
+         self.assertEqual(status, 0)
+         self.assertEqual(config, {'FOO': self.KNOWN_B})
+         self.assertEqual(out, 'checking for foo... %s\n' % self.KNOWN_B)
+ 
+         config, out, status = self.get_result(
+             'check_prog("FOO", ("unknown", "unknown-2", "known c"))')
+         self.assertEqual(status, 0)
+         self.assertEqual(config, {'FOO': fake_short_path(self.KNOWN_C)})
+-        self.assertEqual(out, "checking for foo... '%s'\n"
+-                              % fake_short_path(self.KNOWN_C))
++        self.assertEqual(out, "checking for foo... %s\n"
++                              % shell_quote(fake_short_path(self.KNOWN_C)))
+ 
+         config, out, status = self.get_result(
+             'check_prog("FOO", ("unknown",))')
+         self.assertEqual(status, 1)
+         self.assertEqual(config, {})
+         self.assertEqual(out, textwrap.dedent('''\
+             checking for foo... not found
+             DEBUG: foo: Trying unknown
+@@ -260,18 +261,18 @@ class TestChecksConfigure(unittest.TestC
+             ERROR: Cannot find foo
+         ''') % path)
+ 
+         config, out, status = self.get_result(
+             'check_prog("FOO", ("unknown",))',
+             ['FOO=known c'])
+         self.assertEqual(status, 0)
+         self.assertEqual(config, {'FOO': fake_short_path(self.KNOWN_C)})
+-        self.assertEqual(out, "checking for foo... '%s'\n"
+-                              % fake_short_path(self.KNOWN_C))
++        self.assertEqual(out, "checking for foo... %s\n"
++                              % shell_quote(fake_short_path(self.KNOWN_C)))
+ 
+         config, out, status = self.get_result(
+             'check_prog("FOO", ("unknown", "unknown-2", "unknown 3"), '
+             'allow_missing=True)', ['FOO=unknown'])
+         self.assertEqual(status, 1)
+         self.assertEqual(config, {})
+         self.assertEqual(out, textwrap.dedent('''\
+             checking for foo... not found
+

+ 282 - 0
rel-257/frg/1515579-2only-66a1.patch

@@ -0,0 +1,282 @@
+# HG changeset patch
+# User Mike Hommey <mh+mozilla@glandium.org>
+# Date 1547163466 0
+# Node ID fa8e39feef4389d1ff83fe952c76ffba7c2217d6
+# Parent  8b8532afe5ef3203f5a496b2aceb8c29d0f38406
+Bug 1515579 - Use absolute paths for compilers, etc. r=ted
+
+In bug 1259382, some workarounds were added to make the build system
+alter PATH and not use absolute paths for toolchain programs, because
+autoconf and the build system doesn't deal with spaces in those very
+well. But later in bug 1290040, we made find_program return Windows
+short paths (without spaces), which alleviates the need for those
+workarounds.
+
+We still, however, and unfortunately, need to alter PATH to account for
+the fact that MSVC DLLs are not necessarily alongside the compiler
+executables...
+
+Depends on D15181
+
+Differential Revision: https://phabricator.services.mozilla.com/D15182
+
+diff --git a/build/moz.configure/toolchain.configure b/build/moz.configure/toolchain.configure
+--- a/build/moz.configure/toolchain.configure
++++ b/build/moz.configure/toolchain.configure
+@@ -19,16 +19,22 @@ def developer_options(value):
+         return True
+ 
+ 
+ add_old_configure_assignment('DEVELOPER_OPTIONS', developer_options)
+ set_config('DEVELOPER_OPTIONS', developer_options)
+ 
+ # PGO
+ # ==============================================================
++# LATER
++#  llvm_profdata = check_prog('LLVM_PROFDATA', ['llvm-profdata'],
++# -                           allow_missing=True)
++# +                           allow_missing=True,
++# +                           paths=toolchain_search_path)
++
+ js_option(env='MOZ_PGO', help='Build with profile guided optimizations')
+ 
+ set_config('MOZ_PGO', depends('MOZ_PGO')(lambda x: bool(x)))
+ add_old_configure_assignment('MOZ_PGO', depends('MOZ_PGO')(lambda x: bool(x)))
+ 
+ # Code optimization
+ # ==============================================================
+ 
+@@ -637,39 +643,63 @@ def vc_compiler_path(host, target, vs_ma
+         # Choose the newest version.
+         data = all_versions[-1][1]
+     paths = data.get(vc_target)
+     if not paths:
+         return
+     return paths
+ 
+ 
+-@depends(vc_compiler_path)
++@dependable
++@imports('os')
++@imports(_from='os', _import='environ')
++def original_path():
++    return environ['PATH'].split(os.pathsep)
++
++
++@depends(vc_compiler_path, original_path)
+ @imports('os')
+ @imports(_from='os', _import='environ')
+-def toolchain_search_path(vc_compiler_path):
+-    result = [environ.get('PATH')]
++def toolchain_search_path(vc_compiler_path, original_path):
++    result = list(original_path)
+ 
+     if vc_compiler_path:
+-        result.extend(vc_compiler_path)
++        # The second item, if there is one, is necessary to have in $PATH for
++        # Windows to load the required DLLs from there.
++        if len(vc_compiler_path) > 1:
++            environ['PATH'] = os.pathsep.join(result + vc_compiler_path[1:])
++
++        # The first item is where the programs are going to be
++        result.append(vc_compiler_path[0])
+ 
+     # Also add in the location to which `mach bootstrap` or
+     # `mach artifact toolchain` installs clang.
+     mozbuild_state_dir = environ.get('MOZBUILD_STATE_PATH',
+                                      os.path.expanduser(os.path.join('~', '.mozbuild')))
+     bootstrap_clang_path = os.path.join(mozbuild_state_dir, 'clang', 'bin')
+     result.append(bootstrap_clang_path)
+ 
+-    if vc_compiler_path:
+-        # We're going to alter PATH for good in windows.configure, but we also
+-        # need to do it for the valid_compiler() check below. This is only needed
+-        # on Windows, where MSVC needs PATH set to find dlls.
+-        environ['PATH'] = os.pathsep.join(result)
++    return result
++
+ 
+-    return result
++# As a workaround until bug 1516228 and bug 1516253 are fixed, set the PATH
++# variable for the build to contain the toolchain search path.
++@depends(toolchain_search_path)
++@imports('os')
++@imports(_from='os', _import='environ')
++def altered_path(toolchain_search_path):
++    path = environ['PATH'].split(os.pathsep)
++    altered_path = list(toolchain_search_path)
++    for p in path:
++        if p not in altered_path:
++            altered_path.append(p)
++    return os.pathsep.join(altered_path)
++
++
++set_config('PATH', altered_path)
+ 
+ 
+ @template
+ def default_c_compilers(host_or_target, other_c_compiler=None):
+     '''Template defining the set of default C compilers for the host and
+     target platforms.
+     `host_or_target` is either `host` or `target` (the @depends functions
+     from init.configure.
+@@ -873,36 +903,16 @@ def compiler(language, host_or_target, c
+             # --with-ccache.
+             if provided_wrapper[:len(wrapper)] == wrapper:
+                 provided_wrapper = provided_wrapper[len(wrapper):]
+             wrapper.extend(provided_wrapper)
+             flags = provided_compiler.flags
+         else:
+             flags = []
+ 
+-        # Ideally, we'd always use the absolute path, but unfortunately, on
+-        # Windows, the compiler is very often in a directory containing spaces.
+-        # Unfortunately, due to the way autoconf does its compiler tests with
+-        # eval, that doesn't work out. So in that case, check that the
+-        # compiler can still be found in $PATH, and use the file name instead
+-        # of the full path.
+-        if quote(compiler) != compiler:
+-            full_path = os.path.abspath(compiler)
+-            compiler = os.path.basename(compiler)
+-            found_compiler = find_program(compiler)
+-            if not found_compiler:
+-                die('%s is not in your $PATH'
+-                    % quote(os.path.dirname(full_path)))
+-            if os.path.normcase(find_program(compiler)) != os.path.normcase(
+-                    full_path):
+-                die('Found `%s` before `%s` in your $PATH. '
+-                    'Please reorder your $PATH.',
+-                    quote(os.path.dirname(found_compiler)),
+-                    quote(os.path.dirname(full_path)))
+-
+         info = check_compiler(wrapper + [compiler] + flags, language,
+                               host_or_target)
+ 
+         # Check that the additional flags we got are enough to not require any
+         # more flags. If we get an exception, just ignore it; it's liable to be
+         # invalid command-line flags, which means the compiler we're checking
+         # doesn't support those command-line flags and will fail one or more of
+         # the checks below.
+@@ -1602,17 +1612,18 @@ def as_info(target, c_compiler):
+ # One would expect the assembler to be specified merely as a program.  But in
+ # cases where the assembler is passed down into js/, it can be specified in
+ # the same way as CC: a program + a list of argument flags.  We might as well
+ # permit the same behavior in general, even though it seems somewhat unusual.
+ # So we have to do the same sort of dance as we did above with
+ # `provided_compiler`.
+ provided_assembler = provided_program('AS')
+ assembler = check_prog('_AS', input=provided_assembler.program,
+-                       what='the assembler', progs=as_info.names)
++                       what='the assembler', progs=as_info.names,
++                       paths=toolchain_search_path)
+ 
+ @depends(as_info, assembler, provided_assembler, c_compiler)
+ def as_with_flags(as_info, assembler, provided_assembler, c_compiler):
+     if provided_assembler:
+         return provided_assembler.wrapper + \
+             [provided_assembler.program] + \
+             provided_assembler.flags
+ 
+diff --git a/build/moz.configure/windows.configure b/build/moz.configure/windows.configure
+--- a/build/moz.configure/windows.configure
++++ b/build/moz.configure/windows.configure
+@@ -251,33 +251,29 @@ def valid_ucrt_sdk_dir(windows_sdk_dir, 
+     return namespace(
+         path=sdk.path,
+         include=sdk.include,
+         lib=sdk.lib,
+         version=version,
+     )
+ 
+ 
+-@depends(c_compiler)
++@depends(c_compiler, toolchain_search_path)
+ @imports('os')
+-def vc_path(c_compiler):
++def vc_path(c_compiler, toolchain_search_path):
+     if c_compiler.type not in ('msvc', 'clang-cl'):
+         return
+ 
+-    # Normally, we'd start from c_compiler.compiler, but for now, it's not the
+-    # ideal full path to the compiler. At least, we're guaranteed find_program
+-    # will get us the one we found in toolchain.configure.
+     vc_program = c_compiler.compiler
+ 
+     # In clang-cl builds, we use the headers and libraries from an MSVC installation.
+     if c_compiler.type == 'clang-cl':
+-        vc_program = 'cl.exe'
++        vc_program = find_program('cl.exe', paths=toolchain_search_path)
+ 
+-    cl = find_program(vc_program)
+-    result = os.path.dirname(cl)
++    result = os.path.dirname(vc_program)
+     while True:
+         next, p = os.path.split(result)
+         if next == result:
+             die('Cannot determine the Visual C++ directory the compiler (%s) '
+                 'is in' % cl)
+         result = next
+         if p.lower() == 'bin':
+             break
+@@ -454,23 +450,9 @@ link = check_prog('LINKER', ('lld-link.e
+                   paths=toolchain_search_path)
+ 
+ host_link = check_prog('HOST_LINKER', ('lld-link.exe', 'link.exe'),
+                        paths=toolchain_search_path)
+ 
+ add_old_configure_assignment('LINKER', link)
+ 
+ 
+-# Normally, we'd just have CC, etc. set to absolute paths, but the build system
+-# doesn't currently handle properly the case where the paths contain spaces.
+-# Additionally, there's the issue described in toolchain.configure, in
+-# valid_compiler().
+-@depends(sdk_bin_path)
+-@imports('os')
+-def alter_path(sdk_bin_path):
+-    path = os.pathsep.join(sdk_bin_path)
+-    os.environ['PATH'] = path
+-    return path
+-
+-
+-set_config('PATH', alter_path)
+-
+ check_prog('MAKECAB', ('makecab.exe',))
+diff --git a/toolkit/moz.configure b/toolkit/moz.configure
+--- a/toolkit/moz.configure
++++ b/toolkit/moz.configure
+@@ -1241,17 +1241,18 @@ def midl_names(c_compiler, toolchain_pre
+ def check_for_midl(target, compile_environment):
+     if target.os != 'WINNT':
+         return
+ 
+     if compile_environment:
+         return True
+ 
+ 
+-midl = check_prog('MIDL', midl_names, when=check_for_midl, allow_missing=True)
++midl = check_prog('MIDL', midl_names, when=check_for_midl, allow_missing=True,
++                  paths=sdk_bin_path)
+ 
+ 
+ @depends(c_compiler, target, when=depends(midl, target)(lambda m, t: m and t.kernel == 'WINNT'))
+ def midl_flags(c_compiler, target):
+     if c_compiler and c_compiler.type in ('msvc', 'clang-cl'):
+         env = {
+             'x86': 'win32',
+             'x86_64': 'x64',
+@@ -1313,12 +1314,13 @@ def unsigned_addon_scopes(scopes):
+ set_config('MOZ_UNSIGNED_APP_SCOPE', unsigned_addon_scopes.app)
+ set_config('MOZ_UNSIGNED_SYSTEM_SCOPE', unsigned_addon_scopes.system)
+ 
+ 
+ # Shader Compiler for Windows (and MinGW Cross Compile)
+ # ==============================================================
+ 
+ fxc = check_prog('FXC', ('fxc.exe', 'fxc2.exe'), when=depends(target)
+-                 (lambda t: t.kernel == 'WINNT'))
++                 (lambda t: t.kernel == 'WINNT'),
++                 paths=sdk_bin_path)
+ add_old_configure_assignment('FXC', fxc)
+ wine = check_prog('WINE', ['wine'], when=depends(target, host)
+                   (lambda t, h: t.kernel == 'WINNT' and h.kernel == 'Linux'))