Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linking static library using C++/CX with C++/WinRT runtime component fails #1053

Closed
sylveon opened this issue Oct 28, 2021 · 5 comments
Closed

Comments

@sylveon
Copy link
Contributor

sylveon commented Oct 28, 2021

  1. Create a new C++/WinRT Windows Runtime component
  2. In the same solution, create a UWP static library.
  3. In that static library project, enable /ZW, and write a dummy function making use of C++/CX, like so:
    int foo()
    {
    	return (ref new Platform::String(L"aaa"))->Length();
    }
  4. In the runtime component project, add a reference to the static library project, and replace the default property getter to call foo():
    int32_t Class::MyProperty()
    {
        return foo();
    }
  5. Observe the build fail with these errors:
    2>------ Build started: Project: RuntimeComponent19, Configuration: Debug x64 ------
    2>vccorlibd.lib(init.obj) : error LNK2038: mismatch detected for 'vccorlib_lib_should_be_specified_before_msvcrt_lib_to_linker': value '1' doesn't match value '0' in MSVCRTD.lib(app_appinit.obj)
    2>vccorlibd.lib(init.obj) : error LNK2005: __crtWinrtInitType already defined in MSVCRTD.lib(app_appinit.obj)
    2>   Creating library T:\Projects\RuntimeComponent19\x64\Debug\RuntimeComponent19\RuntimeComponent19.lib and object T:\Projects\RuntimeComponent19\x64\Debug\RuntimeComponent19\RuntimeComponent19.exp
    2>T:\Projects\RuntimeComponent19\x64\Debug\RuntimeComponent19\RuntimeComponent19.dll : fatal error LNK1169: one or more multiply defined symbols found
    2>Done building project "RuntimeComponent19.vcxproj" -- FAILED.
    

At work (unrelated to issue 1048, which is personal projects), we are migrating to C++/WinRT for all our own code, but must link to proprietary libraries for various DRM functions which use C++/CX internally. This issue is preventing us from using C++/WinRT entirely.

I tried following this Stack Overflow post, but the answers posted did not help.

@sylveon
Copy link
Contributor Author

sylveon commented Oct 28, 2021

To note that we cannot update the proprietary lib files using C++/CX to use C++/WinRT, they are provided to us by a third-party and are closed source.

@kennykerr
Copy link
Collaborator

This sounds more like a question for the C++ team. I suspect they're using incompatible versions of the CRT. Static libs (I believe) need to all use the same CRT in order to be compiled together into a single binary. For C++/WinRT you can use whatever CRT is supported by Visual C++. For C++/CX you're at the mercy of whatever CRT it supports.

@sylveon
Copy link
Contributor Author

sylveon commented Oct 28, 2021

Yeah, I'll see if I can get it to use the CRT that CX is using.

Enabling C++/CX but not using it on the runtime component project might work, but prevents us from using C++20, which we would like to use...

@kennykerr
Copy link
Collaborator

Yes, I don't think the C++ team is going to support C++20 with C++/CX.

@sylveon
Copy link
Contributor Author

sylveon commented Nov 10, 2021

Ok so the fix on StackOverflow does work, but forgets to mention something critical. All the C++/CX libraries you want to use have to be specified before any other library (including vccorlib and msvcrt), meaning you can't use project references (because that adds the .lib at the end). So if your C++/CX static lib is named mylib, your "additional dependencies" should be the following:

mylib.lib;vccorlib.lib;msvcrt.lib;everythingelse.lib;%(AdditionalDependencies)

Without this, the linker will start scanning other .libs, find some references to msvcrt.lib and then load that, while when the C++/CX library is first, it will scan that first, find references to vccorlib.lib, and load it first.

Wrong order:

1>Processed /NODEFAULTLIB:vccorlibd
1>Processed /NODEFAULTLIB:msvcrtd
1>Starting pass 1
1>Processed /DEFAULTLIB:uuid.lib
1>Processed /DEFAULTLIB:msvcprtd
1>Processed /DEFAULTLIB:OLDNAMES
1>Processed /DEFAULTLIB:concrtd
1>Searching libraries
1>    Searching C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.29.30133\lib\x86\store\vccorlibd.lib:
1>    Searching C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.29.30133\lib\x86\store\msvcrtd.lib:
1>      Found "void __stdcall `eh vector destructor iterator'(void *,unsigned int,unsigned int,void (__thiscall*)(void *))" (??_M@YGXPAXIIP6EX0@Z@Z)
1>        Referenced in somecodefile.obj
1>        Loaded msvcrtd.lib(ehvecdtr.obj)

Right order:

1>Processed /NODEFAULTLIB:vccorlibd.lib
1>Processed /NODEFAULTLIB:msvcrtd.lib
1>Starting pass 1
1>Processed /DEFAULTLIB:uuid.lib
1>Processed /DEFAULTLIB:msvcprtd
1>Processed /DEFAULTLIB:OLDNAMES
1>Processed /DEFAULTLIB:concrtd
1>Searching libraries
1>    Searching mylib.lib:
1>      Found "something" (mangledname)
1>        Referenced in somecodefile.obj
1>        Loaded mylib.lib(codefilefromlib.obj)
1>    Searching C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.29.30133\lib\x86\store\vccorlibd.lib:
1>      Found "__declspec(dllimport) void __stdcall __abi_WinRTraiseNotImplementedException(void)" (__imp_?__abi_WinRTraiseNotImplementedException@@YGXXZ)
1>        Referenced in mylib.lib(codefilefromlib.obj)
1>        Loaded vccorlibd.lib(vccorlib140d_app.DLL)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants