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

missingdeps tool, take 2 #1331

Merged
merged 5 commits into from
Feb 23, 2021
Merged

missingdeps tool, take 2 #1331

merged 5 commits into from
Feb 23, 2021

Conversation

ilor
Copy link
Contributor

@ilor ilor commented Sep 20, 2017

This is a tool that detects some classes of random build failure causes around generated files (in Chrome, these are usually generated headers for C/C++). It takes several seconds to run, (more if the optional scan for files with no generator is used), and allows fixing a significant number of build system issues before they happen to randomly break someone's build.

The check relies on the correctness of depfile information, and on having all generator outputs listed. These things are usually easier to get right than proper deps. There's some overlap between this and gn check, but unlike gn check, this checks the actual ninja build graph and sees all issues.

This is a redo of #1031, it's been a while so I think it maybe better to start from scratch.

src/ninja.cc Outdated Show resolved Hide resolved
src/ninja.cc Outdated Show resolved Hide resolved
@ilor
Copy link
Contributor Author

ilor commented Sep 20, 2017

Thanks for the sugesstions so far. I'm also uploading example output of this tool, when run on a fairly recent chrome-linux build for the chrome target: missingdeps-chrome-output.gz

The summary is:

Processed 39546 nodes.
Error: 161 file(s) under /src/chromium/src/out are deps log dependencies of other targets, but have no generator target listing them as outputs.
Error: There are 156 missing dependency paths.
75 targets had depfile dependencies on 87 distinct generated inputs (from 34 rules) without a non-depfile dep path to the generator.
There might be build flakiness if any of the targets listed above are built alone, or not late enough, in a clean output directory.

There's one case that's arguably a false-positive: Missing dep: gen/components/resources/about_credits.html uses build.ninja (generated by gn) which may require a special case to not treat it as an error.

I also would like to have some sort of test for this, but don't really know where such a test (that needs an after-a-build state, basically) would hae tobe.

@ilor
Copy link
Contributor Author

ilor commented Oct 2, 2017

Ping?

@ilor
Copy link
Contributor Author

ilor commented Dec 6, 2017

Ping? I still believe this would be useful to have in ninja.

@ilor
Copy link
Contributor Author

ilor commented Feb 19, 2018

Ping? This could help fix a lot of rare clean-build build flakes in the chrome gn/ninja build, see https://bugs.chromium.org/p/chromium/issues/detail?id=655123 for a list of issues found.

@jcrben
Copy link

jcrben commented Mar 3, 2018

I'm just a random web developer wanting to try building chromium on macOS 10.12.6 using the instructions at https://chromium.googlesource.com/chromium/src/+/67.0.3360.2/docs/mac_build_instructions.md, and running into issues.

Hoping that any efforts to reduce flakiness / missing deps can be merged, so +1 on the ping.

When I ran this tool, I got
image

(note: this was not enough to help me fix my issue - error was specifically ../../services/network/public/cpp/resource_response_info.h:24:10: fatal error: 'services/network/public/mojom/fetch_api.mojom-shared.h' file not found, which is apparently that mojom files are not generating their C++ files - chromium could perhaps use more instructions or more of a scripted setup)

@bratell-at-opera
Copy link
Contributor

I just ran into missing mojom.h files in a Chromium build and I wonder if this tool would have caught the problem when it was introduced. This seems like a good thing to have so I hope some maintainer can take a look.

Copy link
Contributor

@atetubou atetubou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can I ask you to add some tests showing the behavior of this new tool?

src/state.cc Outdated Show resolved Hide resolved
src/ninja.cc Outdated Show resolved Hide resolved
src/ninja.cc Outdated Show resolved Hide resolved
src/ninja.cc Outdated Show resolved Hide resolved
src/ninja.cc Outdated Show resolved Hide resolved
@ilor
Copy link
Contributor Author

ilor commented Dec 11, 2018

Thanks for taking a look. What would be the preferred form of these tests?

My initial idea was that to show the behavior, I'd need several build directories with manually written ninja files for some types of mistakes. Then from some runner script I'd build in each of these and then run the tool to make sure I get the expected diagnostic. Would that be okay? I don't recall anything quite like it in the repo, so I'm not quite sure where I'd put it.

Something like this, assuming there's a generator for foo.h but foo.o doesn't dep on it:

cd missing-deps-test1
ninja clean  # assuming this is clean enough
ninja foo.h   # must be manually built first -- full builds are flaky
ninja foo.o
ninja -t missingdeps   # should report foo.o lacks a dep to foo.h's generator

then repeated for a few other cases.

Copy link
Contributor

@atetubou atetubou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather to have more unittest like test.

src/state.cc Outdated Show resolved Hide resolved
src/ninja.cc Show resolved Hide resolved
@jhasse
Copy link
Collaborator

jhasse commented Dec 12, 2018

My initial idea was that to show the behavior, I'd need several build directories with manually written ninja files for some types of mistakes. Then from some runner script I'd build in each of these and then run the tool to make sure I get the expected diagnostic. Would that be okay? I don't recall anything quite like it in the repo, so I'm not quite sure where I'd put it.

Not sure if this is what you're looking for, but there's https://github.com/ninja-build/ninja/blob/master/misc/output_test.py which runs the ninja binary on a temporary file and checks its output.

src/ninja.cc Outdated Show resolved Hide resolved
@ilor
Copy link
Contributor Author

ilor commented Dec 17, 2018

Admittedly, the timing is not great with regards to me being able to spend as much time as I'd like on this. That said, I've rebased to master and fixed some minor issues, but will need a while for the tests.

The "main" obstacle is that the code uses classes like ImplicitDepLoader which want to load a real file and aren't triviallyfed test data; I guess I can use a temp file for now as I see some tests do that.

@jonesmz

This comment was marked as abuse.

@ilor
Copy link
Contributor Author

ilor commented Aug 5, 2019

I'm working on this and should have something this week. It will be simplifies without the "files that lack a generator target" part (-g switch) because that adds a lot of complexity that's not needed to see the primary feature of the tool.

@ilor ilor force-pushed the missingdeps3 branch 2 times, most recently from 20da95a to 33c25d0 Compare August 9, 2019 09:50
@ilor
Copy link
Contributor Author

ilor commented Aug 9, 2019

Highlights from the update:

  • Rebased onto master
  • Separate cc/h pair for the tool, as it is large enough
  • Unit test for the primary thing the tool should catch
  • Remove -g switch and related code
  • Avoid touching state.h/cc, keep the edge adjacency map inside the tool

Removing -g and extracting to a separate source file simplified things a lot, and as a bonus now Windows should be able to build this without excessive ifdeffery or build config. I never found the -g tool to be very useful, it can be added later if there's a serious need.

Please take a look

src/missing_deps.h Outdated Show resolved Hide resolved
src/missing_deps_test.cc Outdated Show resolved Hide resolved
src/missing_deps.h Outdated Show resolved Hide resolved
src/missing_deps.h Outdated Show resolved Hide resolved
@ilor
Copy link
Contributor Author

ilor commented Aug 12, 2019

Thanks for the comments so far, should be all addressed. Please let me know what I can do next to get this into a merge-able state.

@ilor
Copy link
Contributor Author

ilor commented Aug 23, 2019

Friendly ping

Copy link
Collaborator

@jhasse jhasse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I don't have time right now to give this a closer look. I'm not sure if it's gonna make 1.10.

src/graph.cc Outdated Show resolved Hide resolved
@ilor
Copy link
Contributor Author

ilor commented Aug 28, 2019

Thanks for replying, I understand. While I think this can be very useful, it's not something I have to rush to any particular version.

I'll try to ping again in a week or a couple, maybe clean-up the branch history in the meantime (unless that's not welcome at this stage; I'm not sure how helpful/disruptive it'd be in the middle of a pull request).

src/missing_deps_test.cc Outdated Show resolved Hide resolved
@ilor
Copy link
Contributor Author

ilor commented Sep 20, 2019

ping?

@deepakcse87
Copy link

Nice tool. Looking forward to use it when it gets merged into master.

@ilor
Copy link
Contributor Author

ilor commented Nov 2, 2020

@jhasse friendly ping

@jhasse
Copy link
Collaborator

jhasse commented Nov 2, 2020

This PR is on the 1.11.0 milestone, I will definitely have a look at it before doing that release. Currently I'm working on 1.10.2 though, please be patient.

@ilor
Copy link
Contributor Author

ilor commented Nov 3, 2020

That's good to hear, I'll be waitng.

@jhasse
Copy link
Collaborator

jhasse commented Feb 12, 2021

Can you rebase on master? I think I found a crash in the unit test due to an assert.

@ilor
Copy link
Contributor Author

ilor commented Feb 15, 2021

The test crash seems to be because the test code that writes a depfile needs to be adjusted after cc79afb changed some bits in deps_log.cc

src/missing_deps.h Outdated Show resolved Hide resolved
@ilor ilor force-pushed the missingdeps3 branch 2 times, most recently from f366f4b to aea49f6 Compare February 15, 2021 12:08
@ilor
Copy link
Contributor Author

ilor commented Feb 17, 2021

ping -- this should be better now, the macos failure looks like a infra issue

Copy link
Collaborator

@jhasse jhasse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! The code looks good :) There's one performance impact though:

While implicit_dep is still preallocated, the new temporary vector depfile_deps will grow on the fly. It's also now two loops because of the temporary vector.

Either

  1. show that this has no significant performance impact with an appropriate benchmark,
  2. or pass a callback to LoadDepfileDeps instead of a pointer to a vector. Call it and pass the node instead of doing depfile_deps->push_back(node);.

@ilor
Copy link
Contributor Author

ilor commented Feb 17, 2021

@jhasse thanks, with all the quaint pre-C++11 support going on "use a callback" is a bit less enticing than it should otherwise be but I'll probably end up doing that. I may follow up with some perf experiments later if I find the time because I do feel like one extra vector and some pointer copies there should be immaterial.

@jhasse
Copy link
Collaborator

jhasse commented Feb 17, 2021

I hope it's okay I've tried the "Allow changes from maintainers" feature of GitHub and pushed to your branch 🙈

It isn't pretty, especially PreallocateSpace and CreatePhonyInEdge shouldn't be public. Maybe you have a better idea.

@ilor
Copy link
Contributor Author

ilor commented Feb 17, 2021

I think the virtual function approach works out better now, especially when viewed vs the base branch. Should be little effectively no changes on the main code path now.

@ilor ilor requested a review from jhasse February 17, 2021 22:47
@ilor
Copy link
Contributor Author

ilor commented Feb 19, 2021

friendly ping

Copy link
Collaborator

@jhasse jhasse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good solution :)

src/graph.cc Outdated Show resolved Hide resolved
src/graph.cc Outdated Show resolved Hide resolved
src/graph.h Outdated Show resolved Hide resolved
src/missing_deps_test.cc Outdated Show resolved Hide resolved
@ilor ilor requested a review from jhasse February 22, 2021 22:40
ilor added 5 commits February 22, 2021 23:48
Extract an usable helper to load depfile dependencies without adding them
to the graph.
The tool looks for targets that depend on a generated file, but do not
properly specify a dependency on the generator. It needs to be run after
a successful build, and will list all potential flakes that may have
broken the build, but didn't due to accidental build step ordering.

The search relies on the correctness of depfile and generator output
information, but these are usually easier to get right than dependencies.

The errors found can usually be verified as actual build flakes by trying
to build the listed problematic files alone in a clean build directory.
Such builds usually fail with a compile job lacking a generated file.

There is some overlap between this tool and 'gn check', but not everyone
uses gn, not everyone using gn uses gn check, and most importantly, gn
check is more about modularity, and less about actual build-time deps
without flakes.

The tool needs to be run after a build completes and depfile data is
collected. It may take several seconds to process, up to a dozen or
two on a large, chromium-sized build.
A "missing dep path" to build.ninja is a false positive, skip reporting it.
In my tests, nested maps outperform a large map of pairs by 10-20% on a
sample Chromium missingdeps run, and are arguably simpler due to fewer
ifdefs needed.
@jhasse jhasse merged commit 5c93343 into ninja-build:master Feb 23, 2021
netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this pull request May 27, 2022
release 1.11

This release adds Validation Nodes which are a new way to add jobs like linters or static analyzers to the build graph. They are added using |@ and don't produce any outputs. You can read more about the motivation and the syntax here: ninja-build/ninja#1800

Another big change is that Ninja now uses UTF-8 on Windows. This means that while previous versions of Ninja used the local ANSI encoding it will now always use UTF-8 allowing filenames and output with special characters. For this to work you'll need Windows 10 Version 1903 or newer. And for the console output to show Unicode characters you'll need to set the codepage to 65001. More information at: ninja-build/ninja#1915

Note that this is a breaking change if you relied on non-ASCII characters of the local codepage! If you want to query Ninja what codepage it uses in your generator, call `ninja -t wincodepage` and act accordingly.

There are also two new tools:
missingdeps: ninja-build/ninja#1331
inputs: ninja-build/ninja#1730

And as it was often requested, ninja now has a --quiet flag :)

For a complete list of changes see https://github.com/ninja-build/ninja/milestone/3?closed=1
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.

7 participants