Skip to content

Commit 70b16fe

Browse files
committed
fix(random): name bcrypt the way this package already names libraries
`src/win.cpp` records the four Win32 libraries this backend calls into as linker directives in the object, under `#if defined(_MSC_VER)`, and `mcpp.toml` says so four lines below the block I was editing. Two manifest spellings were pushed before reading that, and neither could have worked: `ldflags` reaches the command line verbatim, and the two toolchains `env = "msvc"` selects reject each other's word for a library. LINK.EXE -lbcrypt → LNK4044: unrecognized option '/lbcrypt' clang++ bcrypt.lib → error: no such file or directory `cfg()` cannot separate them: its four keys name the target, and which compiler drives the link is not a property of the target. The directive mechanism needs no key, and both toolchains on that side read it. clang++ --target=x86_64-pc-windows-msvc -c → Directive(s): /DEFAULTLIB:bcrypt.lib clang++ --target=x86_64-w64-windows-gnu → _MSC_VER undefined, ignored; the GNU list in the manifest carries it The pragma is in `src/random.cpp` rather than beside the other four because a directive travels in the object that carries it, and the object a linker pulls in for `kal_random_fill` is that one.
1 parent ffb96cf commit 70b16fe

2 files changed

Lines changed: 22 additions & 35 deletions

File tree

mcpp.toml

Lines changed: 2 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -51,40 +51,6 @@ openkal = "0.7.0"
5151
[target.'cfg(all(windows, not(env = "msvc")))'.build]
5252
ldflags = ["-lntdll", "-lsynchronization", "-lshell32", "-lkernel32", "-lbcrypt"]
5353

54-
# ⚠️ AND THE SAME ONE LIBRARY ON THE MSVC SIDE, WHICH UNTIL NOW NEEDED NONE.
55-
#
56-
# The block above lists the four this implementation calls into, and the MSVC
57-
# side never needed a list: its SDK links the usual set implicitly, so a
58-
# `ldflags` entry there would have been noise. `openkal.random` changes that —
59-
# `BCryptGenRandom` is in `bcrypt.lib`, and that one is not among the implicit
60-
# set on either the MSVC toolchain or clang's `windows-msvc` target.
61-
#
62-
# Measured on the conformance matrix, both Windows rows:
63-
#
64-
# lld-link: error: undefined symbol: __declspec(dllimport) BCryptGenRandom
65-
#
66-
# ⚠️ The predicate above is `not(env = "msvc")`, so neither row saw the entry
67-
# there. The library is named once per side because the two sides spell a
68-
# library differently and share no list.
69-
#
70-
# ⭐ AND THE SPELLING HERE IS `bcrypt.lib`, NOT `-lbcrypt`. `ldflags` reaches
71-
# the command line verbatim; mcpp's dialect abstraction covers the flags it
72-
# generates itself, not the ones a manifest writes. The two rows this
73-
# predicate selects do not drive the same program: clang drives lld-link and
74-
# translates for it, while `msvc@system` drives LINK.EXE directly, and LINK
75-
# reads `-` and `/` as the same prefix — so `-lbcrypt` arrives as an option
76-
# named `l`:
77-
#
78-
# LINK : warning LNK4044: unrecognized option '/lbcrypt'; ignored
79-
# random.obj : error LNK2019: unresolved external symbol __imp_BCryptGenRandom
80-
#
81-
# One spelling serves both, which is why this stays a single entry. Measured
82-
# with `clang --target=x86_64-pc-windows-msvc -### … -fuse-ld=lld`: the driver
83-
# emits `bcrypt.lib` to lld-link for `-lbcrypt` and for `bcrypt.lib` alike, so
84-
# the clang link line is unchanged by this and only LINK.EXE sees a difference.
85-
[target.'cfg(all(windows, env = "msvc"))'.build]
86-
ldflags = ["bcrypt.lib"]
87-
8854
# Exceptions and run-time type information, on the one ABI where their absence
8955
# is asserted.
9056
#
@@ -101,7 +67,8 @@ ldflags = ["bcrypt.lib"]
10167
# nothing to say about how a program that has a runtime unwinds.
10268
cxxflags = ["-fno-exceptions", "-fno-rtti"]
10369

104-
# The other ABI names them in src/win.cpp instead, where its compilers record
70+
# The other ABI names them in the sources instead --- src/win.cpp for the four
71+
# above and src/random.cpp for bcrypt --- where its compilers record
10572
# the requirement in the object they produce. A library named on the link line
10673
# there would have to be named again by every program that links this package;
10774
# a library named in the object travels with it.

src/random.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,26 @@
3131
// exists to stop depending on, as the note at the top of that file says. What
3232
// this backend links against is either the vendor's SDK or this package's own
3333
// generated libraries, and never a third party's.
34+
// The library this one interface lives in, named the way src/win.cpp names the
35+
// other four and for the reason given there. It is here rather than beside
36+
// them because a directive travels in the object that carries it, and the
37+
// object a linker pulls in for `kal_random_fill` is this one.
38+
//
39+
// ⚠️ TWO SPELLINGS IN THE MANIFEST WERE TRIED BEFORE THIS AND BOTH WERE PUSHED,
40+
// while the mechanism was already established in this package and named four
41+
// lines below the block being edited. `ldflags` reaches the command line
42+
// verbatim, and the two toolchains that `env = "msvc"` selects reject each
43+
// other's word for a library:
44+
//
45+
// LINK.EXE -lbcrypt → LNK4044: unrecognized option '/lbcrypt'
46+
// clang++ bcrypt.lib → error: no such file or directory
47+
//
48+
// `cfg()` cannot separate them — its four keys name the target, and which
49+
// compiler drives the link is not a property of the target.
50+
#if defined(_MSC_VER)
51+
#pragma comment(lib, "bcrypt.lib")
52+
#endif
53+
3454
#include "win.h"
3555
#include <openkal/random.h>
3656

0 commit comments

Comments
 (0)