diff options
| author | Xavier Claessens <xclaessens@netflix.com> | 2025-06-06 08:03:15 -0400 |
|---|---|---|
| committer | Dylan Baker <dylan@pnwbakers.com> | 2025-08-01 07:55:49 -0700 |
| commit | 56e84d35deef8aea2b0beda2ec14ca22334a7f0f (patch) | |
| tree | 210aac22e3b450363c4cfd4538b6754f3a6fa6f7 | |
| parent | 095c852ef3cb93c5fb01ca44b1632d9dd2dae207 (diff) | |
| download | meson-56e84d35deef8aea2b0beda2ec14ca22334a7f0f.tar.gz | |
wrap: wraps from subprojects can replace directories found with no wrap
If main project finds a directory subprojects/foo with no corresponding
foo.wrap, it creates a dummy PackageDefinition for it. If we later find
a subproject that has foo.wrap, replace the dummy wrap with it.
This happens for example when wrap-redirect have been deleted. It also
happens for subprojects downloaded from some Cargo.lock which does not
create a wrap-redirect.
Avoid loading the same location twice, which can happen when preparing
cargo subprojects.
5 files changed, 42 insertions, 6 deletions
diff --git a/mesonbuild/wrap/wrap.py b/mesonbuild/wrap/wrap.py index a9d1b7bf6..1cc2cee61 100644 --- a/mesonbuild/wrap/wrap.py +++ b/mesonbuild/wrap/wrap.py @@ -354,6 +354,7 @@ class Resolver: self.wrapdb: T.Dict[str, T.Any] = {} self.wrapdb_provided_deps: T.Dict[str, str] = {} self.wrapdb_provided_programs: T.Dict[str, str] = {} + self.loaded_dirs: T.Set[str] = set() self.load_wraps() self.load_netrc() self.load_wrapdb() @@ -395,6 +396,7 @@ class Resolver: # Add provided deps and programs into our lookup tables for wrap in self.wraps.values(): self.add_wrap(wrap) + self.loaded_dirs.add(self.subdir) def add_wrap(self, wrap: PackageDefinition) -> None: for k in wrap.provided_deps.keys(): @@ -439,16 +441,25 @@ class Resolver: def _merge_wraps(self, other_resolver: 'Resolver') -> None: for k, v in other_resolver.wraps.items(): - self.wraps.setdefault(k, v) - for k, v in other_resolver.provided_deps.items(): - self.provided_deps.setdefault(k, v) - for k, v in other_resolver.provided_programs.items(): - self.provided_programs.setdefault(k, v) + prev_wrap = self.wraps.get(v.directory) + if prev_wrap and prev_wrap.type is None and v.type is not None: + # This happens when a subproject has been previously downloaded + # using a wrap from another subproject and the wrap-redirect got + # deleted. In that case, the main project created a bare wrap + # for the download directory, but now we have a proper wrap. + # It also happens for wraps coming from Cargo.lock files, which + # don't create wrap-redirect. + del self.wraps[v.directory] + del self.provided_deps[v.directory] + if k not in self.wraps: + self.wraps[k] = v + self.add_wrap(v) def load_and_merge(self, subdir: str, subproject: SubProject) -> None: - if self.wrap_mode != WrapMode.nopromote: + if self.wrap_mode != WrapMode.nopromote and subdir not in self.loaded_dirs: other_resolver = Resolver(self.source_dir, subdir, subproject, self.wrap_mode, self.wrap_frontend, self.allow_insecure, self.silent) self._merge_wraps(other_resolver) + self.loaded_dirs.add(subdir) def find_dep_provider(self, packagename: str) -> T.Tuple[T.Optional[str], T.Optional[str]]: # Python's ini parser converts all key values to lowercase. diff --git a/test cases/common/282 wrap override/meson.build b/test cases/common/282 wrap override/meson.build new file mode 100644 index 000000000..76c84d6a1 --- /dev/null +++ b/test cases/common/282 wrap override/meson.build @@ -0,0 +1,8 @@ +project('wrap override') + + +subproject('sub') + +# sub has subsub.wrap that provides subsub-1.0 dependency. Even if sub itself +# does not use it, that dependency should now be available. +dependency('subsub-1.0') diff --git a/test cases/common/282 wrap override/subprojects/sub/meson.build b/test cases/common/282 wrap override/subprojects/sub/meson.build new file mode 100644 index 000000000..abefb30fc --- /dev/null +++ b/test cases/common/282 wrap override/subprojects/sub/meson.build @@ -0,0 +1,7 @@ +project('sub') + +# Simulate an optional feature that requires subsub.wrap, but that feature is +# not enabled. +if false + dependency('subsub-1.0') +endif diff --git a/test cases/common/282 wrap override/subprojects/sub/subprojects/subsub.wrap b/test cases/common/282 wrap override/subprojects/sub/subprojects/subsub.wrap new file mode 100644 index 000000000..85a1a7c51 --- /dev/null +++ b/test cases/common/282 wrap override/subprojects/sub/subprojects/subsub.wrap @@ -0,0 +1,5 @@ +[wrap-file] + + +[provide] +dependency_names = subsub-1.0 diff --git a/test cases/common/282 wrap override/subprojects/subsub/meson.build b/test cases/common/282 wrap override/subprojects/subsub/meson.build new file mode 100644 index 000000000..668dcb3b0 --- /dev/null +++ b/test cases/common/282 wrap override/subprojects/subsub/meson.build @@ -0,0 +1,5 @@ +project('sub') + +# This simulates a subproject we previously downloaded using +# subproject/sub/subproject/subsub.wrap +meson.override_dependency('subsub-1.0', declare_dependency()) |
