Linker error when building no_std Windows DLL that uses libc


#1

Code can be found here: https://github.com/ArmsOfSorrow/testlib

I’m currently exploring low-level Rust and the build process, so that in the (hopefully not so distant) future we can see Rust running on Windows UWP devices such as HoloLens.
To be able to inspect if linking works correctly, I’m building a cdylib without std while depending on libc so that the resulting exe/dll links to the Windows CRT. However, something is going wrong and I get linker errors.

Here’s the code:

#![no_std]

extern crate libc;

use libc::isalnum;

fn plus_one(x: i32) -> i32 {
    x + 1
}

#[no_mangle]
pub extern "C" fn _DllMainCRTStartup() -> ! {
    loop {}
}

#[no_mangle]
pub extern "C" fn hello() -> libc::c_int {
    unsafe {
        let r = isalnum(0);
        r
    }
}

use core::panic::PanicInfo;

/// This function is called on panic.
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
    loop {}
}

Actually _DllMainCRTStartup should be defined in the CRT, but if I don’t provide it the linker complains. If I do, it does too, but it’s a warning instead of an error. Here’s the build output:

error: linking with `link.exe` failed: exit code: 1120
  |
  = note: "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Tools\\MSVC\\14.16.27023\\bin\\HostX64\\x64\\link.exe" "/NOLOGO" "/NXCOMPAT" "/LIBPATH:C:\\Users\\Krzysztof Lesiak\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib" "C:\\Users\\Krzysztof Lesiak\\Desktop\\devel\\projects\\testlib\\target\\debug\\deps\\testlib.5d6w581my25w0wab.rcgu.o" "/OUT:C:\\Users\\Krzysztof Lesiak\\Desktop\\devel\\projects\\testlib\\target\\debug\\deps\\testlib.dll" "/DEF:C:\\Users\\KRZYSZ~1\\AppData\\Local\\Temp\\rustcU0IXwr\\lib.def" "/OPT:REF,NOICF" "/DEBUG" "/NATVIS:C:\\Users\\Krzysztof Lesiak\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\etc\\intrinsic.natvis" "/NATVIS:C:\\Users\\Krzysztof Lesiak\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\etc\\liballoc.natvis" "/NATVIS:C:\\Users\\Krzysztof Lesiak\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\etc\\libcore.natvis" "/LIBPATH:C:\\Users\\Krzysztof Lesiak\\Desktop\\devel\\projects\\testlib\\target\\debug\\deps" "/LIBPATH:C:\\Users\\Krzysztof Lesiak\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib" "C:\\Users\\Krzysztof Lesiak\\Desktop\\devel\\projects\\testlib\\target\\debug\\deps\\liblibc-bbaf1983144d1ebb.rlib" "C:\\Users\\Krzysztof Lesiak\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcore-29407e746c06360b.rlib" "C:\\Users\\Krzysztof Lesiak\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcompiler_builtins-a8eb281daba8cfb4.rlib" "/DLL" "/IMPLIB:C:\\Users\\Krzysztof Lesiak\\Desktop\\devel\\projects\\testlib\\target\\debug\\deps\\testlib.dll.lib"
  = note: LINK : warning LNK4216: Exported entry point _DllMainCRTStartup
             Creating library C:\Users\Krzysztof Lesiak\Desktop\devel\projects\testlib\target\debug\deps\testlib.dll.lib and object C:\Users\Krzysztof Lesiak\Desktop\devel\projects\testlib\target\debug\deps\testlib.dll.exp
          testlib.5d6w581my25w0wab.rcgu.o : error LNK2019: unresolved external symbol isalnum referenced in function hello
          C:\Users\Krzysztof Lesiak\Desktop\devel\projects\testlib\target\debug\deps\testlib.dll : fatal error LNK1120: 1 unresolved externals


error: aborting due to previous error

error: Could not compile `testlib`.

To learn more, run the command again with --verbose.

Am I doing something obviously wrong here? @retep998, do you have an idea?


#2

According to that error message, you’re not actually linking to the CRT. It’s not listed in the input to link.exe. Interestingly, it seems libc only links to the CRT when being built as a dependency of std, not as a normal dependency. https://github.com/rust-lang/libc/blob/master/src/windows/mod.rs#L199


#3

Thanks for pointing it out, I’ve missed that cfg block.

Should I file a bug in libc?


#4

Definitely file an issue to get a conversation going on what should happen for no_std programs trying to use libc.