microsoft / vcpkg

C++ Library Manager for Windows, Linux, and MacOS
MIT License
22.95k stars 6.34k forks source link

vcpkg integration induces Infinite CMake recursion when compiling #16454

Open terrylyons opened 3 years ago

terrylyons commented 3 years ago

I have a very simple cross-platform cmake C++ project and I am editing it in visual studio 2019. Creating the CMake cache works perfectly if I remove the vcpkg integration; but fails with a loop of 1000 times if I include the vcpkg integration. I downloaded the current version of vcpkg from GitHub to check that the issue had not been fixed.

I include zipped up the CMake code tree and the very simple code.

There is one CMake included external package simdjson which builds successfully.

quicktrack_tree.zip

googling vcpkg Infinite CMake recursion when compiling yields many other cases of this problem

with vcpkg integrate remove:

1> CMake generation started for configuration: 'x64-Release'.
1> Command line: "cmd.exe" /c "%SYSTEMROOT%\System32\chcp.com 65001 >NUL && "C:\PROGRAM FILES (X86)\MICROSOFT VISUAL STUDIO\2019\ENTERPRISE\COMMON7\IDE\COMMONEXTENSIONS\MICROSOFT\CMAKE\CMake\bin\cmake.exe"  -G "Visual Studio 16 2019" -A x64  -DCMAKE_CONFIGURATION_TYPES:STRING="RelWithDebInfo" -DCMAKE_INSTALL_PREFIX:PATH="C:/Users/tlyons/lyonstech/x64-Release"  "C:\Users\tlyons\source\repos\terrylyons\quicktrack" 2>&1"
1> Working directory: C:\Users\tlyons\source\repos\terrylyons\quicktrack\out\build\x64-Release
1> [CMake] -- Selecting Windows SDK version 10.0.18362.0 to target Windows 10.0.19041.
1> [CMake] -- The CXX compiler identification is MSVC 19.28.29337.0
1> [CMake] -- The C compiler identification is MSVC 19.28.29337.0
1> [CMake] -- Detecting CXX compiler ABI info
1> [CMake] -- Detecting CXX compiler ABI info - done
1> [CMake] -- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Tools/MSVC/14.28.29333/bin/Hostx64/x64/cl.exe - skipped
1> [CMake] -- Detecting CXX compile features
1> [CMake] -- Detecting CXX compile features - done
1> [CMake] -- Detecting C compiler ABI info
1> [CMake] -- Detecting C compiler ABI info - done
1> [CMake] -- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Tools/MSVC/14.28.29333/bin/Hostx64/x64/cl.exe - skipped
1> [CMake] -- Detecting C compile features
1> [CMake] -- Detecting C compile features - done
1> [CMake] -- The simdjson repository appears to be used as a subdirectory.
1> [CMake] -- By default, we just build the library.
1> [CMake] -- The simdjson repository appears to be under git.
1> [CMake] -- No build type selected, default to Release
1> [CMake] -- Using SIMDJSON_GOOGLE_BENCHMARKS
1> [CMake] -- Looking for pthread.h
1> [CMake] -- Looking for pthread.h - not found
1> [CMake] -- Found Threads: TRUE  
1> [CMake] -- Building just the library, omitting all tests, tools and benchmarks.
1> [CMake] -- Building a static library.
1> [CMake] grep and nm are unavailable on this system.
1> [CMake] -- Selecting Windows SDK version 10.0.18362.0 to target Windows 10.0.19041.
1> [CMake] -- Selecting Windows SDK version 10.0.18362.0 to target Windows 10.0.19041.
1> [CMake] -- Configuring done
1> [CMake] -- Generating done
1> [CMake] -- Build files have been written to: C:/Users/tlyons/source/repos/terrylyons/quicktrack/out/build/x64-Release
1> Extracted CMake variables.
1> Extracted source files and headers.
1> Extracted code model.
1> Extracted includes paths.
1> CMake generation finished.

with vcpkg integrate install:

1> CMake generation started for configuration: 'x64-Release'.
1> Found and using vcpkg toolchain file (C:/Users/tlyons/source/vcpkg/scripts/buildsystems/vcpkg.cmake).
1> Command line: "cmd.exe" /c "%SYSTEMROOT%\System32\chcp.com 65001 >NUL && "C:\PROGRAM FILES (X86)\MICROSOFT VISUAL STUDIO\2019\ENTERPRISE\COMMON7\IDE\COMMONEXTENSIONS\MICROSOFT\CMAKE\CMake\bin\cmake.exe"  -G "Visual Studio 16 2019" -A x64  -DCMAKE_CONFIGURATION_TYPES:STRING="RelWithDebInfo" -DCMAKE_INSTALL_PREFIX:PATH="C:/Users/tlyons/lyonstech/x64-Release"  -DCMAKE_TOOLCHAIN_FILE="C:/Users/tlyons/source/vcpkg/scripts/buildsystems/vcpkg.cmake" "C:\Users\tlyons\source\repos\terrylyons\quicktrack" 2>&1"
1> Working directory: C:\Users\tlyons\source\repos\terrylyons\quicktrack\out\build\x64-Release
1> [CMake] -- Selecting Windows SDK version 10.0.18362.0 to target Windows 10.0.19041.
1> [CMake] -- The CXX compiler identification is MSVC 19.28.29337.0
1> [CMake] -- The C compiler identification is MSVC 19.28.29337.0
1> [CMake] -- Detecting CXX compiler ABI info
1> [CMake] -- Detecting CXX compiler ABI info - done
1> [CMake] -- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Tools/MSVC/14.28.29333/bin/Hostx64/x64/cl.exe - skipped
1> [CMake] -- Detecting CXX compile features
1> [CMake] -- Detecting CXX compile features - done
1> [CMake] -- Detecting C compiler ABI info
1> [CMake] -- Detecting C compiler ABI info - done
1> [CMake] -- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Tools/MSVC/14.28.29333/bin/Hostx64/x64/cl.exe - skipped
1> [CMake] -- Detecting C compile features
1> [CMake] -- Detecting C compile features - done
1> [CMake] -- The simdjson repository appears to be used as a subdirectory.
1> [CMake] -- By default, we just build the library.
1> [CMake] -- The simdjson repository appears to be under git.
1> [CMake] -- No build type selected, default to Release
1> [CMake] -- Using SIMDJSON_GOOGLE_BENCHMARKS
1> [CMake] -- Looking for pthread.h
1> [CMake] -- Looking for pthread.h - not found
1> [CMake] -- Found Threads: TRUE  
1> [CMake] -- Building just the library, omitting all tests, tools and benchmarks.
1> [CMake] -- Building a static library.
1> [CMake] grep and nm are unavailable on this system.
1> [CMake] -- Selecting Windows SDK version 10.0.18362.0 to target Windows 10.0.19041.
1> [CMake] CMake Error at C:/Users/tlyons/source/vcpkg/scripts/buildsystems/vcpkg.cmake:166 (_add_executable):
1> [CMake]   Maximum recursion depth of 1000 exceeded
1> [CMake] Call Stack (most recent call first):
1> [CMake]   C:/Users/tlyons/source/vcpkg/scripts/buildsystems/vcpkg.cmake:166 (_add_executable)
1> [CMake]   C:/Users/tlyons/source/vcpkg/scripts/buildsystems/vcpkg.cmake:166 (_add_executable)
1> [CMake]   C:/Users/tlyons/source/vcpkg/scripts/buildsystems/vcpkg.cmake:166 (_add_executable)
1> [CMake]   C:/Users/tlyons/source/vcpkg/scripts/buildsystems/vcpkg.cmake:166 (_add_executable)
1> [CMake]   C:/Users/tlyons/source/vcpkg/scripts/buildsystems/vcpkg.cmake:166 (_add_executable)
..........................................................................................................................................................
1> [CMake]   C:/Users/tlyons/source/vcpkg/scripts/buildsystems/vcpkg.cmake:166 (_add_executable)
1> [CMake]   C:/Users/tlyons/source/vcpkg/scripts/buildsystems/vcpkg.cmake:166 (_add_executable)
1> [CMake]   quicktrack/CMakeLists.txt:9 (add_executable)
1> 'cmd.exe' '/c "%SYSTEMROOT%\System32\chcp.com 65001 >NUL && "C:\PROGRAM FILES (X86)\MICROSOFT VISUAL STUDIO\2019\ENTERPRISE\COMMON7\IDE\COMMONEXTENSIONS\MICROSOFT\CMAKE\CMake\bin\cmake.exe"  -G "Visual Studio 16 2019" -A x64  -DCMAKE_CONFIGURATION_TYPES:STRING="RelWithDebInfo" -DCMAKE_INSTALL_PREFIX:PATH="C:/Users/tlyons/lyonstech/x64-Release"  -DCMAKE_TOOLCHAIN_FILE="C:/Users/tlyons/source/vcpkg/scripts/buildsystems/vcpkg.cmake" "C:\Users\tlyons\source\repos\terrylyons\quicktrack" 2>&1"' execution failed with error: ''cmd.exe' '/c "%SYSTEMROOT%\System32\chcp.com 65001 >NUL && "C:\PROGRAM FILES (X86)\MICROSOFT VISUAL STUDIO\2019\ENTERPRISE\COMMON7\IDE\COMMONEXTENSIONS\MICROSOFT\CMAKE\CMake\bin\cmake.exe"  -G "Visual Studio 16 2019" -A x64  -DCMAKE_CONFIGURATION_TYPES:STRING="RelWithDebInfo" -DCMAKE_INSTALL_PREFIX:PATH="C:/Users/tlyons/lyonstech/x64-Release"  -DCMAKE_TOOLCHAIN_FILE="C:/Users/tlyons/source/vcpkg/scripts/buildsystems/vcpkg.cmake" "C:\Users\tlyons\source\repos\terrylyons\quicktrack" 2>&1"' returned with exit code: -1073741819'.
JackBoosY commented 3 years ago
1> CMake Error at extern/CMakeLists.txt:16 (FetchContent_MakeAvailable):
1>   Unknown CMake command "FetchContent_MakeAvailable".

I comment out add_subdirectory(extern) and re-configured, no error occurred.

Please make sure your vcpkg is latest.

terrylyons commented 3 years ago

With version 18 of cmake there is no error in the cmake. I have built the binaries in windows and Linux successfully several times. Sadly It builds without vcpckg integration disabled and loops with it.

Terry

On 1 Mar 2021, at 06:52, Jack·Boos·Yu notifications@github.com wrote:



1> CMake Error at extern/CMakeLists.txt:16 (FetchContent_MakeAvailable): 1> Unknown CMake command "FetchContent_MakeAvailable".

I comment out add_subdirectory(extern) and re-configured, no error occurred.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHubhttps://github.com/microsoft/vcpkg/issues/16454#issuecomment-787698845, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ABQWN6ZGNIT5JN53VHV5OBLTBM2QRANCNFSM4YKOFO6A.

JackBoosY commented 3 years ago

Confirmed with Visual Studio 2019.

sir-maniac commented 2 years ago

@JackBoosY @ras0219-msft

This seems to be related to this message on the CMake mailing list.

I was able to make the wrapping of add_library and add_executable happen only once by surrounding each with an if block, and setting a global property.

if(NOT ${Z_VCPKG_ADD_EXECUTABLE_WRAPPED_ONCE})
    function(add_executable)
        ...
    endfunction()
    set_property(GLOBAL PROPERTY Z_VCPKG_ADD_EXECUTABLE_WRAPPED_ONCE ON)
endif()

if(NOT ${Z_VCPKG_ADD_LIBRARY_WRAPPED_ONCE})
    function(add_library)
        ...
    endfunction()
    set_property(GLOBAL PROPERTY Z_VCPKG_ADD_LIBRARY_WRAPPED_ONCE ON)
endif()

I'm still pretty green with CMake, but that worked for me.

EDIT:
I did a little more trial-and-error, and found this one-liner at the top the file is a workable workaround(for CMake version >= 3.10):

include_guard(GLOBAL)
dg0yt commented 2 years ago

The example uses a subproject. Basically this is valid CMake. Normal variables set in the subdir/subproject won't be visible to the parent scope.

What is unusual in the example project is that add_subdirectory is called before the top-level project command. A lot of things happen when CMake encounters the project command. For example, CMake calls the toolchain file.

Taking this together, order matters: In the example, many variables aren't yet initialized when hitting project in the subdir. And changes to these variables in subdir won't be visible to the parent scope. That's why in your example, the top-level project command triggers a second execution of the toolchain file, including the second redefinition of add_executable. Which isn't supported by CMake.

So first I would advice to avoid add_subdirectory before project. There is no advantage from that, but there is the risk of redundant expensive project steps.

Second, vcpkg needs to generally guard against redefining add_executable or add_library. There are multiple triggers:

JonTheBurger commented 2 years ago

Is there a possibility to add a VCPKG_OVERRIDE_ADD_LIBRARY_NAME in the same vein as VCPKG_OVERRIDE_FIND_PACKAGE_NAME? I have a project that wraps add_library to record packages used to generate find_dependency calls in the generated <Package>Config.cmake file, but this ends up not being usable when vcpkg also wraps add_library. Apologies if this is the wrong place to ask about this!