-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow passing dict to some library() args #4159
Conversation
If the idea is approved, I'll add more tests & doc. |
5c6e7de
to
d0fe27c
Compare
As already stated in #3820, I think this is a bit weird way of doing it and complicates things quite a lot. |
I understand though that there is a need to solve this, I am just not quite convinced about the specific way it is solved in this PR. That said, I do not yet have a better idea. |
After thinking about this for a while, I could not come up with a better way of doing things, so I guess let's go with this approach. 👍 |
It is already like that for name_suffix.
The dict must map a target type to a list of compiler args. This makes possible to pass different c_args to static and shared libraries when using both_libraries(). In that case sources will be compiled twice. Closes mesonbuild#3304.
The dict must map a target type to a string. This makes possible to pass different name_prefix and name_suffix to static and shared libraries when using both_libraries(). Closes mesonbuild#4133.
d0fe27c
to
1e6cd82
Compare
Rebased and added doc. I think this is ready to be merged. @jpakkane any objection? |
The syntax for this is confusing in ways I cannot really put to words. What about something in the vein of #3820 like: x = library(...,
static_kwargs : <dict of stuff>,
shared_kwargs : <other dict of stuff>,
) |
How is that better? |
IMO this is better as it's clearer what exactly it does, while for your proposal you have to guess what it does |
No, it's worst because if you have both |
That's easily solvable by naming it either |
If it were called Or we could make it a hard error to have a kwarg both in the function and the dict. Or something else. |
Oh and if we merge |
So I really don't see how that solution is any better. |
What if we did something like: cargs = {
'always': ['-DFOO'],
'static_library' : ['-DSTATIC_COMPILATION']
}
suffix = {
'static_library' : 'lib'
}
mylib = library('foo', sources, c_args : cargs) specifically enforcing that if something is passed as a dict it must be only a dict, no ambiguity, and no chances of having two dicts passed at the same time. |
Passing |
I already didn't see how that proposal was better, and given those constraints IMHO it's clearly worse. In addition, my PR can be merged today, while yours needs extra work for little to none benefice, for a feature we have been wanting for months. That really seems bikesheding to me. |
We're talking about language syntax, we don't get to take it back if we make a mistake here, we get stuck with it. I think its worth thinking about the corner cases. In the vein of thinking about corners, what happens in your PR if I do this: cargs = {
'static_library' : ['-DSTATIC_COMPILATION']
}
othercargs = {
'static_library' : ['-DSOMETHING']
}
mylib = library('foo', sources, c_args : ['-DFOO', cargs, other_cargs]) |
They are appended in the order you give them. See it as it's flattened just like arrays everywhere. |
Does this proposal also allow conditionally limiting what sources to include when linking a library, depending on the library type? My use case is that when including a windows resource file when building a shared library (to provide metadata about the library), it only makes sense to do this if actually making a shared library. For libraries whose type depend on the --default-library option, one will also end up including the same resource file in the static libraries, which doesn't make much sense. (Including resource files in static libraries can also break creating the library, when targeting non-x86 platforms.) |
I strongly dislike the variants using some form of 'kwargs'. I think we should not design meson so that basic use cases need use the reflection like syntax. It's well very advanced scripting in complex projects, but simple projects should work without. I'm not happy about the magic dictionary either. That feels a lot like having found an hammer and now trying to fix everything with that. But i do like the way that the dictionary approach has a simple additive feel to it. But i feel that using dictionary in that way leads to very hard to understand extensions in the future. I always liked that meson if fairly explicit and i think we should err on the side of being to wordy here. Maybe all that is needed is some more semantic parts in the mix.
I don't mind having 'static_library' as string, but just having it as bare key in a dictionary seems way to implicit. I think we should aim for developers without much meson knowledge to be able to understand working build definitions by just reading them. |
That sounds like functionally the same thing, it's basically either of those:
In that proposal, |
The |
btw, I would call the function |
Apologies for resurrecting what seems to be a contentious bikesheddy PR, but are there alternative solutions to do this? As far as I can tell, one needs to explicitly build both static and shared libraries, avoid For the record, though this is often presented as a Windows issue (because it's mandatory there), it's pretty common to use private visibility in shared libraries on all platforms. Libraries that care about dynamic loading and binary compatibility and so on use private default visibility and explicit exports, because it's important to have a clean symbol table in some domains (and it's just general best practice). It's really weird to have |
@drobilla I am not really sure I understand your issue? Why can't you use |
@ePirat Because I can't detect in the code that a shared (or static) library is being built, so I can't define the export macros (or not). It works "just fine" in that it will hide all the symbols and make the library unusable, I suppose... |
@drobilla Ah indeed, if you support building |
I think the difference is on Linux you can use That means that most projects that build with That being said, I'm no sure to really understand those details myself. |
@xclaesse Yep. In general, anyway, though I think there are some cases where you don't want to blindly set visibility to public (e.g. in case the library is used inside another library which doesn't want to export it). It does mean you don't need to define different things for the library build itself and the user code, though, that is a Windows thing.
Yeah, this is near-ubiquitous. grep for 'visibility' in Something like:
|
@drobilla as far as I understand with GNUC you can Maybe this PR is trying to provide a generic solution to a specific problem. Since this symbol visibility story is really duplicated in so many projects, I'm wondering if meson could handle all that logic itself and define itself
|
@xclaesse You definitely can do that (it is "default" after all), but I'm not entirely sure you always want to. There are also other more fancy visibility attributes. That aside, this usually goes in public headers so I don't think that will work (meson may not be building whatever code is using it). Even if it did, I think it would be trouble for wraps to have build system specific stuff end up in the code though? In an ideal world there'd be a standard for this, but oh well... |
Right, won't work when building an app against your library without meson... |
Another way of achieving this, what about: |
Simple and useful for other stuff, that's nice. It's a bit less powerful I suppose, but Good Enough for most cases, I think. |
I like this, but I don't think it solves the case where you want some flags to apply to one particular target and not all targets (static libraries for instance) within your project. For me whatever solution is come up with, I would like it to increase the usability of library() when default_library=both |
@tristan957 the idea is |
but if I have multiple static_libraries, and one of them need -DX=Y and the other needs -DX=Z, this doesn't work super well. |
True, but does that really happen? |
You never know 🤷. I am fine with this approach. I just think someone in the future could be like "I need this", and then the solution would be suboptimal, and then we are back at the same issue of having to come up with a solution again. |
We usually don't design for hypothetical future use-cases. We can always extend later. That being said, @dcbaker actually has a real use-case for dict approach now... |
Yep I saw that, and was really exemplary of how the dict approach could be used to its fullest potential. |
Can this be closed, now that #11981 is merged? |
There are currently 2 use cases where we want to pass different arguments to library() function if it's shared or static, see #4133 and #3304. A complete solution like the one proposed in #4019 (comment) is probably too complicated and controversial.
This PR allow syntax like this:
This is very similar to my old PR #3320, but using a dict instead of a new object type.