I'm facing a problem with C++20 on a project build with CMake and Bazel, where both work on c++17/c++20 on linux (GCC and Clang), but they fail only on windows msvc with c++20. The error is a link error (LNK2019), which is quite strange because it was CMake (or Bazel) themselves that built the objects, yet they fail to link. I put some reproducible code here on github, although quite big the project: https://github.com/manydeps/manydeps-cln I have tried to change the MSVC version (github actions offers 4 different ones for windows-2022 / windows-latest image): 14.16.27023, 14.29.30133, 14.35.32215 and 14.37.32822. Another strange thing is that CMake decides to use 14.35.32215, while Bazel uses 14.37.32822 (and I couldn't change that, even by deleting the folder). I'm building this as a static /MT library on windows (and .a on linux).
This is the strange link error for CLN project:
[5 / 6] Linking app_demo_cln.exe; 1s local
ERROR: D:/a/manydeps-cln/manydeps-cln/BUILD.bazel:21:10: Linking app_demo_cln.exe failed: (Exit 1120): link.exe failed: error executing command (from target //:app_demo_cln) C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.35.32215\bin\HostX64\x64\link.exe @bazel-out/x64_windows-fastbuild/bin/app_demo_cln.exe-2.params
cln.lib(cl_prin_globals.obj) : error LNK2019: unresolved external symbol "struct cln::cl_heap_string * __cdecl cl_make_heap_string(char const *)" (?cl_make_heap_string@@YAPEAUcl_heap_string@cln@@PEBD@Z) referenced in function "public: __cdecl cln::cl_string::cl_string(char const *)" (??0cl_string@cln@@QEAA@PEBD@Z)
Hint on symbols that are defined and could potentially match:
"struct cln::cl_heap_string * __cdecl cln::cl_make_heap_string(char const *)" (?cl_make_heap_string@cln@@YAPEAUcl_heap_string@1@PEBD@Z)
bazel-out\x64_windows-fastbuild\bin\app_demo_cln.exe : fatal error LNK1120: 1 unresolved externals
Target //:app_demo_cln failed to build
The function cl_make_heap_string exists on CLN library, but the name mangling seems strange... something like cl_make_heap_string@cln@@YAPEAUcl_heap_string@1@PEBD@Z and cl_make_heap_string@@YAPEAUcl_heap_string@cln@@PEBD@Z, so that they won't match.
I tried to change the compilers, change flags in the compiler and look for answers in the Internet for many days already, with no solution.
Thanks @Tsyvarev for the precise comment on the nature of the linking error, that demonstrated a problem in global vs specific namespace for naming. I indeed checked the code, and this is a snippet:
Definition (some random
.ccfile):Declaration (some random
.hfile):So it's interesting that up to C++17 standard, the symbols match between both, but with C++20 strict (
/permissive-) behavior they no longer match (so/permissiveis needed, but I wanted a real fix). I took a look and perhaps the bug defect on C++ that could be responsible is this "1477. Definition of a friend outside its namespace": https://cplusplus.github.io/CWG/issues/1477.htmlOriginal text:
Fixed text in 2012:
So, I changed the declaration and it really worked on C++20 strict mode!
Fixed declaration:
So, thanks a lot for the help!