diff --git a/library/std/src/sys/windows/net.rs b/library/std/src/sys/windows/net.rs
index 1ad13254c0846..1e1a02189dc79 100644
--- a/library/std/src/sys/windows/net.rs
+++ b/library/std/src/sys/windows/net.rs
@@ -2,10 +2,10 @@
 
 use crate::cmp;
 use crate::io::{self, IoSlice, IoSliceMut, Read};
+use crate::lazy::SyncOnceCell;
 use crate::mem;
 use crate::net::{Shutdown, SocketAddr};
 use crate::ptr;
-use crate::sync::Once;
 use crate::sys;
 use crate::sys::c;
 use crate::sys_common::net;
@@ -26,26 +26,31 @@ pub mod netc {
 
 pub struct Socket(c::SOCKET);
 
-static INIT: Once = Once::new();
+static WSA: SyncOnceCell<unsafe extern "system" fn() -> i32> = SyncOnceCell::new();
 
 /// Checks whether the Windows socket interface has been started already, and
 /// if not, starts it.
 pub fn init() {
-    INIT.call_once(|| unsafe {
+    let _ = WSA.get_or_init(|| unsafe {
         let mut data: c::WSADATA = mem::zeroed();
         let ret = c::WSAStartup(
             0x202, // version 2.2
             &mut data,
         );
         assert_eq!(ret, 0);
+
+        // Only register `WSACleanup` if `WSAStartup` is actually ever called.
+        // Workaround to prevent linking to `WS2_32.dll` when no network functionality is used.
+        // See issue #85441.
+        c::WSACleanup
     });
 }
 
 pub fn cleanup() {
-    if INIT.is_completed() {
-        // only close the socket interface if it has actually been started
+    // only perform cleanup if network functionality was actually initialized
+    if let Some(cleanup) = WSA.get() {
         unsafe {
-            c::WSACleanup();
+            cleanup();
         }
     }
 }
diff --git a/src/test/run-make/issue-85441/Makefile b/src/test/run-make/issue-85441/Makefile
new file mode 100644
index 0000000000000..0de956d3aee52
--- /dev/null
+++ b/src/test/run-make/issue-85441/Makefile
@@ -0,0 +1,9 @@
+# only-windows
+
+-include ../../run-make-fulldeps/tools.mk
+
+# Tests that WS2_32.dll is not unnecessarily linked, see issue #85441
+
+all:
+	$(RUSTC) empty.rs
+	objdump -p $(TMPDIR)/empty.exe | $(CGREP) -v -i "WS2_32.dll"
diff --git a/src/test/run-make/issue-85441/empty.rs b/src/test/run-make/issue-85441/empty.rs
new file mode 100644
index 0000000000000..f328e4d9d04c3
--- /dev/null
+++ b/src/test/run-make/issue-85441/empty.rs
@@ -0,0 +1 @@
+fn main() {}