-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
dependencies/dub: First try to describe local project #13555
base: master
Are you sure you want to change the base?
Conversation
fb36971
to
fb0769b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a few style nits here, I'm hoping that some of our resident D people might chime in on this from a functional point of view.
cc @denizzzka @rtbo |
We in D already have I think the file name like |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This adds five new test cases. Is it possible we can test multiple things in a single test case?
Running full end-to-end tests is relatively slow and some of the CI jobs already take a pretty long time.
run_command(dub_exe, 'build', '--deep', '--compiler', dc, '--arch', arch, | ||
'--root', root, | ||
check: true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like basically all of these new test cases are running this command, which I think is supposed to recursively build dependencies, and then the tests maybe never actually build the dub project itself because they just detect which dependency version got found, or something?
But don't we already have the built dependencies we need? If not, can we guarantee it is built in CI rather than potentially very slowly building dependencies on every CI run?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This adds five new test cases. Is it possible we can test multiple things in a single test case?
Yeah, I think some can be merged.
It looks like basically all of these new test cases are running this command, which I think is supposed to recursively build dependencies, and then the tests maybe never actually build the dub project itself?
But don't we already have the built dependencies we need? If not, can we guarantee it is built in CI rather than potentially very slowly building dependencies on every CI run?
I did want to ask about this. I've written the commands in the meson files because I wanted to support people running the testsuite by themselves, without having to go through the CI script or reading test failures to find the line that tells them how to invoke dub to test dependencies. It is also way more manageable to keep track of which dependencies are needed / what versions / what compiler they require etc.
However, as you have said, this has the potential to build a lot of stuff during the tests but note that dub will properly (usually) cache the results so if they have been installed during CI they will not be rebuilt during the tests. This could be made a little better by having the new tests specify "targetType": "none"
in their dub.json which will make the dub build
command to only build the dependencies.
The usually above refers to dub forcefully rebuilding stuff if a change in configuration occurs so:
dub build dep
(builds)dub build dep
(cached)dub build dep --config foo
(builds)dub build dep --config foo
(cached)dub build dep
(builds again even if cached)
Now, if the issue is the potential of building stuff outside of CI then yes, all the dependencies would need to be gathered and installed manually.
There is also another issue with installing them during the tests, there is the possibility of dub being called twice to build the same dependency and if it isn't present dub may get into a race-condition with the other process (it happened to me one).
From your tone it seems you desire to have as little building possibly being done during the tests. I think only test 19 needs to do actual building though it may be possible to change it not to require it. Is that what you suggest?
It is possible to have a separate If we assume a project that support building with both dub and meson will the 2 configuration files |
When I wrote my previous comment I assumed that In DUB to use DUB configurations it is just need to pass configuration via the command line or from users d_dep = dependency('19-this-package', method: 'dub', d_cfg: 'custom') Or maybe something like d_dep = dependency('19-this-package', method: 'dub')
custom_cfg_dep = d_dep.d_subconfig('custom') |
Yes, but that would change the semantics of
I didn't know about this but I don't think it's a good idea either. A criticism of dub is that it gathers more dependencies then it needs to leading to possible conflicts between packages and more things being pointlessly downloaded & analyzed. Perhaps it would be wise not to have meson fall into the same trap but I imagine there could be a way to implement what you suggest in a way that lazily resolves the dependency. |
Dependencies configurations changing can be implemented in proposed |
What does this affect? After all, the package used must already be compiled at this moment |
Yeah I think it can be implemented that way, have
It has to do with the caching dub does. It takes into account all build parameters which is why the code needs to specify As an example of why this is useful imagine: |
cadfbf6
to
8b67cae
Compare
I've reduced the number of tests: now there are only 2. There is only 1 build command during the tests which builds a local package so it shouldn't be resource intensive. I didn't find any good package online that is fast to build and provides 2 configurations, the first an executable and the second a library so I went with the local build. If, in I've changed the installed libraries in CI to be exact versions since some of the new tests check for versions so I wanted it to be consistent. I've hit this locally as well but I needed to compile dub packages with |
It appears that CI is failing. The Of course, the test runs fine on my machine. I've tried using the docker image and debug from that but, for some reason, dub decides to consume 6GB of memory when it invokes the compiler to determine its version and other flags and OOMs. This has happened to me both when trying to build the image manually and when using the prebuilt mesonbuild images. Its probably something broken with my docker but I still can't reproduce the failure. I even tried to recompile dub to exclude those problematic compiler calls and of course the tests pass in the docker image in that case as well. The only thing I can think off after this is shove prints in the code to see why the tests fail. I love CI. |
I'm getting ahead of myself. The CI images used in the tests are from previous runs so my changes to them don't reflect here. Not sure what to do about it though. |
This is exactly the same reason I ragequit attempting to locally debug D issues for the CI. You are not alone and it's not your docker, because I have the same problem. If I try to build the test images, dub build consumes all the memory available to docker, which usually means OOMing my entire computer and breaking everything I was working on willy-nilly. So what I did was just give up and locally comment out all Dub handling when I test other issues on the same CI container. ;) I never figured out the reason why. |
When updating the CI image container for Ubuntu, it is okay if the os_comp tests fail due to the out of date container as long as the container succeeds. However, the Azure CI for Windows is also failing in this PR for the same reason. |
Try to run dub with option --DRT-gcopt=heapSizeFactor:1.1 |
At least mine doesn't crash, just gracefully stops execution.
The problematic lines in dub are the ones that call More problematic this code also OOMs: import std.process : execute;
void main () {
auto r = execute(["/usr/bin/true"], maxOutput: 1000);
import std.stdio;
writeln("Exit status: ", r.status);
writeln("Output: ", [ r.output ]);
} So it would seem D's
No change:
I'll see if I can find what's going wrong here hopefully before the CI starts to fail as well. |
Yes, I have to change what dub packages need to be installed for windows as well. |
Mirror what mesonbuild/meson#13555 installs for dub. Signed-off-by: Andrei Horodniceanu <[email protected]>
Mirror what mesonbuild/meson#13555 installs for dub. Signed-off-by: Andrei Horodniceanu <[email protected]>
Mirror what mesonbuild/meson#13555 installs for dub. Signed-off-by: Andrei Horodniceanu <[email protected]>
I've made a PR (dlang/dub#2962) to fix dub not finding dependencies if they aren't built with |
relate to #10189 where I proposed to add vibe_http_dep = dependency('vibe-d:http',
method: 'dub',
configuration: 'vibe-d:tls/notls',
) |
The current approach of determining dub dependencies is by specifying a name and, optionally, a version. Dub will then be called to generate a json summary of the package and code in meson will parse that and extract relevant information. This can be insufficient because dub packages can provide multiple configurations for multiple use-cases, examples include providing a configuration for an executable and a configuration for a library. As a practical example, the dub package itself provides an application configuration and multiple library configurations, the json description of dub will, by default, be for the application configuration which will make dub as a library unusable in meson. This can be solved without modifying the meson build interface by having dub describe the entire local project and collecting dependencies information from that. This way dub will generate information based on the project's 'dub.json' file, which is free to require dependencies in any way accepted by dub, by specifying configurations, by modifying compilation flags etc. This is all transparent to meson as dub's main purpose is to provide a path to the library file generated by the dependency in addition to other command-line arguments for the compiler. This change will, however, require that projects that want to build with meson also provided a 'dub.json' file in which dependency information is recorded. Failure to do so will not break existing projects that didn't use a 'dub.json', but they will be limited to what the previous implementation offered. Projects that already have a 'dub.json' should be fine, so long as the file is valid and the information in it matches the one in 'meson.build'. For example for a 'dependency()' call in 'meson.build' that dependency must exist in 'dub.json', otherwise the call will now fail when it worked previously. Using a 'dub.json' also has as a consequence that the version of the dependencies that are found are the ones specified in 'dub.selections.json', which can be helpful for projects that already provide a 'dub.json' in addition to 'meson.build' to de-duplicate code. In terms of other code changes: - multiple version requirements for a dub dependency now work, though they can only be used when a 'dub.json' is present in which case the version of dependencies is already pinned by 'dub.selections.json' - the 'd/11 dub' test case has been changed to auto-generate the 'dub.json' config outside of the source directory, as the auto-generated file triggers warning when parsed by dub, which upsets the new code as the warnings interfere with the legitimate output. Signed-off-by: Andrei Horodniceanu <[email protected]>
Rebased for #13629. This should make the windows tests pass but they should still fail on linux. |
Uh, the opensuse job should have failed. Trying to fix in #13673 |
@denizzzka @rtbo @eli-schwartz any more news on this? I'd appreciate if it would be merged. |
The current approach of determining dub dependencies is by specifying a name and, optionally, a version. Dub will then be called to generate a json summary of the package and code in meson will parse that and extract relevant information. This can be insufficient because dub packages can provide multiple configurations for multiple use-cases, examples include providing a configuration for an executable and a configuration for a library. As a practical example, the dub package itself provides an application configuration and multiple library configurations, the json description of dub will, by default, be for the application configuration which will make dub as a library unusable in meson.
This can be solved without modifying the meson build interface by having dub describe the entire local project and collecting dependencies information from that. This way dub will generate information based on the project's 'dub.json' file, which is free to require dependencies in any way accepted by dub, by specifying configurations, by modifying compilation flags etc. This is all transparent to meson as dub's main purpose is to provide a path to the library file generated by the dependency in addition to other command-line arguments for the compiler.
This change will, however, require that projects that want to build with meson also provided a 'dub.json' file in which dependency information is recorded. Failure to do so will not break existing projects that didn't use a 'dub.json', but they will be limited to what the previous implementation offered. Projects that already have a 'dub.json' should be fine, so long as the file is valid and the information in it matches the one in 'meson.build'. For example for a 'dependency()' call in 'meson.build' that dependency must exist in 'dub.json', otherwise the call will now fail when it worked previously.
Using a 'dub.json' also has as a consequence that the version of the dependencies that are found are the ones specified in 'dub.selections.json', which can be helpful for projects that already provide a 'dub.json' in addition to 'meson.build' to de-duplicate code.
In terms of other code changes: