Linking native code with the crate-type "staticlib" causes link failures with internal Windows APIs on Windows
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.2k
- PR merge metrics
- PR metrics pending
Description
Code
I tried this project:
Cargo.toml:
[package]
name = "example"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = [ "lib", "staticlib", "cdylib" ]
rust-toolchain.toml:
[toolchain]
# channel = "1.56.0" # Does work
# channel = "1.60.0" # Does work
# channel = "1.69.0" # Does work
# channel = "1.70.0" # Does not work
# channel = "1.74.1" # Does not work
channel = "stable" # Does not work
# channel = "beta" # Does not work
# channel = "nightly" # Does not work
src/lib.rs:
#[no_mangle]
pub extern "C" fn hello_world()
{
println!("Hello World");
}
src/main.cpp:
#if USE_STATIC_API
#define EXAMPLE_API __cdecl
#else
#define EXAMPLE_API __declspec(dllimport) __cdecl
#endif
extern "C"
{
void EXAMPLE_API hello_world();
}
int wmain()
{
hello_world();
return 0;
}
build.ps1:
cargo clean
cargo b --release
cl /nologo /utf-8 /EHsc /std:c++latest /Zc:preprocessor /permissive- /W4 /Zc:__cplusplus /MD /Fotarget\release\build\ /Fetarget\release\main_static.exe /DUSE_STATIC_API=1 .\src\main.cpp .\target\release\example.lib OneCore.lib
cl /nologo /utf-8 /EHsc /std:c++latest /Zc:preprocessor /permissive- /W4 /Zc:__cplusplus /MD /Fotarget\release\build\ /Fetarget\release\main_dynamic.exe .\src\main.cpp .\target\release\example.dll.lib
build.ps1 is not required, but it was helpful for testing and documents how I'm building the code.
I expected to see this happen:
A C++ application linking against example.lib links & runs successfully.
> .\build.ps1
Compiling example v0.1.0 (C:\Users\bartw\source\rust\Testing)
Finished release [optimized] target(s) in 0.31s
main.cpp # using staticlib, all fine
main.cpp # using cdylib, all fine
> .\target\release\main_static.exe
Hello World
Instead, this happened:
Linking errors to internal Windows APIs:
> .\build.ps1
Removed 23 files, 22.3MiB total
Compiling example v0.1.0 (C:\Users\bartw\source\rust\Testing)
Finished release [optimized] target(s) in 0.35s
main.cpp # using staticlib, linker errors
example.lib(std-0953e6946d141dd5.std.1acf644841c643e8-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_NtCreateFile referenced in function _ZN3std3sys7windows2fs20open_link_no_reparse17hca07eefe7f3c23d8E
example.lib(std-0953e6946d141dd5.std.1acf644841c643e8-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_RtlNtStatusToDosError referenced in function _ZN3std3sys7windows2fs20open_link_no_reparse17hca07eefe7f3c23d8E
example.lib(std-0953e6946d141dd5.std.1acf644841c643e8-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_NtReadFile referenced in function _ZN3std3sys7windows6handle6Handle16synchronous_read17h5729adfb8e80a411E
example.lib(std-0953e6946d141dd5.std.1acf644841c643e8-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_NtWriteFile referenced in function _ZN3std3sys7windows6handle6Handle17synchronous_write17h87d0e51b32ace2e3E
target\release\main_static.exe : fatal error LNK1120: 4 unresolved externals
main.cpp # using cdylib, all fine
Version it worked on
It most recently worked on:
rustc 1.69.0 (84c898d65 2023-04-16)
binary: rustc
commit-hash: 84c898d65adf2f39a5a98507f1fe0ce10a2b8dbc
commit-date: 2023-04-16
host: x86_64-pc-windows-msvc
release: 1.69.0
LLVM version: 15.0.7
Version with regression
First noticed with:
rustc 1.74.1 (a28077b28 2023-12-04)
binary: rustc
commit-hash: a28077b28a02b92985b3a3faecf92813155f1ea1
commit-date: 2023-12-04
host: x86_64-pc-windows-msvc
release: 1.74.1
LLVM version: 17.0.4
Lowest version tested which did not work:
rustc 1.70.0 (90c541806 2023-05-31)
binary: rustc
commit-hash: 90c541806f23a127002de5b4038be731ba1458ca
commit-date: 2023-05-31
host: x86_64-pc-windows-msvc
release: 1.70.0
LLVM version: 16.0.2
Versions not listed in the rust-toolchain.toml example above where not tested.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the regression using Cargo.toml, rust-toolchain.toml, src/lib.rs, src/main.cpp, and build.ps1, comparing Rust 1.69.0 with 1.70.0 or later. Trace the staticlib link path and its Windows API dependencies, then verify that the static C++ executable links and runs without unresolved symbols while the cdylib case remains working.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, powershell, rust
- Domain
- build-system, compilers, operating-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100