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

[SR-4123] Incremental build rebuilds vapor's testing module unnecessarily #5085

Closed
rballard opened this issue Mar 1, 2017 · 20 comments
Closed
Assignees
Labels

Comments

@rballard
Copy link
Contributor

rballard commented Mar 1, 2017

Previous ID SR-4123
Radar rdar://problem/30788004
Original Reporter @rballard
Type Bug
Status Closed
Resolution Done
Additional Detail from JIRA
Votes 0
Component/s llbuild, Package Manager
Labels Bug
Assignee @rballard
Priority Medium

md5: df5cdad553717cde0fba7d09bd7e729e

Issue Description:

In testing an incremental build with vapor, I found that if I touch a file in the "Sessions" module, swiftpm rebuilds the "Testing" module, even though the "Testing" module doesn't import "Sessions". It's not clear to me why it's rebuilding.

Steps to reproduce:

  1. Check out Vapor (I am on the 2.0.0-alpha.7 tag)
  2. `swift build`
  3. `touch Sources/Sessions/Session.swift`
  4. `swift build`

Result:
I got:
Compile Swift Module 'Sessions' (6 sources)
Compile Swift Module 'Vapor' (85 sources)
Compile Swift Module 'Testing' (6 sources)

I expected Sessions and Vapor to rebuild, but not Testing.
Note that if I touch a file in Vapor and build, only Vapor rebuilds, not Testing.

@ankitspd
Copy link
Member

ankitspd commented Mar 1, 2017

From Vapor's manifest file it looks like Vapor depends on Sessions, and Testing depends on Vapor so I think this is the correct even if Testing doesn't really import Vapor in the source code. But @ddunbar would know better.

@rballard
Copy link
Contributor Author

rballard commented Mar 1, 2017

Ah, right, I was somehow imagining that we'd already implemented our desired import-based dependency detection, but we haven't and are purely driven from the manifest. So then I guess the question is, why does forcing Vapor to rebuild not force Testing to rebuild? It turns out that it seems that that's only true for certain files in Vapor. So for .e.g:
`touch Sources/Vapor/View/View.swift; swift build` gives me:
Compile Swift Module 'Vapor' (85 sources)
Compile Swift Module 'Testing' (6 sources)
which is correct. But:
`touch Sources/Vapor/Utilities/Bytes.swift; swift build` only gives me:
Compile Swift Module 'Vapor' (85 sources)

@ddunbar
Copy link
Member

ddunbar commented Mar 1, 2017

I suspect that what is happening here is that `swiftc` is smart enough to sometimes avoid regenerating output files when they haven't changed, and so the difference between the two scenarios is in one Sessions.swiftmodule ends up rebuilt, and in another it doesn't.

@ankitspd
Copy link
Member

ankitspd commented Mar 1, 2017

Actually the rebuilding other modules was non deterministic on my computer (sometimes it only rebuilt Session module).

@rballard
Copy link
Contributor Author

rballard commented Mar 1, 2017

When I touch Vapor/View/View.swift, the only files that seem to get touched in Vapor's build products are master.swiftdeps and output-file-map.json. When I touch Sources/Vapor/Utilities/Bytes.swift, the same files in Vapor's build products get touched. Should these files trigger rebuilding Testing?

@rballard
Copy link
Contributor Author

rballard commented Mar 1, 2017

I'll also add that in neither case is Vapor.swiftmodule touched.

@ddunbar
Copy link
Member

ddunbar commented Mar 1, 2017

No I wouldn't expect master.swiftdeps or output-file-map.json in Session module to cause Testing to rebuild.

I can't actually reproduce this issue, when I touch Sessions.swift I just see Sessions rebuild as I would expect.

What swift version are you using?

@ddunbar
Copy link
Member

ddunbar commented Mar 1, 2017

I did fix a non-determinism in llbuild's value encoding recently which might cause unnecessary rebuilds... let me dig it up and see if that could be related.

@rballard
Copy link
Contributor Author

rballard commented Mar 1, 2017

I'm using swift-3.1-DEVELOPMENT-SNAPSHOT-2017-02-27-a

@ddunbar
Copy link
Member

ddunbar commented Mar 1, 2017

The patch I'm thinking of was:

commit 346849f
Author: Daniel Dunbar <daniel_dunbar@apple.com>
Date: Wed Jan 18 12:01:56 2017 -0800

[BuildSystem] Fix BuildValue initialization & serialization.

  • The initializer was allowing uninitialized data in the commandSignature for
    sentinel values (like virtual inputs).
  • The move initialization was failing to initialize some fields ❗.
  • The serialization was also failing to properly normalize values, so the
    serialized value was not properly deterministic.

    which just missed the 3.1 branch and I didn't think to cherry pick in. 🙁

I'm testing now with the snapshots on either side of this commit to see if I can reproduce & see whether it was fixed in that range.

@belkadan
Copy link

belkadan commented Mar 1, 2017

Simply touching a file should not result in downstream targets being recompiled, because the swiftmodule shouldn't change. If we are seeing changes in the swiftmodule then we've got nondeterminism we need to stamp out!

@belkadan
Copy link

belkadan commented Mar 1, 2017

(that is, if it's the compiler doing it and not llbuild)

@ddunbar
Copy link
Member

ddunbar commented Mar 1, 2017

While on this topic @belkadan is my understanding correct that the .o will change iff the incremental dependencies logic decides to rerun the compile for that file? That file is never not updated if unchanged, right (and should we do so – llbuild will take advantage of it by default)?

@ddunbar
Copy link
Member

ddunbar commented Mar 1, 2017

I verified this problem occurs with TOOLCHAINS=org.swift.3020170118a and not TOOLCHAINS=org.swift.3020170120a, so I believe this was fixed with 346849f.

@belkadan
Copy link

belkadan commented Mar 1, 2017

The .o certainly will not change if the incremental logic decides not to recompile. It may also not change if the file is recompiled and the output is "close enough"—I believe we both short-circuit the last phase of compilation.

@ddunbar
Copy link
Member

ddunbar commented Mar 1, 2017

apple/swift-llbuild#127

@ddunbar
Copy link
Member

ddunbar commented Mar 1, 2017

@swift-ci create

@ddunbar
Copy link
Member

ddunbar commented Mar 1, 2017

@belkadan thanks for the clarification, I filed:
https://bugs.swift.org/browse/SR-4127
to track some improvements on a trivial test case (but I think they are blocked on cleaning up private API in the .swiftmodule primarily)

@ddunbar
Copy link
Member

ddunbar commented Mar 2, 2017

Merged apple/swift-llbuild#127

@rballard
Copy link
Contributor Author

I can't reproduce this exactly because the 2.0.0-alpha.7 tag gives me dependencies that don't build now, and I didn't think to upload my pinfile when I filed this. But I verified this with similar steps against Vapor 1.5.9 and this appears to work correctly now.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@shahmishal shahmishal transferred this issue from apple/swift May 4, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants