Can't link custom lib

Hi there! I have 2 crates:

  1. Vigem - crate with libs directory which have "VigemClient_x64.lib" and build script:
 #[cfg(target_arch = "x86_64")]
pub const LIB_NAME: &str = "VigemClient_x64";

#[cfg(target_arch = "x86")]
pub const LIB_NAME: &str = "VigemClient_x86";

fn main() {
    println!("cargo:rerun-if-changed=libs/{}", LIB_NAME);
    println!("cargo:rustc-link-search=libs");
    println!("cargo:rustc-link-lib=dylib=setupapi");
    println!("cargo:rustc-link-lib={}", LIB_NAME);
}
  1. XOut - crate which uses Vigem as dependency.

So, examples in vigem crate works fine! But when I use vigem as dependency, I get an error:

error: linking with `link.exe` failed: exit code: 1181
  |
  = note: "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.25.28610\\bin\\HostX64\\x64\\link.exe" "/NOLOGO" "/NXCOMPAT" "/LIBPATH:C:\\Users\\DuckerMan\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib" "C:\\Users\\DuckerMan\\Desktop\\RUST\\vigemy\\target\\debug\\deps\\vigemy.13scivpw3znq73fd.rcgu.o" "C:\\Users\\DuckerMan\\Desktop\\RUST\\vigemy\\target\\debug\\deps\\vigemy.1fg2nbnkvqxdm4xk.rcgu.o" "C:\\Users\\DuckerMan\\Desktop\\RUST\\vigemy\\target\\debug\\deps\\vigemy.2oc73foxj7dq9wjj.rcgu.o" 
"C:\\Users\\DuckerMan\\Desktop\\RUST\\vigemy\\target\\debug\\deps\\vigemy.39bgnojp24hevbwe.rcgu.o" "C:\\Users\\DuckerMan\\Desktop\\RUST\\vigemy\\target\\debug\\deps\\vigemy.3tiri1fxt3k18fzb.rcgu.o" "C:\\Users\\DuckerMan\\Desktop\\RUST\\vigemy\\target\\debug\\deps\\vigemy.4ezpkg0nwk42k0gc.rcgu.o" "C:\\Users\\DuckerMan\\Desktop\\RUST\\vigemy\\target\\debug\\deps\\vigemy.4l7tv4sxp7p9k710.rcgu.o" "C:\\Users\\DuckerMan\\Desktop\\RUST\\vigemy\\target\\debug\\deps\\vigemy.4r3edl6ifme6bc61.rcgu.o" "C:\\Users\\DuckerMan\\Desktop\\RUST\\vigemy\\target\\debug\\deps\\vigemy.4we9apttnrtn88xt.rcgu.o" "C:\\Users\\DuckerMan\\Desktop\\RUST\\vigemy\\target\\debug\\deps\\vigemy.b4zwmipdxtixfy2.rcgu.o" "/OUT:C:\\Users\\DuckerMan\\Desktop\\RUST\\vigemy\\target\\debug\\deps\\vigemy.exe" "C:\\Users\\DuckerMan\\Desktop\\RUST\\vigemy\\target\\debug\\deps\\vigemy.2xtxujq08lpjy6yn.rcgu.o" "/OPT:REF,NOICF" "/DEBUG" "/NATVIS:C:\\Users\\DuckerMan\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\etc\\intrinsic.natvis" "/NATVIS:C:\\Users\\DuckerMan\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\etc\\liballoc.natvis" "/NATVIS:C:\\Users\\DuckerMan\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\etc\\libcore.natvis" "/NATVIS:C:\\Users\\DuckerMan\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\etc\\libstd.natvis" "/LIBPATH:C:\\Users\\DuckerMan\\Desktop\\RUST\\vigemy\\target\\debug\\deps" "/LIBPATH:libs" "/LIBPATH:C:\\Users\\DuckerMan\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib" "C:\\Users\\DuckerMan\\Desktop\\RUST\\vigemy\\target\\debug\\deps\\libvigem-dc28fc37d2d400be.rlib" "C:\\Users\\DuckerMan\\Desktop\\RUST\\vigemy\\target\\debug\\deps\\libvigem_sys-c785acfdaee95e4c.rlib" "C:\\Users\\DuckerMan\\Desktop\\RUST\\vigemy\\target\\debug\\deps\\libbitflags-63e431f540d116bf.rlib" 
"C:\\Users\\DuckerMan\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libstd-bc2b04b7c9a44f97.rlib" "C:\\Users\\DuckerMan\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libpanic_unwind-73c12b6959d9c5fd.rlib" "C:\\Users\\DuckerMan\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libhashbrown-c41a2b552e68f0cc.rlib" "C:\\Users\\DuckerMan\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\librustc_std_workspace_alloc-e79a4701ffa7cbcc.rlib" "C:\\Users\\DuckerMan\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libbacktrace-9f3b0426ee0f39d1.rlib" "C:\\Users\\DuckerMan\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\librustc_demangle-31bd0c60452501f1.rlib" "C:\\Users\\DuckerMan\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libunwind-a9c788e4be0605b0.rlib" "C:\\Users\\DuckerMan\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcfg_if-1999078cd5ceb0ce.rlib" "C:\\Users\\DuckerMan\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\liblibc-5dd545b022f6be58.rlib" "C:\\Users\\DuckerMan\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\liballoc-acd4590212ce9dae.rlib" "C:\\Users\\DuckerMan\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\librustc_std_workspace_core-87cb4dffff33f37a.rlib" "C:\\Users\\DuckerMan\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcore-81caf0281e0b427b.rlib" "C:\\Users\\DuckerMan\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcompiler_builtins-bb027328a052d4db.rlib" "setupapi.lib" "VigemClient_x64.lib" "advapi32.lib" "ws2_32.lib" "userenv.lib" "msvcrt.lib"
  = note: LINK : fatal error LNK1181: cannot open input file 'VigemClient_x64.lib'

Why link.exe cannot find `VigemClient_x64.lib?

It's really weird

Try adding cargo:rustc-link-search=PathToVigemClientDir to Xout's build.rs
I'm pretty sure that static libs don't contain their dependencies, you have to link them when linking the binary itself

So, where should I place VigemClient?

Add it to the linker's search path (the .lib itself)

I'm new at Rust, sorry. What is linker's search path ?

It's the path you give in cargo:rustc-link-search=

I have added my lib to vigem/libs, nothing changed :frowning:

I dont get it. Why does it work in Vigem examples, but doesnt in my other project?

As you wrote, Vigem examples has a build.rs script that points to a "libs" directory, on the other hand Xout doesn't, so you have to tell the linker where it can find "VigemClient_x64.lib".

You can do this by adding/modifying a build-script that prints cargo:rustc-link-search=... where ... would be replaced with the path where "VigemClient_x64.lib" can be found, just like "Vigem" does, except it probably will need to be an absolute path.

So, every project which use Vigem as dependency, should copy libs catalog to their project catalog? Are there any ways to avoid it?

I'm unfamiliar with how Vigem works, but unless Cargo builds the libs, the lib must be found in the linker search path. If you have many projects that depend on Vigem you could add it's path to your cargo config in the user's home directory.

Hm, there's something weird. Build.rs:

    let project_dir = std::env::var("OUT_DIR").unwrap();
    println!("cargo:rustc-link-search={}/libs", project_dir);

But if I place my libs files in C:\Users\Username\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\x86_64-pc-windows-msvc\lib it works. So, why does linker try to find different path?

You could do that, but I think that when you update Rust with rustup it may clear that directory, and you'd have to copy it over again (I'm not sure)

Using the link-search doesn't limit the search to that directory, it just adds the directory to the list of searched directories. It's like executing something in the %PATH% variable on Windows.

To avoid copying the same build script to all projects, you can move it to a separate crate. Rust calls such pattern sys crates.