lu-zero / cdylib-link-lines

Helper to build correctly cdylibs
MIT License
16 stars 5 forks source link

Wrong SONAME if dependending on another dylib crate #9

Open phi-gamma opened 1 year ago

phi-gamma commented 1 year ago

Wrong SONAME if dependending on another dylib crate

When building a shared library that itself depends on another dylib type library, both libraries’ SONAMEs are passed to the linker of the depending (main) library, causing the SONAME of the dependency (which comes last) to be embedded in the resulting object.

In this example workspace:

.
├── Cargo.toml
├── dependency
│   ├── build.rs
│   ├── Cargo.toml
│   └── src
│       └── lib.rs
└── main
    ├── build.rs
    ├── Cargo.toml
    └── src
        └── lib.rs

both members are libraries with crate_type = [ "lib", "cdylib" ] and this build.rs:

fn main() { cdylib_link_lines::metabuild(); }

Building with cargo results in this rustc invocation for libmain.so:

 rustc \
    --crate-name main \
    --edition=2021 main/src/lib.rs \
    --error-format=json \
    --json=diagnostic-rendered-ansi,artifacts,future-incompat \
    --crate-type lib \
    --crate-type cdylib \
    --emit=dep-info,link \
    -C embed-bitcode=no \
    -C debuginfo=2 \
    -C metadata=301376fe41e0aabc \
    --out-dir /home/phg/src/playground/soname/target/debug/deps \
    -C linker=/usr/bin/clang \
    -C incremental=/home/phg/src/playground/soname/target/debug/incremental \
    -L dependency=/home/phg/src/playground/soname/target/debug/deps \
    --extern dependency=/home/phg/src/playground/soname/target/debug/deps/libdependency.rlib \
    -C link-arg=--ld-path=/usr/bin/mold \
    -C link-arg=-Wl,-soname,libmain.so.0 \
    -C link-arg=-Wl,-soname,libdependency.so.0

– that last line obviously being misplaced. (The line for libdependency.so is fine.) As a result:

$ readelf -d target/debug/libdependency.so |grep SONAME
 0x000000000000000e (SONAME)             Library soname: [libdependency.so.0]
$ readelf -d target/debug/libmain.so |grep SONAME
 0x000000000000000e (SONAME)             Library soname: [libdependency.so.0]
lu-zero commented 1 year ago

What would be your expectation ? Can you please share the example repository so I can have a look?

lu-zero commented 1 year ago

what happens if you do not use the build.rs at all?

phi-gamma commented 1 year ago

What would be your expectation ?

Can you please share the example repository so I can have a look?

Demo: https://gitlab.com/phgsng/buggy-soname

what happens if you do not use the build.rs at all?

The objects lack DT_SONAME.

lu-zero commented 1 year ago

I doublechecked and a single rustc-cdylib-link-arg is produced per crate name, looks like it is cargo doing something strange itself, you can try by emitting manually rustc-cdylib-link-arg to confirm.

phi-gamma commented 1 year ago

Yeah, I realized that as well. If you wish, you could perhaps contribute to the discussion on the Rust forums:

https://users.rust-lang.org/t/suppress-link-arg-in-dependency/89245

FWIW I’m investigating adding a patchelf step to the cargo handler in our build process to fix up broken DT_SONAMES.

lu-zero commented 1 year ago

It is better to report the issue on the cargo tracker, I'm afraid I won't have enough time to look into it if not in the weekend.

phi-gamma commented 1 year ago

Probably a good idea; I reported my case on the cargo issue.

lu-zero commented 1 year ago

You might have better luck with https://crates.io/crates/cargo-c. It is aware of workspaces and provides additional niceties.

phi-gamma commented 1 year ago

2023-02-14 (Tuesday), @.*** (Luca Barbato):

You might have better luck with https://crates.io/crates/cargo-c. It is aware of workspaces and provides additional niceties.

Thanks, I’m aware of cargo-c but haven’t found time to evaluate it yet.