Skip to content
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

new module "sourceset" to match source file lists against configuration data #5028

Merged
merged 2 commits into from May 22, 2019

Conversation

bonzini
Copy link
Contributor

@bonzini bonzini commented Mar 6, 2019

In QEMU a single set of source files is built against many different configurations in order to generate many executable. Each executable includes a different but overlapping subset of the source files; some of the files are compiled separately for each output, others are compiled just once.

Using Makefiles, this is achieved with a complicated mechanism involving a combination of non-recursive and recursive make; Meson can do better. However, because there are hundreds of such conditional rules, it's important to keep meson.build files brief and easy to follow. Therefore, this commit adds a new module to satisfy this use case while preserving Meson's declarative nature.

Configurations are mapped to a configuration_data object, and a new "source set" object is used to store all the rules, and then retrieve the desired set of sources together with their dependencies.

The test case shows how the source set object can be used either directly or via extract_objects, in order to satisfy both cases—that is, either share object files across targets or keeping them separate. In the real-world case of QEMU we would use two or more source set objects, and then do executable(..., sources: ... , objects: ...).

@bonzini bonzini force-pushed the sourceset branch 5 times, most recently from 7a43b33 to e245e10 Compare March 6, 2019 16:19
@bonzini bonzini mentioned this pull request Mar 6, 2019
@bonzini
Copy link
Contributor Author

bonzini commented Mar 6, 2019

Based on @dcbaker's comments on #1617, this should be changed to accept a dictionary instead of a configuration_data.

@bonzini bonzini force-pushed the sourceset branch 2 times, most recently from 227a875 to 098ef9d Compare March 18, 2019 18:33
@bonzini
Copy link
Contributor Author

bonzini commented Mar 27, 2019

@jpakkane I have the impression that you're not convinced. :) If you'd like, I can try and put together an almost-realistic example.

You can certainly achieve the same in pure Meson using arrays of dictionaries, not unlike the Foreach with a dictionary example. In this case you'd write something like

sourceset += [{'symbols': ['ECC'], 'sources': files('ecc.c')}]

as a replacement for

sourceset.add('CONFIG_ECC', files('ecc.c'))

and then use a foreach loop to extract the files and dependencies. However, from least to most severe:

  • at 20-ish extra characters per line, the syntax would be more unwieldy. QEMU currently has about 1300 rules with 600 different conditions, which makes it important to find the right balance between terseness and clarity (I put this as least important only because clarity is a bit in the eye of the beholder);

  • it would suffer from quadratic behavior. I tried timing 1300 += vs. 1300 sourceset.add(), and the cost was 300 ms vs 10 ms; it would be repeated many times during the build;

  • I would have to copy over and over the add_all() and apply() loops since they are performed on various sourcesets at different stages. The loops would also be complicated by the need to validate free-form dictionaries, instead of relying on permittedKwargs.

@bonzini
Copy link
Contributor Author

bonzini commented Apr 16, 2019

Now that #5119 is in, I cleaned up 218 source set custom target a bit.

@bonzini
Copy link
Contributor Author

bonzini commented May 2, 2019

@jpakkane Could you please review at least the concept? It's the only remaining blocker for even considering switching QEMU to Meson.

@jpakkane
Copy link
Member

jpakkane commented May 5, 2019

Sorry, there has been a lot of stuff happening. I'll try to get something done about this tomorrow.

@jpakkane
Copy link
Member

jpakkane commented May 6, 2019

On a general level having a better ("declarative-y") way of getting sources based on external factors like here is something we definitely want. I have gone through this twice now and there are things that need changing but the thing has not yet "clicked" for me to know exactly what it should look like.

I'll need to think about this more. In the mean time here are some things that came to mind:

  • Why does it return a Python dependency since this has nothing to do with Python. Should it not be a regular dependency object instead?

  • This should not use flattening preventer. Having more than one type of arguments is confusing. We only permit it for build targets and even then only because it has exactly one string for the name, not several. Those should all be kwargs instead. It also makes it more readable and self-documenting.

  • Is Source files object really needed? Would it be enough to return an array with the elements? (OTOH doing that broke in the Gnome module just recently)

@bonzini
Copy link
Contributor Author

bonzini commented May 7, 2019

Why does it return a Python dependency since this has nothing to do with Python. Should it not be a regular dependency object instead?

It's just a cut-and-paste error in the documentation. all_sources returns simply a list of file objects

This should not use flattening preventer. Having more than one type of arguments is confusing. We only permit it for build targets and even then only because it has exactly one string for the name, not several. Those should all be kwargs instead. It also makes it more readable and self-documenting.

Fair enough. My reasoning is that add is going to be used tens or hundreds times in meson.build, it is going to be pretty self-explanatory what it does and there is some advantage in keeping the length of the lines to the minimum. However, I guess adding sources: to each line is not the end of the world and you're the boss anyway. ;)

Is Source files object really needed? Would it be enough to return an array with the elements?

It's needed because the configuration data affects both the source files and the dependencies. I'll rename the source files object to "source configuration".

@bonzini bonzini force-pushed the sourceset branch 3 times, most recently from e7408c6 to f7f9961 Compare May 12, 2019 09:45
@jpakkane
Copy link
Member

I could not think of things that would obviously break so no point in keeping this blocked. In addition since it is a module, we can just create a new one. There are a few fixes though:

  • the arguments should be kwarged, having two different types is confusing, thus this method should be marked as @noPosArgs
  • the documentation should have a simple practical example along the lines of "we add these files with these settings and then when do X, only this subset of things comes out"

@bonzini
Copy link
Contributor Author

bonzini commented May 15, 2019

Since I force pushed, you can use this link to compare the previous version with this one.

@jpakkane
Copy link
Member

The thing that is still sticking out to my eye a bit is the cond keyword. It is abbreviated a bit too much. On the other hand condition seems a bit vague. Maybe something like based_on? Other suggestions for the name are gladly accepted. 😃

@bonzini
Copy link
Contributor Author

bonzini commented May 21, 2019

I'll change it to when. Short but not abbreviated. Thanks for forcing me to think about it once more. ;-)

@jpakkane
Copy link
Member

Sounds good to me.

…on data

In QEMU a single set of source files is built against many different
configurations in order to generate many executable.  Each executable
includes a different but overlapping subset of the source files; some
of the files are compiled separately for each output, others are
compiled just once.

Using Makefiles, this is achieved with a complicated mechanism involving
a combination of non-recursive and recursive make; Meson can do better,
but because there are hundreds of such conditional rules, it's important
to keep meson.build files brief and easy to follow.  Therefore, this
commit adds a new module to satisfy this use case while preserving
Meson's declarative nature.

Configurations are mapped to a configuration_data object, and a new
"source set" object is used to store all the rules, and then retrieve
the desired set of sources together with their dependencies.

The test case shows how extract_objects can be used to satisfy both
cases, i.e. when the object files are shared across targets and when
they have to be separate.  In the real-world case, a project would use
two source set objects for the two cases and then do
"executable(..., sources: ... , objects: ...)".  The next commit
adds such an example.
@jpakkane jpakkane merged commit 77a933f into mesonbuild:master May 22, 2019
@bonzini bonzini deleted the sourceset branch February 1, 2021 07:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants