Skip to content

link fails since 1.82.0 #134596

Closed
Closed
@loongs-zhang

Description

@loongs-zhang

My crate uses hook technology, which requires Rust to be able to link .dylib/.so/.dll. Unlike other projects, dynamic link libraries are also compiled from rust code(I built link-example to show what I'm trying to do), the link can not works since 1.82.0. The CI failed due to link problem.
If there is any other information you need to know, please tell me, thanks a lot for helping me.

I tried this code:

use cargo_metadata::MetadataCommand;
use std::env::var;
use std::fs::{copy, read_dir};
use std::path::PathBuf;

fn main() {
    // build dylib
    let out_dir = PathBuf::from(var("OUT_DIR").expect("OUT_DIR not found"));
    let target = var("TARGET").expect("env not found");
    let mut cargo = std::process::Command::new("cargo");
    let mut cmd = cargo.arg("build").arg("--target").arg(target.clone());
    if cfg!(not(debug_assertions)) {
        cmd = cmd.arg("--release");
    }
    let mut hook_toml = PathBuf::from(var("CARGO_MANIFEST_DIR").expect("env not found"))
        .parent()
        .expect("parent not found")
        .join("dep")
        .join("Cargo.toml");
    let metadata = MetadataCommand::default()
        .no_deps()
        .exec()
        .expect("read cargo metadata failed");
    let package = if hook_toml.exists() {
        metadata
            .packages
            .iter()
            .find(|pkg| pkg.name.eq("mycrate"))
            .expect("read current package failed")
    } else {
        metadata
            .packages
            .first()
            .expect("read current package failed")
    };
    let dependency = package
        .dependencies
        .iter()
        .find(|dep| dep.name.eq("dep"))
        .expect("dep not found");
    if !hook_toml.exists() {
        // 使用cargo_metadata读到依赖版本,结合CARGO_HOME获取dep的toml
        let dep_src_dir = PathBuf::from(var("CARGO_HOME").expect("CARGO_HOME not found"))
            .join("registry")
            .join("src");
        let crates_parent_dirs = Vec::from_iter(
            read_dir(dep_src_dir.clone())
                .expect("Failed to read deps")
                .flatten(),
        );
        let crates_parent = if crates_parent_dirs.len() == 1 {
            crates_parent_dirs.first().expect("host dir not found")
        } else {
            let rustup_dist_server =
                var("RUSTUP_DIST_SERVER").expect("RUSTUP_DIST_SERVER not found");
            let host = rustup_dist_server
                .split("://")
                .last()
                .expect("host not found");
            crates_parent_dirs
                .iter()
                .find(|entry| {
                    entry
                        .file_name()
                        .to_string_lossy()
                        .to_string()
                        .contains(host)
                })
                .unwrap_or_else(|| {
                    crates_parent_dirs
                        .iter()
                        .find(|entry| {
                            entry
                                .file_name()
                                .to_string_lossy()
                                .to_string()
                                .contains("crates.io")
                        })
                        .expect("host dir not found")
                })
        }
        .file_name()
        .to_string_lossy()
        .to_string();
        let version = &dependency
            .req
            .comparators
            .first()
            .expect("version not found");
        hook_toml = dep_src_dir
            .join(crates_parent)
            .join(format!(
                "dep-{}.{}.{}",
                version.major,
                version.minor.unwrap_or(0),
                version.patch.unwrap_or(0)
            ))
            .join("Cargo.toml");
    }
    if !dependency.uses_default_features {
        cmd = cmd.arg("--no-default-features");
    }
    let features: Vec<&str> = Vec::new();
    if let Err(e) = cmd
        .arg("--features")
        .arg(features.join(","))
        .arg("--manifest-path")
        .arg(hook_toml)
        .arg("--target-dir")
        .arg(out_dir.clone())
        .status()
    {
        panic!("failed to build dylib {}", e);
    }
    // correct dylib path
    let hook_deps = out_dir
        .join(target)
        .join(if cfg!(debug_assertions) {
            "debug"
        } else {
            "release"
        })
        .join("deps");
    let deps = out_dir
        .parent()
        .expect("can not find deps dir")
        .parent()
        .expect("can not find deps dir")
        .parent()
        .expect("can not find deps dir")
        .join("deps");
    for entry in read_dir(hook_deps.clone())
        .expect("can not find deps dir")
        .flatten()
    {
        let file_name = entry.file_name().to_string_lossy().to_string();
        if !file_name.contains("dep") {
            continue;
        }
        if cfg!(target_os = "linux") && file_name.ends_with(".so") {
            let from = hook_deps.join(file_name);
            let to = deps.join("libdep.so");
            copy(from.clone(), to.clone()).expect("copy to libdep.so failed!");
        } else if cfg!(target_os = "macos") && file_name.ends_with(".dylib") {
            let from = hook_deps.join(file_name);
            let to = deps.join("libdep.dylib");
            copy(from.clone(), to.clone()).expect("copy to libdep.dylib failed!");
        } else if cfg!(windows) {
            if file_name.ends_with(".dll") {
                let from = hook_deps.join(file_name);
                let to = deps.join("dep.dll");
                copy(from.clone(), to.clone()).expect("copy to dep.dll failed!");
            } else if file_name.ends_with(".lib") {
                let from = hook_deps.join(file_name);
                let to = deps.join("dep.lib");
                copy(from.clone(), to.clone()).expect("copy to dep.lib failed!");
            }
        }
    }
    // link dylib
    println!("cargo:rustc-link-lib=dylib=dep");
}

I expected to see this happen: it should be successfully linked

Instead, this happened: library 'dep' not found

Meta

rustc --version --verbose:

current stable
Backtrace

error: linking with `cc` failed: exit status: 1
  |
  = note: LC_ALL="C" PATH="/home/runner/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/bin:/snap/bin:/home/runner/.local/bin:/opt/pipx_bin:/home/runner/.cargo/bin:/home/runner/.config/composer/vendor/bin:/usr/local/.ghcup/bin:/home/runner/.dotnet/tools:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin" VSLANG="1033" "cc" "-m64" "/tmp/rustcC4e8ps/symbols.o" "/home/runner/work/link-example/link-example/target/x86_64-unknown-linux-gnu/debug/deps/mycrate-017e6f266393094c.16yuoqw4qihxedrxt7bjozxih.rcgu.o" "/home/runner/work/link-example/link-example/target/x86_64-unknown-linux-gnu/debug/deps/mycrate-017e6f266393094c.1i90mqsokdkai8vfc2qc3fs5r.rcgu.o" "/home/runner/work/link-example/link-example/target/x86_64-unknown-linux-gnu/debug/deps/mycrate-017e6f266393094c.1ow4wdo5q2m7qb6rrkywy4k0g.rcgu.o" "/home/runner/work/link-example/link-example/target/x86_64-unknown-linux-gnu/debug/deps/mycrate-017e6f266393094c.3bvcwvtb5z9wjvd3fry9zxnwl.rcgu.o" "/home/runner/work/link-example/link-example/target/x86_64-unknown-linux-gnu/debug/deps/mycrate-017e6f266393094c.41xajaflu2fvqgqr9ofx75ayl.rcgu.o" "/home/runner/work/link-example/link-example/target/x86_64-unknown-linux-gnu/debug/deps/mycrate-017e6f266393094c.4f09v7k4mhfotmqfnhqg7we1u.rcgu.o" "/home/runner/work/link-example/link-example/target/x86_64-unknown-linux-gnu/debug/deps/mycrate-017e6f266393094c.6ns745cs1exrcanfduxjvotot.rcgu.o" "/home/runner/work/link-example/link-example/target/x86_64-unknown-linux-gnu/debug/deps/mycrate-017e6f266393094c.6qcse19qldku4gznimzacjyue.rcgu.o" "/home/runner/work/link-example/link-example/target/x86_64-unknown-linux-gnu/debug/deps/mycrate-017e6f266393094c.8o9vu0ztih3lndi8b6vk6572x.rcgu.o" "/home/runner/work/link-example/link-example/target/x86_64-unknown-linux-gnu/debug/deps/mycrate-017e6f266393094c.997gv3oaw5u68cciatpbgtatc.rcgu.o" "/home/runner/work/link-example/link-example/target/x86_64-unknown-linux-gnu/debug/deps/mycrate-017e6f266393094c.9f4sqyw0cel31ozpin2coz2gh.rcgu.o" "/home/runner/work/link-example/link-example/target/x86_64-unknown-linux-gnu/debug/deps/mycrate-017e6f266393094c.aph3sk39otglbj4zwk6wzoxtk.rcgu.o" "/home/runner/work/link-example/link-example/target/x86_64-unknown-linux-gnu/debug/deps/mycrate-017e6f266393094c.b4giartyvdgi3iu0uo4qakzdw.rcgu.o" "/home/runner/work/link-example/link-example/target/x86_64-unknown-linux-gnu/debug/deps/mycrate-017e6f266393094c.b8cbe7qisu09nn0vlcpyr9qvj.rcgu.o" "/home/runner/work/link-example/link-example/target/x86_64-unknown-linux-gnu/debug/deps/mycrate-017e6f266393094c.bloz9x20vbeaosqhd1wh7gp1e.rcgu.o" "/home/runner/work/link-example/link-example/target/x86_64-unknown-linux-gnu/debug/deps/mycrate-017e6f266393094c.bynfem9r1213phlalld2vjpac.rcgu.o" "/home/runner/work/link-example/link-example/target/x86_64-unknown-linux-gnu/debug/deps/mycrate-017e6f266393094c.byu94s2lmx2i63rkze48obc03.rcgu.o" "/home/runner/work/link-example/link-example/target/x86_64-unknown-linux-gnu/debug/deps/mycrate-017e6f266393094c.d93qx84u7r6ww2obncqm2zdpa.rcgu.o" "/home/runner/work/link-example/link-example/target/x86_64-unknown-linux-gnu/debug/deps/mycrate-017e6f266393094c.evg0p8pgy9xiwz64pm373jq0q.rcgu.o" "/home/runner/work/link-example/link-example/target/x86_64-unknown-linux-gnu/debug/deps/mycrate-017e6f266393094c.7y1yrl52ww0nso4ebvk81p9xj.rcgu.o" "-Wl,--as-needed" "-Wl,-Bdynamic" "-ldep" "-Wl,-Bstatic" "/home/runner/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libtest-aa035fdca64e6492.rlib" "/home/runner/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libgetopts-094c0ce9f8c98ed9.rlib" "/home/runner/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunicode_width-aa0663517f777947.rlib" "/home/runner/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_std-e1cd6e17fe237c71.rlib" "/home/runner/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-ca74a2d9c5166d9f.rlib" "/home/runner/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libpanic_unwind-e31ab23316ed5080.rlib" "/home/runner/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libobject-27dc4aa955912662.rlib" "/home/runner/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libmemchr-bd0d6cccce077b99.rlib" "/home/runner/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libaddr2line-8d001680935b5e3c.rlib" "/home/runner/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libgimli-ba8ce71964f984f4.rlib" "/home/runner/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_demangle-99a73526abcec14b.rlib" "/home/runner/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd_detect-63ac0d22cff92579.rlib" "/home/runner/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libhashbrown-9057355c92c922d5.rlib" "/home/runner/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_alloc-3[58](https://github.com/loongs-zhang/link-example/actions/runs/12441472853/job/34738401633#step:5:59)be9bc1f6bab04.rlib" "/home/runner/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libminiz_oxide-aca15549d5bff974.rlib" "/home/runner/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libadler-8251d2cef7072448.rlib" "/home/runner/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunwind-7d50b86011c66411.rlib" "/home/runner/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcfg_if-51ea098fce5006bf.rlib" "/home/runner/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-5a14e0d0b712e731.rlib" "/home/runner/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-8b83dbf3a7b8f999.rlib" "/home/runner/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_core-c6fd227bdc7b39ff.rlib" "/home/runner/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-9[59](https://github.com/loongs-zhang/link-example/actions/runs/12441472853/job/34738401633#step:5:60)d3389fa3da8a5.rlib" "/home/runner/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-abe05db089cc2c62.rlib" "-Wl,-Bdynamic" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-L" "/home/runner/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-o" "/home/runner/work/link-example/link-example/target/x86_64-unknown-linux-gnu/debug/deps/mycrate-017e6f266393094c" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-nodefaultlibs"
  = note: /usr/bin/ld: cannot find -ldep: No such file or directory
          collect2: error: ld returned 1 exit status

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-discussionCategory: Discussion or questions that doesn't represent real issues.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions