diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 21cc8bb0a65d..201edfe6d6d4 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -1216,7 +1216,7 @@ def create_test_serialisation(self, tests: T.List['Test']) -> T.List[TestSeriali extra_bdeps: T.List[build.BuildTargetTypes] = [] if isinstance(exe, build.CustomTarget): extra_bdeps = list(exe.get_transitive_build_target_deps()) - extra_bdeps.extend(t.depends) + extra_bdeps.extend(d for d in t.depends if isinstance(d, build.BuildTarget)) extra_bdeps.extend(a for a in t.cmd_args if isinstance(a, build.BuildTarget)) extra_paths = self.determine_windows_extra_paths(exe, extra_bdeps) else: diff --git a/test cases/windows/13 test argument extra paths/test/meson.build b/test cases/windows/13 test argument extra paths/test/meson.build index 4daccaea669b..fa4ec5ed1b5b 100644 --- a/test cases/windows/13 test argument extra paths/test/meson.build +++ b/test cases/windows/13 test argument extra paths/test/meson.build @@ -1,3 +1,13 @@ python3 = find_program('python3') test('run_exe', python3, args: [files('test_run_exe.py')[0], barexe]) + +stamp = custom_target('stamp', + output: 'stamp.txt', + command: [python3, '-c', 'open("@OUTPUT@", "w").close()'], + build_by_default: true, +) + +test('run_exe_with_custom_depends', python3, + args: [files('test_run_exe.py')[0], barexe], + depends: stamp) diff --git a/unittests/windowstests.py b/unittests/windowstests.py index a6f9e264ffbb..fe3d91cdfff6 100644 --- a/unittests/windowstests.py +++ b/unittests/windowstests.py @@ -490,3 +490,42 @@ def test_vsenv_option(self): with mock.patch.object(self, 'install_command', self.meson_command + ['install']): out = self.install(override_envvars=env) self.assertIn('Activating VS', out) + + def test_custom_target_in_depends_no_extra_paths_bloat(self): + ''' + Test that when a test depends on a non-BuildTarget, the extra_paths does + not include parent directories from that non-BuildTarget. + + This is a regression test for: when t.depends contained non-BuildTarget + items (like CustomTarget), they were incorrectly added to extra_bdeps + and their parent directories could end up in the PATH, causing bloat. + + See: https://www.postgresql.org/message-id/CAD5tBcJXAX8bz5q9ngE4znvVLiXaPO89D0yTFhJgEPrPyT-Erw@mail.gmail.com + ''' + testdir = os.path.join(self.platform_test_dir, '13 test argument extra paths') + self.init(testdir) + + tests = self.introspect('--tests') + test_with_custom_depends = None + for t in tests: + if t['name'] == 'run_exe_with_custom_depends': + test_with_custom_depends = t + break + + self.assertIsNotNone(test_with_custom_depends, 'Test run_exe_with_custom_depends not found') + + extra_paths = test_with_custom_depends.get('extra_paths', []) + self.assertIsInstance(extra_paths, list) + + # The executable 'barexe' links against libfoo, so the lib directory + # should be in extra_paths (so the DLL can be found at runtime). + self.assertTrue(any('lib' in p for p in extra_paths) or len(extra_paths) == 0, + f'extra_paths should contain a lib directory or be empty: {extra_paths}') + + # The test depends on a CustomTarget in the test subdirectory. + # The CustomTarget's parent directory should NOT appear in extra_paths. + for path in extra_paths: + self.assertNotIn('test', path, + 'extra_paths should not include the test subdirectory. ' + 'This would indicate that non-BuildTarget dependencies are incorrectly ' + 'adding their parent directories to PATH.')