Skip to content

[Windows/Clang-cl] Linker errors while linking Rust-built static lib into a main project #115813

Closed
@amitin

Description

@amitin

In our C/C++ project we use Rust-written components as a static lib which includes C interface to Rust code.
We use cmake to invoke cargo as an external command. The static lib builds successfully this way and we link it into our main project's target dll.
We use Clang-CL toolkit as a part of MSVS 2022 to compile and link our project.
Updating Rust to 1.70+ causes linker errors (see below).

Cargo build command is

cargo.exe build --target x86_64-pc-windows-msvc --release

I expected to see this happen: successful build

Instead, this happened: linker errors

lld-link : error : undefined symbol: __declspec(dllimport) NtCreateFile [C:\workspace\ourproj.vcxproj]
  >>> referenced by /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\std\src\sys\windows\fs.rs:829
  >>>               esu_rust.lib(std-0f357f0f8e8eb48f.std.895242974ff7d01b-cgu.0.rcgu.o):(std::sys::windows::fs::open_l
  ink_no_reparse::h262f7b3e7853935c)

lld-link : error : undefined symbol: __declspec(dllimport) RtlNtStatusToDosError [C:\workspace\ourproj.vcxproj]
  >>> referenced by /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\std\src\sys\windows\fs.rs:858
  >>>               esu_rust.lib(std-0f357f0f8e8eb48f.std.895242974ff7d01b-cgu.0.rcgu.o):(std::sys::windows::fs::open_l
  ink_no_reparse::h262f7b3e7853935c)
  >>> referenced by /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\std\src\sys\windows\handle.rs:273
  >>>               esu_rust.lib(std-0f357f0f8e8eb48f.std.895242974ff7d01b-cgu.0.rcgu.o):(std::sys::windows::handle::Ha
  ndle::synchronous_read::h00067f19ba39bde9)
  >>> referenced by /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\std\src\sys\windows\handle.rs:319
  >>>               esu_rust.lib(std-0f357f0f8e8eb48f.std.895242974ff7d01b-cgu.0.rcgu.o):(std::sys::windows::handle::Ha
  ndle::synchronous_write::h977c567d7f264f32)

lld-link : error : undefined symbol: __declspec(dllimport) NtReadFile [C:\workspace\ourproj.vcxproj]
  >>> referenced by /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\std\src\sys\windows\handle.rs:242
  >>>               esu_rust.lib(std-0f357f0f8e8eb48f.std.895242974ff7d01b-cgu.0.rcgu.o):(std::sys::windows::handle::Ha
  ndle::synchronous_read::h00067f19ba39bde9)

lld-link : error : undefined symbol: __declspec(dllimport) NtWriteFile [C:\workspace\ourproj.vcxproj]
  >>> referenced by /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\std\src\sys\windows\handle.rs:291
  >>>               esu_rust.lib(std-0f357f0f8e8eb48f.std.895242974ff7d01b-cgu.0.rcgu.o):(std::sys::windows::handle::Ha
  ndle::synchronous_write::h977c567d7f264f32)

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

rustc --version --verbose:

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

Rust 1.72 also has this issue.

Workaround

Explicitly adding ntdll dependency fixes the issue, but this doesn't seem good to have an extra dependency.

Activity

added
C-bugCategory: This is a bug.
regression-untriagedUntriaged performance or correctness regression.
on Sep 13, 2023
added
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
I-prioritizeIssue: Indicates that prioritization has been requested for this issue.
on Sep 13, 2023
ChrisDenton

ChrisDenton commented on Sep 13, 2023

@ChrisDenton
Member

You also need ntdll.lib. To see all required native libs you can use rustc with --print native-static-libs.

amitin

amitin commented on Sep 13, 2023

@amitin
Author

Well, why did it work with 1.69? What was a purpose of adding dependency to ntdll.dll into Rust?

ChrisDenton

ChrisDenton commented on Sep 13, 2023

@ChrisDenton
Member

Well, why did it work with 1.69?

Because 1.69 used GetModuleHandle at runtime instead.

What was a purpose of adding dependency to ntdll.dll into Rust?

To save lazily loading the functions.

amitin

amitin commented on Sep 13, 2023

@amitin
Author

Thanks for your explanations.
Still not clear though why don't use kernel32.dll counterparts for these functions, but it's OK, closing the case.

ChrisDenton

ChrisDenton commented on Sep 13, 2023

@ChrisDenton
Member
  • NtCreateFile is used to mitigate CVE-2022-21658.
  • NtReadFile and NtWriteFile are used to avoid a soundness issue when stdin, stdout or stderr are opened for async reads or writes (also other file handles). See File implementation on Windows has unsound methods #81357.
  • RtlNtStatusToDosError is simply used to convert the status codes from the above two functions into normal Win32 errors.
removed
I-prioritizeIssue: Indicates that prioritization has been requested for this issue.
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
regression-untriagedUntriaged performance or correctness regression.
on Sep 13, 2023
added a commit that references this issue on Nov 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @amitin@ChrisDenton@apiraino@rustbot

        Issue actions

          [Windows/Clang-cl] Linker errors while linking Rust-built static lib into a main project · Issue #115813 · rust-lang/rust