It seems virtually everyone who tries to do LTO build with Clang and
LLD was hit by a mistake to forget using llvm-ar command to create
archive files. I wasn't an exception. Since this is an annoying common
issue, it is probably better to handle that gracefully rather than
reporting an error and tell the user to redo build with different
configuration.
Details
Diff Detail
- Build Status
Buildable 6071 Build 6071: arc lint + arc unit
Event Timeline
hmm, I'm not entirely sure I agree with this one. (cc @rafael)
This has the drawback of of having to scan all the members in an archive so it's potentially expensive.
We could maybe take the hit because the LTO time is dominated by opt/codegen but I'm under the impression the cost should be evaluated.
Also, I'm really worried about semantic changes, like two members with the same symbol name producing different results.
Both are valid concerns. Particularly I'm a bit worried about the semantics change this patch implies. If you inadvertently use this feature, you can't switch back to other linkers as your archive files are not valid for them. However, this patch would undeniably be convenient and potentially saves a lot of time to debug & reconfigure & rebuild. So I'd like to hear more opinions.
One thing I'd like to note is that this doesn't change the semantics of linking as long as your archive file are sane (i.e. there's no duplicate public symbols in one archive). You probably could create an archive that demonstrates the difference, but unless you don't intentionally break, I think it won't break.
True, but on the other hand, it's pretty much the exact same work that the archiver would need to do, and asking the user to change their archiver and rebuild would probably consume even more time.
Once D32061 lands I expect this operation to be relatively cheap.
We could maybe take the hit because the LTO time is dominated by opt/codegen but I'm under the impression the cost should be evaluated.
Opt/codegen should not be dominating in small incremental ThinLTO builds. We could evaluate it by measuring the impact on no-op incremental ThinLTO link time for a large application such as Chromium with/without archive symbol tables with this change patched in.
But the measurements I took for D32061 showed that just reading LTO symbol tables for Chromium takes at least 10-20 seconds at the moment.
Also, I'm really worried about semantic changes, like two members with the same symbol name producing different results.
That is a concern, but in practice I'd expect it not to matter which member the linker chooses.
It's also worth to mention that it is not always easy to use an alternative ar command to build something. Most build systems support the CC/CPP/CFLAGS env variables or equivalents to use alternative compilers with additional command flags. But the same feature is not always available for ar, or even if it is available it is less known and can potentially take a lot of time to investigate about how to do that.
lld/ELF/Driver.cpp | ||
---|---|---|
188 | I guess it could also mean that the archive contains only members that do not define any symbols, which I suppose is possible in practice (e.g. each member was compiled from platform-specific code that targets some other platform -- I think Chromium does this sort of thing, for example). We should probably warn only if the LazyObjectFile adds at least one LazyObject symbol. |
Do you actually want a fine grained warning message? What if we don't warn on it at all or warn only when -verbose?
The possible semantics change I mentioned was when you have multiple object files defining the same symbol. If our choice of object file is different from ar command's, the result will be different as a different file gets linked in. But in practice not an issue as the exact behavior is unpredictable even without this feature.
I personally think *not* warn is a terrible thing to do when there is a configuration issue. Erroring is annoying, but warning should be intended in such cases!
True, but on the other hand, it's pretty much the exact same work that the archiver would need to do,
The archiver do it once for potentially a lot of linker invocations.
and asking the user to change their archiver and rebuild would probably consume even more time.
This is a one time thing, and the user can live with the warning (or pass a flag to disable the warning maybe) if they choose to.
Can you call Archive::create(MB) only once and pass that to the ArchiveFile constructor?