mesonbuild / meson

The Meson Build System
http://mesonbuild.com
Apache License 2.0
5.35k stars 1.53k forks source link

New `unique()` method on list #13195

Open bruchar1 opened 1 month ago

bruchar1 commented 1 month ago

List now have a unique() method that return a copy of the list without duplicated elements.

If other lists are provided as arguments to the method, it returns the union of all lists, without duplicated elements.

[1, 1, 2, 2, 3, 3].unique() == [1, 2, 3]
[].unique([1, 2], [2, 3], [3, 4]) == [1, 2, 3, 4]
bruchar1 commented 1 month ago

What is the use case of the new method?

In a big project, I need to compute some dependencies between parts of the project. For instance, if I have

libA_deps = ['dep1', 'dep2', 'dep3']
libB_deps = ['dep1', 'dep4']
libC_deps = libA_deps + libB_deps  # because libC depends on libA and libB

It would result in duplicated deps for libC.

This is a first step towards what is described in https://github.com/mesonbuild/meson/discussions/13189.

tristan957 commented 1 month ago

I feel like it might be better to have a set type where you could do set functions like union and intersection.

bruchar1 commented 1 month ago

I feel like it might be better to have a set type where you could do set functions like union and intersection.

This could be another option. I guess it depends whether element order is important or not.

tristan957 commented 1 month ago

At least in your example, it doesn't seem like order matters. I can't really think of a good example where an ordered unique list would be useful.

jpakkane commented 4 weeks ago

libC_deps = libA_deps + libB_deps # because libC depends on libA and libB

Could you explain why you are computing this by hand as opposed to using Meson's builtin library deduplication?

Working "in strings" is famously unreliable which is why we strongly recommend people to use things like declare_dependency instead. Is there a particular reason why you can't use it?

bruchar1 commented 3 weeks ago

As I already tried to explain in the linked discussion, there are two different cases where I need to follow the library dependencies, but in a context different from link dependencies: for translations, I need to extract strings from all dependent libraries; for tests I need to be able to compile and run unit tests from all dependent libraries. One way of doing that would be to have the dependency tree expressed as a datastructure, and to construct build, translation, and test dependencies from that. But I'm open to any other solution that could solve my problem.

eli-schwartz commented 3 weeks ago

Translations, at least, should usually be done per domain, not per library-plus-dependencies.

e.g. gettext() wants a compiled .mo named DOMAIN.mo, and calls to gettextdomain of DOMAIN mean to load translations from there. A single project will generally share translation catalogues between multiple executables/libraries so there is only one domain, though they might choose to have multiple domains for parts of the codebase with a lot of logical and code separation.

So the usual translation process I'm aware of is "scan all source files into one big translation template".

bruchar1 commented 3 weeks ago

Our current process is that we extract a .pot file for each library, then we merge all the generated .pot files into a single .pot, and a single .mo file is generated from this. The problem is that is we have productB.exe and productC.exe that both depend on libA.dll, productB doesn't need translated strings from productC, and vice-versa, but they both need translated strings from libA. What I'd like to do is to generate, for each executable, a .pot file with only the strings needed for that executable. But if I add a new dependency for that executable, I want to get the strings from that dependency too. Am I missing something?

eli-schwartz commented 3 weeks ago

What I'd like to do is to generate, for each executable, a .pot file with only the strings needed for that executable.

This is the part I'm unfamiliar with.