-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Open
Labels
A-linkageArea: linking into static, shared libraries and binariesArea: linking into static, shared libraries and binariesC-discussionCategory: Discussion or questions that doesn't represent real issues.Category: Discussion or questions that doesn't represent real issues.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
Similarly to #47384, statics in a static library that are marked as used
are not included in the resulting binary if a non-inlined function is used in the same module.
Example
This code can be found at mkroening/rust-issue-99721
.
staticlib.rs
:
mod note {
#[used]
#[link_section = ".note.my-note"]
static MY_NOTE: u8 = 0;
#[inline(always)]
pub fn dummy() {}
}
#[no_mangle]
pub extern "C" fn staticlib() {
note::dummy();
}
bin.rs
:
fn main() {
extern "C" {
fn staticlib();
}
unsafe {
staticlib();
}
}
Build using:
rustc --crate-type staticlib staticlib.rs
rustc -L native=. -l static=staticlib bin.rs
Display static library notes:
$ readelf -Wn libstaticlib.a
[...]
File: libstaticlib.a(staticlib.staticlib.68b5aa53-cgu.0.rcgu.o)
Displaying notes found in: .note.my-note
Owner Data size Description
readelf: Warning: Corrupt note: only 1 byte remains, not enough for a full note
[...]
Display binary notes:
$ readelf -Wn bin
Displaying notes found in: .note.gnu.property
Owner Data size Description
GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0 Properties: x86 ISA needed: x86-64-baseline
Displaying notes found in: .note.gnu.build-id
Owner Data size Description
GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring) Build ID: 258d83311faf1a32cb84dd090ccc57abdbb1cb38
Displaying notes found in: .note.ABI-tag
Owner Data size Description
GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag) OS: Linux, ABI: 4.4.0
If note::dummy
is made inline(never)
, the symbol is included in the resulting binary:
$ readelf -Wn bin
Displaying notes found in: .note.gnu.property
Owner Data size Description
GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0 Properties: x86 ISA needed: x86-64-baseline
Displaying notes found in: .note.gnu.build-id
Owner Data size Description
GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring) Build ID: 72d6efcf61e2b33563094c3f179ebcc511db7485
Displaying notes found in: .note.ABI-tag
Owner Data size Description
GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag) OS: Linux, ABI: 4.4.0
Displaying notes found in: .note.my-note
Owner Data size Description
readelf: Warning: Corrupt note: only 1 byte remains, not enough for a full note
Metadata
Metadata
Assignees
Labels
A-linkageArea: linking into static, shared libraries and binariesArea: linking into static, shared libraries and binariesC-discussionCategory: Discussion or questions that doesn't represent real issues.Category: Discussion or questions that doesn't represent real issues.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Type
Projects
Milestone
Relationships
Development
Select code repository
Activity
mkroening commentedon Jul 25, 2022
CC: @nbdd0121 @petrochenkov
nbdd0121 commentedon Jul 25, 2022
That's the nature of static library; there's not much we can do about it unless we squeeze everything into one single object file or reference all object files from every single one of them.
mkroening commentedon Jul 25, 2022
That makes sense.
I just found that you can force link the symbol with
-Clink-arg=--undefined=<symbol_name>
when building the binary. I was hoping there would be some general way of doing this that does not require modifying the binary.I'll resort to using the
inline(never)
approach in the meantime, although that is really not a nice way of forcing a reference into the object file.carbotaniuman commentedon Jul 28, 2022
You need
[used(linker)]
for this to work. That has spotty availability sadly, but there are workarounds.nbdd0121 commentedon Jul 28, 2022
That won't work either. Object file inside static libs will not participate in linker if it does not provide any undefined symbol. SHF_GNU_RETAIN are not special in this regard.
mkroening commentedon Jul 28, 2022
Yeah, that does not work unfortunately.
petrochenkov commentedon Jul 31, 2022
There's a similar issue that can be fixed.
You link a staticlib (written in C, or Rust, or whatever) to a binary, and you want to preserve some symbol from it.
Unfortunately,
#[used]
attributes do not work on foreign items, but it probably should.(It should also work on (foreign) functions too, but this is what #94348 is about.)
If it worked it would refer to the symbol in question from
symbols.o
thus keeping the corresponding object file during linking.mkroening commentedon Aug 1, 2022
Interesting!
Since in our use case we want to distribute the static library, this won't work. It's great that you can use
--undefined
from within Rust, though. For our problem I have now resorted to having a macro in the excluded module to define the static in the rood module while keeping the logic separate.bjorn3 commentedon May 9, 2025
For pulling in the right object files,
#[used]
nowadays causes symbol to be added tosymbols.o
. So all that is needed to fix this would be to make#[used]
an alias for#[used(linker)]
, which #140872 does if accepted.nbdd0121 commentedon May 10, 2025
I don't see how the linked PR would fix this issue. See #99721 (comment)
bjorn3 commentedon May 10, 2025
As I said, because we reference
#[used]
statics fromsymbols.o
the object files containg them should be pulled in even if otherwise unreferenced.nbdd0121 commentedon May 10, 2025
This is a staticlib,
#[used]
marking within the staticlib itself cannot propagate out to the user.bjorn3 commentedon May 21, 2025
Right, this would either need
--whole-archive
or somethingsymbols.o
like wheresymbols.o
in turn gets pulled in by every codegen unit.