Help needed linking external libraries on windows


#1

I’m getting frustrated trying to link against external dependencies.

This is on Windows with the msvc toolchain. I want to add audio to my program. I don’t care too much which library I use as long as I get cross-platform audio, but that pretty much seems to imply an external C library across the board.

Right now I’m trying to depend on ears 0.3.5: https://github.com/jhasse/ears

I’ve made one local edit to change the requested openal to OpenAL32 to match my system. The name openal is for the gnu target and I’m using the msvc target.

I get an error like this:

error: linking with `link.exe` failed: exit code: 1181
note: "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\bin\\amd64\\link.exe" "/LIBPATH:C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\lib\\amd64" "/LIBPATH:C:\\Program Files (x86)\\Windows Kits\\10\\lib\\10.0.10586.0\\ucrt\\x64" "/LIBPATH:C:\\Program Files (x86)\\Windows Kits\\10\\lib\\10.0.10586.0\\um\\x64" "/NOLOGO" "/NXCOMPAT" "/LIBPATH:C:\\Users\\dagit\\.multirust\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib" "C:\\Users\\dagit\\Source\\Repos\\rust-2d-demo\\target\\debug\\deps\\ears-67a37438b43c3377.0.o" "/OUT:C:\\Users\\dagit\\Source\\Repos\\rust-2d-demo\\target\\debug\\deps\\ears-67a37438b43c3377.dll" "/DEF:C:\\Users\\dagit\\AppData\\Local\\Temp\\rustc.ssTxpDcnVVhp\\lib.def" "C:\\Users\\dagit\\Source\\Repos\\rust-2d-demo\\target\\debug\\deps\\ears-67a37438b43c3377.metadata.o" "/OPT:REF,ICF" "/DEBUG" "/LIBPATH:C:\\Users\\dagit\\Source\\Repos\\rust-2d-demo\\target\\debug\\deps" "/LIBPATH:C:\\Users\\dagit\\Source\\Repos\\rust-2d-demo\\target\\debug\\deps" "/LIBPATH:C:\\Users\\dagit\\.multirust\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib" "OpenAL32.lib" "sndfile.lib" "C:\\Users\\dagit\\AppData\\Local\\Temp\\rustc.ssTxpDcnVVhp\\liblibc-1417726cb94dbc83.rlib" "/LIBPATH:C:\\Users\\dagit\\.multirust\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib" "std-39b92f95.dll.lib" "msvcrt.lib" "ws2_32.lib" "userenv.lib" "shell32.lib" "advapi32.lib" "msvcrt.lib" "/DLL" "/IMPLIB:C:\\Users\\dagit\\Source\\Repos\\rust-2d-demo\\target\\debug\\deps\\ears-67a37438b43c3377.dll.lib" "compiler-rt.lib"
note: LINK : fatal error LNK1181: cannot open input file 'OpenAL32.lib'

In the past, I could have had luck creating a file ./.cargo/config and adding lines like this:

[target.x86_64-pc-windows-msvc.OpenAL32]
rustc-link-search = ["C:/Program Files (x86)/OpenAL 1.1 SDK/libs/Win64"]
rustc-link-lib    = ["OpenAL32"]
root              = "C:/Program Files (x86)/OpenAL 1.1 SDK/libs/Win64"

I’ve tried adding that in this case, but it seems to get ignored. I set LIB="C:/Program Files (x86)/OpenAL 1.1 SDK/libs/Win64" on the command line before running cargo build and cargo is able to find it and I can move on to the next error (need sndfile.lib). This tells me that link.exe should be able to find the OpenAL32.lib that I have, if I could feed the correct paths.

What is wrong with my cargo config? I’ve tried moving it around to different locations but that doesn’t seem to help. Rustup lists this:

Default host: x86_64-pc-windows-msvc

installed toolchains
--------------------

stable-x86_64-pc-windows-gnu
stable-x86_64-pc-windows-msvc (default)
nightly-2016-08-01-x86_64-pc-windows-msvc

active toolchain
----------------

stable-x86_64-pc-windows-msvc (default)
rustc 1.11.0 (9b21dcd6a 2016-08-15)

I tried adding stable to my target name but that didn’t help.

Thanks!

PS. I asked this question on reddit as well, but no one has responded there yet.

Edit: Minor update. If I go into the ears package’s Cargo.toml and add a link in the [package] section that reads links = "OpenAL32" I’m then able to set the path via the cargo config file. What does this mean? How can I fix the ears package? Why does adding this line make a difference?


#2

Doing a cargo build script override of the form [target.x86_64-pc-windows-msvc.foo] will override the output of the build script for the crate in your dependency tree that has links = "foo". It does not override crates by name, it does not override based on library names. The override is purely done based on the target triple and the value of links. Because that crate does not have a links in its Cargo.toml, you could not override it until you added one to that crate yourself.