MSVCRT Linkage Compatibility Question

Post Reply
gmdianaty
Posts: 7
Joined: Thu Oct 26 2023 4:30 am

MSVCRT Linkage Compatibility Question

Post by gmdianaty »

Hello!

Firstly, allow me to thank you folks -- community and contributors -- for your work on CopperSpice. It's a truly useful project with some truly inspiring goals.

I was recently working on brining CopperSpice with me into a new project, and in the course of that work I was faced with an interesting dilemma: I needed to build CopperSpice for the statically-linked MSVCRT.

I was able to build CsCore (as DLL) using the /MT directive, but experienced the '__acrt_first_block == header' assertion upon trying to compile CsGui (upon the invocation of rcc.exe). This assertion occurs upon the first instance of QString being initialized with a const char*.

It is my understanding that Qt has the ability to compile under /MT without issue, and remain in DLL form. Is CopperSpice also supportive of this case?

Thank you for your time!
Last edited by gmdianaty on Thu Mar 28 2024 2:42 am, edited 1 time in total.
barbara
Posts: 475
Joined: Sat Apr 04 2015 2:32 am
Contact:

Re: MSVCRT Linkage Compatibility Question

Post by barbara »

Thank you for the lovely comments about CopperSpice. Our team is very dedicated about this project.

We believe we can resolve these issues. There are multiple places you need to pass the directive and it sounds like it was not passed when building RCC. Please let us know the following information about how you built CopperSpice using MSVC.

1) Did you change any of our CMake build files? If so tell us exactly what changes you made.

2) The other piece of information we need is the command line parameters you passed during configuration or what settings you changed in VS.

Barbara
gmdianaty
Posts: 7
Joined: Thu Oct 26 2023 4:30 am

Re: MSVCRT Linkage Compatibility Question

Post by gmdianaty »

Of course!

My changes to CopperSpice's CMakeFiles.txt(s) can be found here: https://github.com/gdianaty/copperspice, and I also apply the following patch prior to compile:

Code: Select all

diff --git a/cmake/CopperSpiceConfigVersion.cmake b/cmake/CopperSpiceConfigVersion.cmake
index 4f11c5f49..3504850c8 100644
--- a/cmake/CopperSpiceConfigVersion.cmake
+++ b/cmake/CopperSpiceConfigVersion.cmake
@@ -35,7 +35,7 @@ if (MSVC OR "${CS_CHECK_BUILD_TYPE}")
 
    if ("${CMAKE_BUILD_TYPE}" IN_LIST Debug_Types)
 
-      if ("@CMAKE_BUILD_TYPE@" IN_LIST Debug_Types)
+      if ("Debug" IN_LIST Debug_Types)
          set(PACKAGE_VERSION_COMPATIBLE true)
       endif()
 
@@ -46,7 +46,7 @@ if (MSVC OR "${CS_CHECK_BUILD_TYPE}")
 
    if ("${CMAKE_BUILD_TYPE}" IN_LIST Release_Types)
 
-      if("@CMAKE_BUILD_TYPE@" IN_LIST Release_Types)
+      if("Release" IN_LIST Release_Types)
          set(PACKAGE_VERSION_COMPATIBLE true)
       endif()
The above patch is applied to allow for CopperSpice to build for multi-config generators as I am writing a VCPKG port for CopperSpice.

The changes at my GitHub are also to help achieve the aforementioned goal as it allows the build of CopperSpice to use whatever ZLIB is made available by VCPKG. VCPKG does perform some monkey-patching of the CMake scripts but all builds proceed as expected. I am currently configuring for static CRT linkage via the triplet-specific VCPKG_CRT_LINKAGE (https://learn.microsoft.com/en-us/vcpkg/users/triplets#vcpkg_crt_linkage) directive, and as far as I can tell this simply overrides CRT linkage to be /MT and /MTd respectively, from what I can tell by overriding the project's own CMakeFile.txt's requests (there's that monkey-patching I mentioned).

I am re-building CopperSpice as I type this under VCPKG (using MSBuild as the generator) to see if RCC is being built with different CRT linkage. I'll be in touch shortly (~45mins) with my results!
gmdianaty
Posts: 7
Joined: Thu Oct 26 2023 4:30 am

Re: MSVCRT Linkage Compatibility Question

Post by gmdianaty »

Tell a lie, I'm already looking at an error! This is being thrown during compile of the debug profile.

Image

Image

Now luckily for me VCPKG discontinues trying to build when it encounters this particular error, so I can take a post-mortem. Taking a look at rcc.exe's own dependencies (using DependenciesGui), I'm not seeing MSVCRT being requested by rcc.exe itself, or any of its dependencies.
barbara
Posts: 475
Joined: Sat Apr 04 2015 2:32 am
Contact:

Re: MSVCRT Linkage Compatibility Question

Post by barbara »

In our opinion you are trying to change too many things at one time. This will make it very difficult if not impossible to test and figure out which parts are not working.

(1) The first step is to build CS from the command line using the ninja generator and ensure everything works before trying to set up MS Build or VCPKG.

(2) After step one is working then it makes sense to try using MS Build and ensure it works as expected. This step is not required to build CS but it may be necessary for your work.

(3) The last step would involve making any changes required for VCPKG. Our team looked at this awhile back and there are some rather surprising issues the MS team mentioned to us. Happy to share details if you are interested.

* * *
So let's work on step one. Start by using our exact CMake build files with no changes. You can build from a command line or from the IDE.

The following is an example showing how to build from the command line and pass a compiler argument. As of CMake 3.15 a new variable was added to set the runtime library on a project wide basis. We tested this and it appears to work.

Release Build

Code: Select all

cmake -GNinja  ^          
      -DCMAKE_BUILD_TYPE=Release ^
      -DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreaded"  ^    
      -DCMAKE_INSTALL_PREFIX=c:\cs_lib  ^
      c:\cs_src  
      
ninja 
Barbara
gmdianaty
Posts: 7
Joined: Thu Oct 26 2023 4:30 am

Re: MSVCRT Linkage Compatibility Question

Post by gmdianaty »

Hello Barbara (and all other folks). Apologies for my radio silence, other commitments kept me busy for a while. Thank you for providing the build scenario, and your willingness to help!

I have confirmed that (as of your latest release at the time of writing) the compile parameters you provided worked successfully under CMake 3.29.0-rc4, Ninja 1.11.1 and MSVC CL 19.39.33522. The only difference I had from your provided build scenario was the usage of sccache.

For good measure, I have also tried to compile the latest release of CopperSpice under vcpkg (with Ninja) as both a MultiThreaded and MultiThreadedDLL program. Both unfortunately failed, but this time the CRT did not provide an popup of any kind.

I am currently planning on trying a second build of CopperSpice with my patch applied so that I may determine if my CMake patch is the culprit. I'll report back if I can determine the results. Please let me know what you're thinking my next troubleshooting step would be.

Graham
gmdianaty
Posts: 7
Joined: Thu Oct 26 2023 4:30 am

Re: MSVCRT Linkage Compatibility Question

Post by gmdianaty »

Hello! Status update. It appears that my CMake changes work as expected when compiled with your provided build scenario. Which leaves me with the question, what makes vcpkg different?

I'll do some looking around while I await your response.

Graham
gmdianaty
Posts: 7
Joined: Thu Oct 26 2023 4:30 am

Re: MSVCRT Linkage Compatibility Question

Post by gmdianaty »

Hello once again!

I have confirmed that building CopperSpice under vcpkg + Ninja + my patches with MultiThreadedDLL works flawlessly. However, changing to a static CRT linkage causes the assert to rear it's ugly head once again:

Code: Select all

Debug Assertion Failed!

Program: ...ildtrees\copperspice\x64-windows-static-dbg\bin\CsCore1.9.dll
File: minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp
Line: 996

Expression: __acrt_first_block == header

For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.
Except this time it causes an indefinite hang in Ninja. This is probably because, interestingly, there is no assertion failure popup on my system from the CRT (but I hear the Windows popup sound cue). I was only able to extrapolate the above error by launching rcc.exe under WinDbg (no parameters). Very weird!

Thank you for your attention - let me know what ya'll think.

Graham
ansel
Posts: 155
Joined: Fri Apr 10 2015 8:23 am

Re: MSVCRT Linkage Compatibility Question

Post by ansel »

We asked our MSVC team member to take a look at your issue. He did some research and determined that building with a statically linked MSVCRT is not a supported configuration. For reference, very few C++ projects would support this setup.

Static CRT linkage creates a separate heap for every module. This violates the C++ standard and causes issues when memory is allocated in one module and then deallocated in another.

Let us know your use case so we can think about an alternate solution.
Ansel Sermersheim
CopperSpice Cofounder
gmdianaty
Posts: 7
Joined: Thu Oct 26 2023 4:30 am

Re: MSVCRT Linkage Compatibility Question

Post by gmdianaty »

Fair enough. We're now using dynamic linkage in our project, and I have edited my vcpkg port accordingly. It's working well.

Thank you all for your help!
Post Reply