This implements -start-lib and -end-lib flags for lld-link, analogous
to the similarly named options in ld.lld. Object files after
-start-lib are included in the link only when needed to resolve
undefined symbols. The -end-lib flag goes back to the normal behavior
of always including object files in the link. This mimics the
semantics of static libraries, but without needing to actually create
the archive file.
Details
- Reviewers
ruiu smeenai MaskRay - Commits
- rG7dc5e7a0a4f4: reland "[lld-link] implement -start-lib and -end-lib"
rLLD370816: reland "[lld-link] implement -start-lib and -end-lib"
rL370816: reland "[lld-link] implement -start-lib and -end-lib"
rGfd7569c8e366: [lld-link] implement -start-lib and -end-lib
rLLD370487: [lld-link] implement -start-lib and -end-lib
rL370487: [lld-link] implement -start-lib and -end-lib
Diff Detail
- Repository
- rG LLVM Github Monorepo
- Build Status
Buildable 37393 Build 37392: arc lint + arc unit
Event Timeline
Primarily, this change adds a LazyObject Symbol kind, and a LazyObjFile InputFile kind. A LazyObject represents a symbol defined in a LazyObjFile, and a LazyObjFile is either a native object file or a bitcode file that we know of, but have not yet decided to link in. As with the LazyArchive symbols we already had, when we encounter both a lazy symbol and an Undefined symbol, we resolve this by linking in the file that defines the symbol, so the result is a Defined symbol.
The change also modifies the way we track wholearchive. This was previously passed as a boolean. Because it doesn't make sense to have both wholearchive (which says to link in all objects in an archive regardless of whether their symbols are referenced) and -start-lib (which says to only link in objects only when their symbols are referenced), this change replaces this with a mode enum which can be wholearchive, lazy, or neither.
Finally, -start-lib and -end-lib are added to the options the linker accepts, and we perform some sanity checks (no -end-lib without -start-lib, for example).
lld/COFF/DebugTypes.cpp | ||
---|---|---|
234 | AddMode is not an enum class, so it is in the namespace of LinkerDriver, so it can just be LinkerDriver::NORMAL | |
lld/COFF/Driver.cpp | ||
1578–1581 | Too much nesting I guess? I'd write this way if (InLib) enqueuePath(*path, LAZY); else if (isWholeArchive(*Path)) enqueuePath(*path, WHOLE_ARCHIVE); else enqueuePath(*path, NORMAL); | |
1594 | I think you can omit AddMode::. |
lld/COFF/InputFiles.h | ||
---|---|---|
133 | symbols(std::move(symbols)) |
lld/test/COFF/start-lib-cmd-diagnostics.ll | ||
---|---|---|
15 | What made you decide -start-lib and -wholearchive: cannot be used together? I noticed that -wholearchive: can apply on both archives and regular object files. However, there is no test before this patch that test -wholearchive: can apply on object files. In ELF, the -wholearchive: counterpart is a pair of --whole-archive and --no-whole-archive. --start-lib is allowed to be used together because
Their use cases don't overlap so their combination is not rejected. |
lld/test/COFF/start-lib-cmd-diagnostics.ll | ||
---|---|---|
15 | I agree with MaskRay. Giving static libraries object file semantics and object files library file semantics at the same time seems odd but they don't technically conflict. I can't think of a sane use case of the combination of the features, but I don't think we should ban the combination. |
This caused failures in a sanitizer buildbot: http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-bootstrap-msan/builds/14443/steps/check-lld%20msan/logs/stdio
AddMode is not an enum class, so it is in the namespace of LinkerDriver, so it can just be LinkerDriver::NORMAL