Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[rustbuild] cannot link to printf with MSVC on AppVeyor #42830

Closed
kennytm opened this issue Jun 22, 2017 · 4 comments
Closed

[rustbuild] cannot link to printf with MSVC on AppVeyor #42830

kennytm opened this issue Jun 22, 2017 · 4 comments
Labels
O-windows-msvc Toolchain: MSVC, Operating system: Windows

Comments

@kennytm
Copy link
Member

kennytm commented Jun 22, 2017

Spun off from #42777 (comment). The test case for error code E0060 contains an invocation to the C function printf. On MSVC, performing doctest on this test case failed with

  = note: rust_out.0.o : error LNK2019: unresolved external symbol printf referenced in function _ZN8rust_out4main17ha22022d8940e3e88E

Currently I'm checking if there is any missing linker args should be added to make the pass without #[cfg]ing it out.


Minimal test case

Code (copy of E0060), see https://github.com/kennytm/test-term-coloring/tree/43a23596b

/**
```
# use std::os::raw::{c_char, c_int};
# extern "C" { fn printf(_: *const c_char, ...) -> c_int; }
unsafe {
    use std::ffi::CString;
    let fmt = CString::new("test\n").unwrap();
    printf(fmt.as_ptr());
    let fmt = CString::new("number = %d\n").unwrap();
    printf(fmt.as_ptr(), 3);
    let fmt = CString::new("%d, %d\n").unwrap();
    printf(fmt.as_ptr(), 10, 5);
}
```
*/
pub fn wut() {}

Test result, see https://ci.appveyor.com/project/kennytm/test-term-coloring/build/1.0.2

   Doc-tests test-term-coloring
running 1 test
error: linking with `link.exe` failed: exit code: 1120
  |
  = note: "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\bin\\amd64\\link.exe" "/NOLOGO" "/NXCOMPAT" "/LIBPATH:C:\\Users\\appveyor\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib" "C:\\Users\\appveyor\\AppData\\Local\\Temp\\1\\rustdoctest.xIdH18C27InS\\rust_out.0.o" "/OUT:C:\\Users\\appveyor\\AppData\\Local\\Temp\\1\\rustdoctest.xIdH18C27InS\\rust_out.exe" "/OPT:REF,NOICF" "/DEBUG" "/LIBPATH:C:\\projects\\test-term-coloring\\target\\x86_64-pc-windows-msvc\\debug\\deps" "/LIBPATH:C:\\Users\\appveyor\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib" "/LIBPATH:C:\\Users\\appveyor\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib" "std-7c926edf41e020d3.dll.lib" "C:\\Users\\appveyor\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcompiler_builtins-ce3e1312c7c980ee.rlib" "advapi32.lib" "ws2_32.lib" "userenv.lib" "shell32.lib" "msvcrt.lib"
  = note: rust_out.0.o : error LNK2019: unresolved external symbol printf referenced in function _ZN8rust_out4main17ha22022d8940e3e88E
          C:\Users\appveyor\AppData\Local\Temp\1\rustdoctest.xIdH18C27InS\rust_out.exe : fatal error LNK1120: 1 unresolved externals
          
error: aborting due to previous error(s)
thread 'rustc' panicked at 'Box<Any>', src\librustc_errors\lib.rs:512
note: Run with `RUST_BACKTRACE=1` for a backtrace.
thread 'rustc' panicked at 'couldn't compile the test', src\librustdoc\test.rs:278
test src\lib.rs - wut (line 1) ... FAILED
failures:
failures:
    src\lib.rs - wut (line 1)
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out
@retep998
Copy link
Member

retep998 commented Jun 22, 2017

With the new Universal CRT, msvc has switched to all the printf functions being inline wrapper functions. This is a known issue that has been hit before in Rust If you really want printf the solution is to link against legacy_stdio_definitions.lib which provides the printf wrapper functions as normal symbols to link against, but only when using a newer msvc that uses the Universal CRT. For older versions (such as VS 2013) that library does not exist and you can use printf normally.

@retep998 retep998 added the O-windows-msvc Toolchain: MSVC, Operating system: Windows label Jun 22, 2017
@kennytm
Copy link
Member Author

kennytm commented Jun 22, 2017

Looks like adding

#[cfg_attr(all(windows, target_env="msvc"), link(name="legacy_stdio_definitions", kind="static"))]

to the extern block works.

It is not possible to cfg the linker version in the doctest. As we are just using the default VS version on AppVeyor i.e. VS2015, I'll just add the attribute and ignore VS2013.

@kennytm kennytm closed this as completed Jun 22, 2017
@retep998
Copy link
Member

Please don't use kind="static". Either use dylib or static-nobundle. static should only be used when the bundling behavior is necessary.

@kennytm
Copy link
Member Author

kennytm commented Jun 22, 2017

@retep998 Thanks. static-nobundle should be the only option then? legacy_stdio_definitions does not seem to be a dynamic library.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
O-windows-msvc Toolchain: MSVC, Operating system: Windows
Projects
None yet
Development

No branches or pull requests

2 participants