We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 3080

Summary: SDL fails to link when CMake is used with VS2015
Product: SDL Reporter: Alex Szpakowski <amaranth72>
Component: buildAssignee: Ryan C. Gordon <icculus>
Status: RESOLVED FIXED QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2 CC: gygax
Version: HG 2.0   
Hardware: x86_64   
OS: Windows (All)   
Attachments: Conditionally add libraries needed by Visual Studio 2015

Description Alex Szpakowski 2015-07-30 00:00:58 UTC
When I use CMake to build the latest SDL 2.0.4 code with VS2015's compiler, SDL fails to link. The CMake project worked (I believe) when VS2013 was used, and the Visual Studio project file bundled with SDL's source builds SDL fine when used with VS2015.

These are the link errors:

1>MSVCRTD.lib(_init_.obj) : error LNK2019: unresolved external symbol __CrtDbgReport referenced in function __CRT_RTC_INIT
1>MSVCRTD.lib(_init_.obj) : error LNK2019: unresolved external symbol __CrtDbgReportW referenced in function __CRT_RTC_INITW
1>MSVCRTD.lib(_ftol3_.obj) : error LNK2019: unresolved external symbol __except1 referenced in function __ftol3_except
1>MSVCRTD.lib(_error_.obj) : error LNK2019: unresolved external symbol ___stdio_common_vsprintf_s referenced in function __vsprintf_s_l
1>MSVCRTD.lib(_pdblkup_.obj) : error LNK2019: unresolved external symbol __wmakepath_s referenced in function "int __cdecl GetPdbDllPathFromFilePath(wchar_t const *,wchar_t *,unsigned int)" (?GetPdbDllPathFromFilePath@@YAHPB_WPA_WI@Z)
1>MSVCRTD.lib(_pdblkup_.obj) : error LNK2019: unresolved external symbol __wsplitpath_s referenced in function "int __cdecl GetPdbDllPathFromFilePath(wchar_t const *,wchar_t *,unsigned int)" (?GetPdbDllPathFromFilePath@@YAHPB_WPA_WI@Z)
1>MSVCRTD.lib(_pdblkup_.obj) : error LNK2019: unresolved external symbol _wcscpy_s referenced in function "int __cdecl GetPdbDllPathFromFilePath(wchar_t const *,wchar_t *,unsigned int)" (?GetPdbDllPathFromFilePath@@YAHPB_WPA_WI@Z)
1>MSVCRTD.lib(_pdblkup_.obj) : error LNK2019: unresolved external symbol ___vcrt_GetModuleFileNameW referenced in function "struct HINSTANCE__ * __cdecl GetPdbDll(void)" (?GetPdbDll@@YAPAUHINSTANCE__@@XZ)
1>MSVCRTD.lib(_pdblkup_.obj) : error LNK2019: unresolved external symbol ___vcrt_GetModuleHandleW referenced in function "struct HINSTANCE__ * __cdecl GetPdbDll(void)" (?GetPdbDll@@YAPAUHINSTANCE__@@XZ)
1>MSVCRTD.lib(_pdblkup_.obj) : error LNK2019: unresolved external symbol ___vcrt_LoadLibraryExW referenced in function "struct HINSTANCE__ * __cdecl GetPdbDll(void)" (?GetPdbDll@@YAPAUHINSTANCE__@@XZ)
1>MSVCRTD.lib(_chandler4gs_.obj) : error LNK2019: unresolved external symbol __except_handler4_common referenced in function __except_handler4
Comment 1 Jean-Pierre Gygax 2015-12-18 21:54:15 UTC
Created attachment 2340 [details]
Conditionally add libraries needed by Visual Studio 2015

Also removed dxerr.lib and dxerr8.lib.
Comment 2 Alex Szpakowski 2015-12-19 00:03:43 UTC
SDL is supposed to avoid dependencies on the Visual C runtime libraries, I believe.

I have some local changes to the CMakeLists.txt file which fix the issues for me, but I'll probably need to clean them up (and make sure they don't do anything unintentional) before committing them. The changes are:

if(MSVC)
  # Don't try to link with the default set of libraries.
  set_target_properties(SDL2 PROPERTIES LINK_FLAGS_RELEASE "/NODEFAULTLIB")
  set_target_properties(SDL2 PROPERTIES LINK_FLAGS_DEBUG "/NODEFAULTLIB")
  set_target_properties(SDL2 PROPERTIES STATIC_LIBRARY_FLAGS "/NODEFAULTLIB")

  # Prevent codegen that would use the VC runtime libraries.
  add_definitions(/arch:SSE /GS-)

  # Make sure /RTC1 is disabled, otherwise it will use functions from the CRT
  foreach(flag_var
      CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
      CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO)
    string(REGEX REPLACE "/RTC(su|[1su])" "" ${flag_var} "${${flag_var}}")
  endforeach(flag_var)
endif()

(although they aren't all grouped together in my local copy of the file.)
Comment 3 Jean-Pierre Gygax 2015-12-19 14:12:37 UTC
Thanks Alex,

the DLL builds perfectly with your changes. (I was completely unaware of buffer overrun detection and its implications.)

So, two things to do:

1) add in your settings

2) remove references to dxerr.lib and dxerr8.lib 

How can we make sure these changes make it into the official source ?
Comment 4 Alex Szpakowski 2015-12-23 18:50:30 UTC
Is dxerr not used at all in recent SDL versions?

Once I'm completely satisfied with my changes I'll commit them to SDL's repository.
Comment 5 Jean-Pierre Gygax 2015-12-23 20:50:58 UTC
It builds without dxerr.lib or dxerr8.lib.

Also, about a year ago I searched the code for calls to dxerr functions, and found a few, which were however all commented out.
Comment 6 Alex Szpakowski 2015-12-31 19:28:22 UTC
I pushed my fixes: https://hg.libsdl.org/SDL/rev/d3e4f7b44d4d

There was a separate commit which changed the dxerr stuff to only link in more limited circumstances: https://hg.libsdl.org/SDL/rev/e3d651c5fe31