diff options
| author | Thibault Saunier <tsaunier@igalia.com> | 2019-08-01 17:13:29 -0700 | 
|---|---|---|
| committer | Thibault Saunier <tsaunier@igalia.com> | 2019-08-24 06:43:47 -0400 | 
| commit | 42c5e4fe2b21a8f70f62e0153d0098b3d186259f (patch) | |
| tree | f7c0074b4cf483351f6d88edd329328760ce1b60 | |
| parent | e3b21de5630e009f130d2e160a6fc125b5f84e31 (diff) | |
| download | meson-42c5e4fe2b21a8f70f62e0153d0098b3d186259f.tar.gz | |
wine: Try to get the short paths when generating WINEPATH
The size of WINEPATH is limited (1024 [until recently]), we
can very easily reach that limit, and even the new one (2048) so
try to keep path as small as possible by using the shortPath
version of paths.
Also assert that we do not reach the new hard limit.
And avoid having duplicates in the list of path.
[until recently]: https://bugs.winehq.org/show_bug.cgi?id=45810
| -rw-r--r-- | mesonbuild/mesonlib.py | 34 | ||||
| -rw-r--r-- | mesonbuild/mtest.py | 20 | ||||
| -rw-r--r-- | mesonbuild/scripts/meson_exe.py | 12 | 
3 files changed, 48 insertions, 18 deletions
diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py index bf87f0f7e..133302781 100644 --- a/mesonbuild/mesonlib.py +++ b/mesonbuild/mesonlib.py @@ -22,6 +22,7 @@ import collections  from enum import Enum  from functools import lru_cache  import typing +import uuid  from mesonbuild import mlog @@ -1375,3 +1376,36 @@ try:              super().__init__(*args, **kwargs)  except ImportError:      ProgressBar = ProgressBarFallback + + +def get_wine_shortpath(winecmd, wine_paths): + +    """ Get A short version of @wine_paths to avoid +    reaching WINEPATH number of char limit. +    """ + +    seen = set() +    wine_paths = [p for p in wine_paths if not (p in seen or seen.add(p))] + +    getShortPathScript = '%s.bat' % str(uuid.uuid4()).lower()[:5] +    with open(getShortPathScript, mode='w') as f: +        f.write("@ECHO OFF\nfor %%x in (%*) do (\n echo|set /p=;%~sx\n)\n") +        f.flush() +    try: +        with open(os.devnull, 'w') as stderr: +            wine_path = subprocess.check_output( +                winecmd + +                ['cmd', '/C', getShortPathScript] + wine_paths, +                stderr=stderr).decode('utf-8') +    except subprocess.CalledProcessError as e: +        print("Could not get short paths: %s" % e) +        wine_path = ';'.join(wine_paths) +    finally: +        os.remove(getShortPathScript) +    if len(wine_path) > 2048: +        raise MesonException( +            'WINEPATH size {} > 2048' +            ' this will cause random failure.'.format( +                len(wine_path))) + +    return wine_path.strip(';') diff --git a/mesonbuild/mtest.py b/mesonbuild/mtest.py index dc5c9d19e..e11c8e47c 100644 --- a/mesonbuild/mtest.py +++ b/mesonbuild/mtest.py @@ -41,7 +41,7 @@ from . import build  from . import environment  from . import mlog  from .dependencies import ExternalProgram -from .mesonlib import substring_is_in_list, MesonException +from .mesonlib import MesonException, get_wine_shortpath  if typing.TYPE_CHECKING:      from .backend.backends import TestSerialisation @@ -488,15 +488,15 @@ class SingleTestRunner:          if len(self.test.extra_paths) > 0:              self.env['PATH'] = os.pathsep.join(self.test.extra_paths + ['']) + self.env['PATH'] -            if substring_is_in_list('wine', cmd): -                wine_paths = ['Z:' + p for p in self.test.extra_paths] -                wine_path = ';'.join(wine_paths) -                # Don't accidentally end with an `;` because that will add the -                # current directory and might cause unexpected behaviour -                if 'WINEPATH' in self.env: -                    self.env['WINEPATH'] = wine_path + ';' + self.env['WINEPATH'] -                else: -                    self.env['WINEPATH'] = wine_path +            winecmd = [] +            for c in cmd: +                winecmd.append(c) +                if os.path.basename(c).startswith('wine'): +                    self.env['WINEPATH'] = get_wine_shortpath( +                        winecmd, +                        ['Z:' + p for p in self.test.extra_paths] + self.env.get('WINEPATH', '').split(';') +                    ) +                    break          # If MALLOC_PERTURB_ is not set, or if it is set to an empty value,          # (i.e., the test or the environment don't explicitly set it), set diff --git a/mesonbuild/scripts/meson_exe.py b/mesonbuild/scripts/meson_exe.py index 8b34448a5..a5acb228d 100644 --- a/mesonbuild/scripts/meson_exe.py +++ b/mesonbuild/scripts/meson_exe.py @@ -52,14 +52,10 @@ def run_exe(exe):          child_env['PATH'] = (os.pathsep.join(exe.extra_paths + ['']) +                               child_env['PATH'])          if exe.exe_runner and mesonlib.substring_is_in_list('wine', exe.exe_runner.get_command()): -            wine_paths = ['Z:' + p for p in exe.extra_paths] -            wine_path = ';'.join(wine_paths) -            # Don't accidentally end with an `;` because that will add the -            # current directory and might cause unexpected behaviour -            if 'WINEPATH' in child_env: -                child_env['WINEPATH'] = wine_path + ';' + child_env['WINEPATH'] -            else: -                child_env['WINEPATH'] = wine_path +            child_env['WINEPATH'] = mesonlib.get_wine_shortpath( +                exe.exe_runner.get_command(), +                ['Z:' + p for p in exe.extra_paths] + child_env.get('WINEPATH', '').split(';') +            )      p = subprocess.Popen(cmd_args, env=child_env, cwd=exe.workdir,                           close_fds=False,  | 
