microsoft / vcpkg

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

Build boost-numpy with boost-python #5732

Open palotasb-conti opened 5 years ago

palotasb-conti commented 5 years ago

Hi, I'm using boost-python with the builtin numpy support enabled. Boost build decides whether to build the boost-numpy library as part of the boost-python library based on whether executing python -c "import sys; sys.stderr = sys.stdout; import numpy; print(numpy.get_include())" succeeds or not. See https://github.com/boostorg/build/blob/e22a75c8fd83f0e52adea4f48ef5f9fbbdf5b72c/src/tools/python.jam#L838-L857

Is there a way using Vcpkg to (1) rely on the Python installed by Vcpkg and (2) force boost to build the boost-numpy library as well?

I have tried the following script:

REM file: build.bat

REM pybind11 only used to install Python.exe in vcpkg\downloads\tools\python\python3\python.exe
.\vcpkg\vcpkg.exe install pybind11

REM install pip3.exe. See: https://pip.pypa.io/en/stable/installing/
.\vcpkg\downloads\tools\python\python3\python.exe "../path/to/get-pip.py"

REM install numpy
.\vcpkg\downloads\tools\python\python3\Scripts\pip3.exe install numpy==1.16.2

REM verify that if boost build used the Vcpkg Python installation it would see numpy
.\vcpkg\downloads\tools\python\python3\python.exe -c "import sys; sys.stderr = sys.stdout; import numpy; print(numpy.get_include())"
REM prints correct path to .\vcpkg\downloads\tools\python\python3\lib\site-packages\numpy\core\include

set PATH=\full\path\to\vcpkg\downloads\tools\python\python3;%PATH%

REM try to build boost python
.\vcpkg\vcpkg.exe install boost-python

The expected result is that boost-ptython gets built with boostnumpy.

Instead, it is not built and the log say this:

notice: [python-cfg] Configuring python...
notice: [python-cfg]   user-specified version: "3.6"
notice: [python-cfg]   user-specified includes: "/path/to/vcpkg/installed/x64-windows/include/python3.6"
notice: [python-cfg]   user-specified libraries: "/path/to/vcpkg/installed/x64-windows/lib"
notice: [python-cfg] Registry indicates Python 3.6 installed at "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\"
notice: [python-cfg] Checking interpreter command "python"...
notice: [python-cfg] running command 'python -c "from sys import *; print('version=%d.%d\nplatform=%s\nprefix=%s\nexec_prefix=%s\nexecutable=%s' % (version_info[0],version_info[1],platform,prefix,exec_prefix,executable))" 2>&1'
notice: [python-cfg] ...does not invoke a working interpreter
notice: [python-cfg] Checking interpreter command "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\python"...
notice: [python-cfg] running command 'DIR /-C /A:S "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\python.exe" 2>&1'
notice: [python-cfg] running command 'C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\python -c "from sys import *; print('version=%d.%d\nplatform=%s\nprefix=%s\nexec_prefix=%s\nexecutable=%s' % (version_info[0],version_info[1],platform,prefix,exec_prefix,executable))" 2>&1'
notice: [python-cfg] ...does not invoke a working interpreter
notice: [python-cfg] No working Python interpreter found.
notice: [python-cfg] falling back to "python"
notice: [python-cfg] Details of this Python configuration:
notice: [python-cfg]   interpreter command: "python"
notice: [python-cfg]   include path: "/path/to/vcpkg/installed/x64-windows/include/python3.6"
notice: [python-cfg]   library path: "/path/to/vcpkg/installed/x64-windows/lib"
notice: [python-cfg]   DLL search path: "<empty>"
notice: [python-cfg] Checking for NumPy...
notice: [python-cfg] running command 'python -c "import sys; sys.stderr = sys.stdout; import numpy; print(numpy.get_include())"'
notice: [python-cfg] NumPy disabled. Reason:
notice: [python-cfg]   python -c "import sys; sys.stderr = sys.stdout; import numpy; print(numpy.get_include())" aborted with 
notice: [python-cfg]   
notice: [python-cfg] Configuring python...
notice: [python-cfg]   user-specified version: "3.6"
notice: [python-cfg]   user-specified includes: "/path/to/vcpkg/installed/x64-windows/include/python3.6"
notice: [python-cfg]   user-specified libraries: "/path/to/vcpkg/installed/x64-windows/debug/lib"
notice: [python-cfg]   user-specified condition: "<python-debugging>on"
notice: [python-cfg] Registry indicates Python 3.6 installed at "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\"
notice: [python-cfg] Checking interpreter command "python"...
notice: [python-cfg] running command 'python -c "from sys import *; print('version=%d.%d\nplatform=%s\nprefix=%s\nexec_prefix=%s\nexecutable=%s' % (version_info[0],version_info[1],platform,prefix,exec_prefix,executable))" 2>&1'
notice: [python-cfg] ...does not invoke a working interpreter
notice: [python-cfg] Checking interpreter command "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\python"...
notice: [python-cfg] running command 'DIR /-C /A:S "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\python.exe" 2>&1'
notice: [python-cfg] running command 'C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\python -c "from sys import *; print('version=%d.%d\nplatform=%s\nprefix=%s\nexec_prefix=%s\nexecutable=%s' % (version_info[0],version_info[1],platform,prefix,exec_prefix,executable))" 2>&1'
notice: [python-cfg] ...does not invoke a working interpreter
notice: [python-cfg] No working Python interpreter found.
notice: [python-cfg] falling back to "python"
notice: [python-cfg] Details of this Python configuration:
notice: [python-cfg]   interpreter command: "python"
notice: [python-cfg]   include path: "/path/to/vcpkg/installed/x64-windows/include/python3.6"
notice: [python-cfg]   library path: "/path/to/vcpkg/installed/x64-windows/debug/lib"
notice: [python-cfg]   DLL search path: "<empty>"
notice: [python-cfg] Checking for NumPy...
notice: [python-cfg] running command 'python -c "import sys; sys.stderr = sys.stdout; import numpy; print(numpy.get_include())"'
notice: [python-cfg] NumPy disabled. Reason:
notice: [python-cfg]   python -c "import sys; sys.stderr = sys.stdout; import numpy; print(numpy.get_include())" aborted with 
notice: [python-cfg]   

Any ideas how to solve this, or any willingness to support this use case with Vcpkg?

MVoz commented 5 years ago

I have tried the following script:

well it's written right there --- "../path/to/get-pip.py"

by mistake the same

notice: [python-cfg] Configuring python... notice: [python-cfg] user-specified version: "3.6" notice: [python-cfg] user-specified includes:"/path/to/vcpkg/installed/x64-windows/include/python3.6" notice: [python-cfg] user-specified libraries:"/path/to/vcpkg/installed/x64-windows/lib"

??? /path/to/vcpkg /path/to/vcpkg/installed/x64-windows

palotasb-conti commented 5 years ago

well it's written right there --- "../path/to/get-pip.py"

@Voskrese What I imply here is that I have separately downloaded the get-pip.py script and I'm invoking it. This part works; it builds the vcpkg\downloads\tools\python\python3\Scripts\pip3.exe used in the next command. ../path/to/get-pip.py and /path/to/vcpkg do not necessarily refer to the same path, it is just a placeholder and it is not causing the issue as far as I see.

by mistake the same

notice: [python-cfg] Configuring python... notice: [python-cfg] user-specified version: "3.6"

I do not understand what you are saying in your comment. Can you please explain it in simple words?

The only thing I see here is that the Python.exe under Vcpkg (and used in the script) is version 3.5, not 3.6. That might be the reason boost-build is not picking it up while building boost-python, but I'm not sure (I wasn't able to verify this).

MVoz commented 5 years ago

then the reason is this

python.exe

notice: [python-cfg] Checking interpreter command "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\python"... notice: [python-cfg] running command 'DIR /-C /A:S "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\python.exe" 2>&1'

MVoz commented 5 years ago

try with such variables

full path c:\vcpkg\ set PYTHONHOME="c:\vcpkg\downloads\tools\python\python3"

set PATH="c:\vcpkg\downloads\tools\python\python3";%PATH% set PYTHONPATH="%PYTHONHOME%\Lib\site-packages;%PYTHONHOME%\Lib;%PYTHONHOME%\DLL" set PYTHONSCRIPT="%PYTHONHOME%\Scripts" set PYTHON_EXECUTABLE="%PYTHONHOME%\python.exe" set PYTHON_INCLUDE_DIR="%PYTHONHOME%\include" set PYTHON_LIBRARY="%PYTHONHOME%\libs\python35.lib;%PYTHONHOME%\libs"

"c:\vcpkg\downloads\tools\python\python3\python.exe" -m pip install -U numpy==1.16.2

MVoz commented 5 years ago

cmake default search python

C:\Program Files (x86)\CMake\share\cmake-3.13\Modules\FindPython\Support.cmake

    # Windows registry
    if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST")
      find_program (${_PYTHON_PREFIX}_EXECUTABLE
                    NAMES python${_${_PYTHON_PREFIX}_VERSION}
                          python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}
                          python
                          ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}
                    NAMES_PER_DIR
                    HINTS ${_${_PYTHON_PREFIX}_HINTS}
                    PATHS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
                          [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
                          [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]
                          [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
                          [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]
                          [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
                          [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
                          [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]
                          [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
                          [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]
                          [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
                    PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
                    NO_SYSTEM_ENVIRONMENT_PATH
                    NO_CMAKE_SYSTEM_PATH)
    endif()
Yienschwen commented 5 years ago

I'm not an expert in vcpkg or b2, so some of the technical details may be incorrect.


The situation is:

However, python is actually searched by b2 of boost-build instead of CMake.

The "call stack" of boost-python build is:

cmake: ports/boost-python/portfile.cmake
  cmake: installed/.../shared/boost-build/boost-modular-build.cmake
    b2: ...

And python related paths are formatted into user-config.jam copy of build variant of boost-python in its buildtree, where the original user-config.jam originates from installed/.../shared/boost-build/user-config.jam.

b2 uses the information in the copied user-config.jam to search for python executable in the way detailed in installed/.../tools/boost-build/src/tools/python.jam, that searches for python registry if the cmd-or-prefix field in user-config.jam is empty.

So the brute-force and dirty solution is to fill the cmd-or-prefix field of installed/.../shared/boost-build/user-config.jam, otherwise b2 will never build boost-numpy library.


P.S., IMO, python path should have the option to be given manually by user, since user may have python installed in virtual environments or anything else, and that's user-config.jam designed for.

vlarin commented 4 years ago

Hi! I have the same issue and @Yienschwen solution didn't help, it still unable to find python in the directory for numpy check.

notice: [python-cfg] Configuring python...
notice: [python-cfg]   user-specified version: "3.7"
notice: [python-cfg]   user-specified includes: "C:/vcpkg/installed/x64-windows/include/python3.7"
notice: [python-cfg]   user-specified libraries: "C:/vcpkg/installed/x64-windows/lib"
notice: [python-cfg] Registry indicates Python 3.7 installed at "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\"
notice: [python-cfg] Checking interpreter command "python"...
notice: [python-cfg] running command 'python -c "from sys import *; print('version=%d.%d\nplatform=%s\nprefix=%s\nexec_prefix=%s\nexecutable=%s' % (version_info[0],version_info[1],platform,prefix,exec_prefix,executable))" 2>&1'
notice: [python-cfg] ...does not invoke a working interpreter
notice: [python-cfg] Checking interpreter command "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\python"...
notice: [python-cfg] running command 'DIR /-C /A:S "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\python.exe" 2>&1'
notice: [python-cfg] running command 'C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\python -c "from sys import *; print('version=%d.%d\nplatform=%s\nprefix=%s\nexec_prefix=%s\nexecutable=%s' % (version_info[0],version_info[1],platform,prefix,exec_prefix,executable))" 2>&1'
notice: [python-cfg] ...does not invoke a working interpreter
notice: [python-cfg] No working Python interpreter found.
notice: [python-cfg] falling back to "python"
notice: [python-cfg] Details of this Python configuration:
notice: [python-cfg]   interpreter command: "python"
notice: [python-cfg]   include path: "C:/vcpkg/installed/x64-windows/include/python3.7"
notice: [python-cfg]   library path: "C:/vcpkg/installed/x64-windows/lib"
notice: [python-cfg]   DLL search path: "<empty>"
notice: [python-cfg] Checking for NumPy...
notice: [python-cfg] running command 'python -c "import sys; sys.stderr = sys.stdout; import numpy; print(numpy.get_include())"'
notice: [python-cfg] NumPy disabled. Reason:
notice: [python-cfg]   python -c "import sys; sys.stderr = sys.stdout; import numpy; print(numpy.get_include())" aborted with 
notice: [python-cfg]   
notice: [python-cfg] Configuring python...
notice: [python-cfg]   user-specified version: "3.7"
notice: [python-cfg]   user-specified includes: "C:/vcpkg/installed/x64-windows/include/python3.7"
notice: [python-cfg]   user-specified libraries: "C:/vcpkg/installed/x64-windows/debug/lib"
notice: [python-cfg]   user-specified condition: "<python-debugging>on"
notice: [python-cfg] Registry indicates Python 3.7 installed at "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\"
notice: [python-cfg] Checking interpreter command "python"...
notice: [python-cfg] running command 'python -c "from sys import *; print('version=%d.%d\nplatform=%s\nprefix=%s\nexec_prefix=%s\nexecutable=%s' % (version_info[0],version_info[1],platform,prefix,exec_prefix,executable))" 2>&1'
notice: [python-cfg] ...does not invoke a working interpreter
notice: [python-cfg] Checking interpreter command "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\python"...
notice: [python-cfg] running command 'DIR /-C /A:S "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\python.exe" 2>&1'
notice: [python-cfg] running command 'C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\python -c "from sys import *; print('version=%d.%d\nplatform=%s\nprefix=%s\nexec_prefix=%s\nexecutable=%s' % (version_info[0],version_info[1],platform,prefix,exec_prefix,executable))" 2>&1'
notice: [python-cfg] ...does not invoke a working interpreter
notice: [python-cfg] No working Python interpreter found.
notice: [python-cfg] falling back to "python"
notice: [python-cfg] Details of this Python configuration:
notice: [python-cfg]   interpreter command: "python"
notice: [python-cfg]   include path: "C:/vcpkg/installed/x64-windows/include/python3.7"
notice: [python-cfg]   library path: "C:/vcpkg/installed/x64-windows/debug/lib"
notice: [python-cfg]   DLL search path: "<empty>"
notice: [python-cfg] Checking for NumPy...
notice: [python-cfg] running command 'python -c "import sys; sys.stderr = sys.stdout; import numpy; print(numpy.get_include())"'
notice: [python-cfg] NumPy disabled. Reason:
notice: [python-cfg]   python -c "import sys; sys.stderr = sys.stdout; import numpy; print(numpy.get_include())" aborted with 
notice: [python-cfg]   

In the same time, local boost distribution built well with numpy. Will be grateful for any help, thanks!

vlarin commented 4 years ago

So dirty workaround that worked:

  1. Open C:\vcpkg\installed\x64-windows\tools\boost-build\src\tools\python.jam
  2. At line ~838 change code to the following (just be sure to provide correct location of numpy headers):
    #
    # Discover the presence of NumPy
    #
    debug-message "Checking for NumPy..." ;
    local full-cmd = "import sys; sys.stderr = sys.stdout; import numpy; print(numpy.get_include())" ;
    local full-cmd = $(interpreter-cmd)" -c \"$(full-cmd)\"" ;
    debug-message "running command '$(full-cmd)'" ;
    local result = [ SHELL $(full-cmd) : strip-eol : exit-status ] ;
    #if $(result[2]) = 0
    #{
        .numpy = true ;
        .numpy-include = "C:/Program Files (x86)/Microsoft Visual Studio/Shared/Python37_64/lib/site-packages/numpy/core/include" ; #$(result[1]) ;
        debug-message "NumPy enabled" ;
    #}
    #else
    #{
    #    debug-message "NumPy disabled. Reason:" ;
    #    debug-message "  $(full-cmd) aborted with " ;
    #    debug-message "  $(result[1])" ;
    #}
  3. Remove and then install again boost.python
  4. Fix will be need to done again if you reinstall boost.build
Miaua commented 4 years ago

I'm not having any luck with building libboost_numpy37-vc141-mt-x64-1_72.lib I have installed in Win10 Python 3.7.4 64bit and numpy 1.16.3 vcpkg python3 is version 3.7.3, would it matter?

at line 849 in vcpkg\installed\x64-windows\tools\boost-build\src\tools\python.jam i have .numpy-include = "C:/Program Files/Python37/Lib/site-packages/numpy/core/include" ; #$(result[1]) ;

removed and reinstalled boost-python, and run vcpkg install boost, because boost-python remove needed to remove few more packages than just boost-python.

I need this libs in below but numpy for sure is missing: libboost_numpy37-vc141-mt-x64-1_72.lib libboost_python37-vc141-mt-x64-1_72.lib libboost_zlib-vc141-mt-x64-1_72.lib libboost_bzip2-vc141-mt-x64-1_72.lib libboost_regex-vc141-mt-x64-1_72.lib libboost_chrono-vc141-mt-x64-1_72.lib libboost_locale-vc141-mt-x64-1_72.lib libboost_system-vc141-mt-x64-1_72.lib libboost_thread-vc141-mt-x64-1_72.lib libboost_date_time-vc141-mt-x64-1_72.lib libboost_iostreams-vc141-mt-x64-1_72.lib libboost_filesystem-vc141-mt-x64-1_72.lib libboost_serialization-vc141-mt-x64-1_72.lib libboost_wserialization-vc141-mt-x64-1_72.lib libboost_program_options-vc141-mt-x64-1_72.lib

Miaua commented 4 years ago

I got it working on Boost 1_73 with fresh git clone. I have all the libs that i need.

asbe commented 3 years ago

I have Python 3.8 on the system and vcpkg insists on installing 3.9. I need to build boost-python with numpy for 3.8 - but this fails. I tried to resolve it by changing user-config.jam (in vcpkg\buildtrees\boost-python\x64-windows-rel\user-config.jam) but this is overwritten with 3.9. Is this the incorrect way of hinting which Python to use?

tmamakov commented 3 years ago

Hello. The problem looks much more complicated. @vlarin provided a good local solution, but it is impossible to commit such changes. Building numpy requires python, but which one? vcpkg directory has at least two copies of python, third one was installed by standart installation in the most cases.

  1. Is it possible to install python by vcpkg into the system and use it everywhere?
  2. Could we use pip for vcpkg-python and install numpy before boost-python builder call?
  3. Could you publish some recomendations or instructions of using b2 for vcpkg-boost?
Grantim commented 3 years ago

There is other workaround to try.
https://github.com/microsoft/vcpkg/issues/5732#issuecomment-554746190 Same file vcpkg\installed\x64-windows\tools\boost-build\src\tools\python.jam Lines 765 - 770

        while $(cmds-to-try)
        {
            # Pop top command.
            local cmd = \"$(cmds-to-try[1])\" ;
            cmds-to-try = $(cmds-to-try[2-]) ;

It has issue with spaces in python.exe path.

Also note that this file will be removed if you call: vcpkg remove boost-uninstall --recurse and added again on boost installation

crinai commented 11 months ago

Edit this file:"pathto\vcpkg\installed\x64-windows\tools\boost-build\src\tools\python.jam", about line 835~836 before " debug-message "Details of this Python configuration:" ; debug-message " interpreter command:" \"$(interpreter-cmd:E=)\" ; debug-message " include path:" \"$(includes:E=)\" ; debug-message " library path:" \"$(libraries:E=)\" ;", add this two line to use your settings of python installed includes = [ path-to-native "D:/vcpkg/installed/x64-windows/include/python3.11" ] ; libraries = [ path-to-native "D:/vcpkg/installed/x64-windows/lib" "D:/vcpkg/installed/x64-windows/debug/lib" ] ; Lines 765 - 770: change " local cmd = $(cmds-to-try[1]) ; cmds-to-try = $(cmds-to-try[2-]) ; " to " local cmd = "D:/vcpkg/installed/x64-windows/tools/python3/python.exe" ; cmds-to-try = $(cmds-to-try[2-]) ;"

MFHava commented 1 month ago

Anyone know how to apply this hack? installed\<triplet>\tools\boost-build seems to no longer exist...

kdombroski commented 1 month ago

Anyone know how to apply this hack? installed\<triplet>\tools\boost-build seems to no longer exist...

I had success by modifying this file: packages\boost-build_\tools\boost-build\src\tools\python.jam

MFHava commented 1 month ago

Wait, that one is missing aswell ... turns out there still is a port for boost-build, but boost doesn't include it...

Well apparently I'm stuck anyways as Boost 1.85 is not compatible with Numpy 2.1.1 for API changes and the fix is included with Boost 1,86, which hasn't made it to vcpkg yet...