aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/mesonlib.py34
-rw-r--r--mesonbuild/mtest.py20
-rw-r--r--mesonbuild/scripts/meson_exe.py12
3 files changed, 48 insertions, 18 deletions
diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py
index bf87f0f..1333027 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 dc5c9d1..e11c8e4 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 8b34448..a5acb22 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,