Visual Studio 2019 generator check_symbol_exists sometimes fails

I’m trying to include libssh into my project via add_subdirectory(…) with cmake 3.24.2 using the Visual Studio 2019 generator. And all the calls to check_symbol_exists fail.

My configure cmd is:

cmake -G "Visual Studio 16 2019" -A x64 ..

When I look at why it’s failing, my CMakeFiles\CMakeError.log file contains this sort of thing:

Determining if the vsnprintf exist failed with the following output:
Change Dir: C:/Code/FileTeePee/build/CMakeFiles/CMakeTmp

Run Build Command(s):C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/MSBuild/Current/Bin/MSBuild.exe cmTC_30e9e.vcxproj /p:Configuration=Debug /p:Platform=x64 /p:VisualStudioVersion=16.0 /v:m && Microsoft (R) Build Engine version 16.11.2+f32259642 for .NET Framework

Copyright (C) Microsoft Corporation. All rights reserved.



MSBUILD : error MSB1009: Project file does not exist.

Switch: cmTC_30e9e.vcxproj



File C:/Code/FileTeePee/build/CMakeFiles/CMakeTmp/CheckSymbolExists.c:
/* */
#include <stdio.h>

int main(int argc, char** argv)
{
  (void)argv;
#ifndef vsnprintf
  return ((int*)(&vsnprintf))[argc];
#else
  (void)argc;
  return 0;
#endif
}

I think this is a cmake bug. As I’m not doing anything weird here… this should be working.

It seems that CHECK_INCLUDE_FILE in share\cmake-3.24\Modules\CheckIncludeFile.cmake is trying to compile a test file but MSBuild.exe is expecting a vcxproj file. That doesn’t exist. Who creates that? try_compile? I can’t find the try_compile source right now… maybe it’s in the C++ part of cmake.

Although it seems highly arbitrary which calls to check_include_file succeed and which fail. In one example this following code:

set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
check_include_file(openssl/des.h HAVE_OPENSSL_DES_H)
if (NOT HAVE_OPENSSL_DES_H)
    message(FATAL_ERROR "Could not detect openssl/des.h")
endif()

set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
check_include_file(openssl/aes.h HAVE_OPENSSL_AES_H)
if (NOT HAVE_OPENSSL_AES_H)
    message(FATAL_ERROR "Could not detect openssl/aes.h")
endif()

Fails on HAVE_OPENSSL_AES_H == False but HAVE_OPENSSL_DES_H is ok. But the headers are in the same folder? OPENSSL_INCLUDE_DIR is the same value for each call… it makes no sense for one to succeed and the other the fail.