21

I'm using several libraries built through vcpkg (such as civet-web and prometheus-cpp), against my Visual C++ projects. When building x86 all is perfect, in x64 I get a bunch of linker errors:

error LNK2001: unresolved external symbol __CxxFrameHandler4

Searching online all references to this symbol/error are about specific projects, I cannot find what __CxxFrameHandler4 is and what problem this error is highlighting. I don't know if it's a problem with the way vcpkg is building the library, or a problem in my project or how to start looking for a solution.

I did find this blog article but it is in reference to a preview of VS2019, I cannot find any settings related to it: https://devblogs.microsoft.com/cppblog/making-cpp-exception-handling-smaller-x64/

If anyone can explain what this is all about it would be a big help.

Mr. Boy
  • 60,845
  • 93
  • 320
  • 589
  • 7
    `__CxxFrameHandler4` is part of the newer (since VS 2019 [16.3](https://devblogs.microsoft.com/cppblog/msvc-backend-updates-in-visual-studio-2019-versions-16-3-and-16-4/)) 64-bit [FH4](https://devblogs.microsoft.com/cppblog/making-cpp-exception-handling-smaller-x64/) exception handling. I guess `LNK2001` could happen if you linked modules built with mismatched versions of the compiler/toolsets. – dxiv Jan 11 '21 at 23:30

3 Answers3

13

I faced the same issues when trying to install and use cpr with vcpkg. I wanted to use cpr library in a VS2015 project.

Reason: I had VS2019 installed. vcpkg uses latest version of toolset Visual Studio.
Resolution: Add your own triplet or change existing such a way that your specified toolset is used. Adding did not work in my case so I changed existing "triplet" files in triplet folder in vcpkg. I wanted vcpkg to use toolset that comes with VS2015 (It's V140)

Content of x86-windows.cmake file

set(VCPKG_TARGET_ARCHITECTURE x86)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE dynamic)
set(VCPKG_PLATFORM_TOOLSET "v140")
set(VCPKG_DEP_INFO_OVERRIDE_VARS "v140")

Content of x64-windows.cmake file

set(VCPKG_TARGET_ARCHITECTURE x64)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE dynamic)
set(VCPKG_PLATFORM_TOOLSET "v140")
set(VCPKG_DEP_INFO_OVERRIDE_VARS "v140")
Dharman
  • 30,962
  • 25
  • 85
  • 135
Rupesh Bhurke
  • 162
  • 1
  • 8
  • 1
    I had actually eventually figured this out to exactly this since posting, I had to force vcpkg not to use the latest vs2019 toolset. You might demonstrate example triplet changes for anyone else seeing this – Mr. Boy Feb 04 '21 at 15:33
  • @Mr.Boy, The last two lines are added. First 3 lines were already there in both cases. – Rupesh Bhurke Feb 11 '21 at 14:19
  • Pardon my ignorance but is there a way to do this through the project settings? I am not calling cmake directly but Visual Studio is when I build a project or solution. I don't see any '.cmake' file that I can edit for my project. – David Bowser May 04 '22 at 17:45
3

I think you pointed out the right article which is https://devblogs.microsoft.com/cppblog/making-cpp-exception-handling-smaller-x64/

I faced a similar issue in linking 64-bit library built with VC143 toolset with a 64-bit Application built with VC141 toolset.

After adding the following properties to VC143 built static library project, I was able to build the application. This disables the new feature mentioned in the above article (Exception Handling Smaller)

VS2019->Properties->C/C++->Command Line add '-d2FH4-'
VS2019->Properties->Linker->Command Line add '-d2:-FH4-' 
Sowrab B M
  • 69
  • 5
2

A more general answer is that this happens if you are mixing objects that were built with different platform toolsets, e.g.,

  • Visual C++ 2015 (v140)
  • Visual C++ 2017 (v141)

Typically, you (or someone else) may have built a dependency of your project with a different compiler version (platform toolset), and the fix it to change the platform toolset of either your project or the dependency (or use the correct build of the dependency, if you used a pre-built package)

Florian Winter
  • 4,750
  • 1
  • 44
  • 69