28

I want to use vcpkg in a CMake project in Windows, because I need boost and xerces that are both handled by this package manager.

I've the following CMakeLists.txt:

cmake_minimum_required (VERSION 3.12.0)

project (myproj)

set (CMAKE_PREFIX_PATH ${XERCES_ROOT})
set (Boost_USE_STATIC_LIBS ON)
set (Boost_USE_MULTITHREADED ON)
unset (Boost_INCLUDE_DIR CACHE)
unset (Boost_LIBRARY_DIRS CACHE)

# set (CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/modules)
find_package (Boost COMPONENTS filesystem regex REQUIRED)
find_package (XercesC CONFIG REQUIRED)

set (CMAKE_INCLUDE_CURRENT_DIR ON)
message (STATUS "binary dir is ${CMAKE_BINARY_DIR}")
include_directories (${CMAKE_BINARY_DIR}/${PROJECT_NAME}/)
include_directories (${CMAKE_CURRENT_SOURCE_DIR}/..)
include_directories (${Boost_INCLUDE_DIRS})
include_directories (${XercesC_INCLUDE_DIRS})

set (PROJECT_SRC
  code.cpp
  )

add_library (${PROJECT_NAME} SHARED ${PROJECT_SRC})
add_dependencies (${PROJECT_NAME} UPDATE_RESOURCES)
target_link_libraries (${PROJECT_NAME} ${Boost_LIBRARIES} XercesC::XercesC)

Boost and xerces-c are installed with vcpkg. Since I'm using Visual Studio Code I'm setting vcpkg variables in settings.json:

  "cmake.configureSettings": {
    "CMAKE_TOOLCHAIN_FILE" : "some/path/vcpkg/scripts/buildsystems/vcpkg.cmake",
    "VCPKG_TARGET_TRIPLET": "x64-windows"
  }

When I run che CMake I obtain following errors:

[cmake] CMake Error at C:/Program Files/CMake/share/cmake-3.14/Modules/FindBoost.cmake:2132 (message):
[cmake]   Unable to find the requested Boost libraries.
[cmake] 
[cmake]   Unable to find the Boost header files.  Please set BOOST_ROOT to the root
[cmake]   directory containing Boost or BOOST_INCLUDEDIR to the directory containing
[cmake]   Boost's headers.
[cmake] Call Stack (most recent call first):
[cmake]   D:/projects/vcpkg/scripts/buildsystems/vcpkg.cmake:233 (_find_package)
[cmake]   src/myroject/CMakeLists.txt:24 (find_package)
[cmake] 
[cmake] 
[cmake] CMake Error at D:/Projects/vcpkg/installed/x64-windows/share/xercesc/vcpkg-cmake-wrapper.cmake:1 (_find_package):
[cmake]   Could not find a package configuration file provided by "XercesC" with any
[cmake]   of the following names:
[cmake] 
[cmake]     XercesCConfig.cmake
[cmake]     xercesc-config.cmake
[cmake] 
[cmake]   Add the installation prefix of "XercesC" to CMAKE_PREFIX_PATH or set
[cmake]   "XercesC_DIR" to a directory containing one of the above files.  If
[cmake]   "XercesC" provides a separate development package or SDK, be sure it has
[cmake]   been installed.
[cmake] Call Stack (most recent call first):
[cmake]   D:/Projects/vcpkg/scripts/buildsystems/vcpkg.cmake:189 (include)
[cmake]   src/ZLA/CMakeLists.txt:25 (find_package)
[cmake] 
[cmake] 
[cmake] Configuring incomplete, errors occurred!
[cmake] See also "D:/Projects/zla/build/vscode/CMakeFiles/CMakeOutput.log".
[cms-driver] Error during CMake configure: [cmake-server] Configuration failed.

At the moment I've installed xerces with vcpkg commands, while boost is currently not installed, but I was expecting that during the execution of the cmake command, vcpkg will download and build needed build packages.

I've tried also the command line:

 cmake -DCMAKE_TOOLCHAIN_FILE=D:/Projects/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows ../

but the result is the same.

What I'm doing wrong? How can I use vcpkg successfully?

Jepessen
  • 11,744
  • 14
  • 82
  • 149

4 Answers4

19

In theory it's as simple as (assuming vcpkg as installed in C:/vcpkg as it is for github actions);

  1. Install your "foo" package with vcpkg install foo

  2. Make sure your CMakeLists.txt finds and uses the package with;

    find_package(FOO)
    # Use these instead of the package doesn't have proper cmake 
    package support.
    # find_path(FOO_INCLUDE_DIRS foo.h)
    # find_library(FOO_LIBRARYS foo)
    include_directories(${FOO_INCLUDE_DIRS})
    target_link_libraries(myprogram ${FOO_LIBRARIES})                                     
    
  3. Run cmake with

    -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake
    

But... this didn't work for me until I added --triplet x64-windows to the vcpkg install command.

The DCMAKE_TOOLCHAIN_FILE sets the various CMAKE_(SYSTEM_)?(PREFIX|LIBRARY|INCLUDE|FRAMEWORK)_PATH variables to enable the find_*() cmake functions to work, but note that these paths include the VCPKG_TARGET_TRIPLET. In my case the package install with vcpkg install <foo> defaulted to x86-windows but then invoking cmake with -DCMAKE_TOOLCHAIN_FILE=C:/.... defaulted to x64-windows so it couldn't find the the package.

Currently vcpkg defaults to the older x86 target, but modern Visual Studio (as used by githup actions) defaults to x64. The fix was to install the package with vcpkg -triplet x64-windows install <foo>. It took me way too long going down too many red-herring rabbit holes to discover this.

aSemy
  • 5,485
  • 2
  • 25
  • 51
Donovan Baarda
  • 411
  • 4
  • 5
  • This is the solution for my problem. The only thing to mention is that it is `--triplet x64-windows`, not `--triple x64-windows`. – Ivan Siutsou Nov 26 '21 at 14:18
  • Thanks, i think I corrected this (or accepted a correction?) some time ago but forgot to acknowledge the correction. – Donovan Baarda Aug 19 '22 at 03:16
  • According to vcpkg warning: the default triplet for vcpkg libraries *will* change from x86-windows to the detected host triplet since the September 2023 release. For anyone who doesn't want to wait, try to set the `VCPKG_DEFAULT_TRIPLET` environment variable. – kbridge4096 Feb 25 '23 at 15:06
17
  1. You need to install the packages beforehand (using vcpkg install ).

    (Then you could specify the toolchain as a CMake option:

     -DCMAKE_TOOLCHAIN_FILE=C:\path\to\vcpkg\scripts\buildsystems\vcpkg.cmake
    

    but this won't work if you already specify a toolchain, such as when cross-compiling.)

  2. "include" it, instead, to avoid this problem:

    Add this line to the project CMakeLists.txt before find_package():

    include(/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake)
    
aSemy
  • 5,485
  • 2
  • 25
  • 51
automorphic
  • 680
  • 7
  • 18
  • Doing this sets the various `CMAKE_(SYSTEM_)?(PREFIX|LIBRARY|INCLUDE|FRAMEWORK)_PATH` cmake variables to enable the find_*() cmake functions to work, but note that these paths include the VCPKG_TARGET_TRIPLET. – Donovan Baarda Aug 07 '21 at 00:41
7

boost is currently not installed, but I was expecting that during the execution of the cmake command, vcpkg will download and build needed build packages.

This is not the case as far as I know. You need to install the packages you want with vcpkg beforehand for the triplet you plan to use (i.e. x64-windows). You will then need to ensure that the correct triplet is being used when you run CMake (check the VCPKG_TARGET_TRIPLET variable in your CMakeCache.txt). If it's incorrect, you can change it and re-configure using CMake.

Additionally, based on the error output you're getting, it doesn't seem that xerces has been installed properly either using vcpkg. You can check what is installed with vcpkg by running:

vcpkg list --triplet x64-windows

Developer Paul
  • 1,502
  • 2
  • 13
  • 18
  • I've executed the command and xerces seems to be installed: `xerces-c:x64-windows 3.2.2-8 Xerces-C++ is a XML parser, for parsing, generat…`. And in the `CMakeCache.txt` I've the correct triplet: `VCPKG_TARGET_TRIPLET:STRING=x64-windows` – Jepessen Apr 03 '19 at 13:58
  • @Jepessen ok, how about boost? – Developer Paul Apr 03 '19 at 14:00
  • I'm installing them right now with `vcpkg install boost:x64-windows`. It will take a while. But I think that the problem is with xerces, since it can be the same for all libraries. – Jepessen Apr 03 '19 at 14:02
  • 1
    For XercesC, remove `CONFIG` from your `find_package` call. CMake should be able to find the library if you have installed it with `vcpkg`. – Developer Paul Apr 03 '19 at 16:17
  • 1
    I've removed `CONFIG`, even if it was suggested by xerces-c vcpkg package, but nothing changes. – Jepessen Apr 04 '19 at 07:26
  • 1
    Delete all XercesC variables in your CMake cache and re-configure? – Developer Paul Apr 04 '19 at 12:59
  • @Jepessen I have the same issue with CMake error of your xerces lib. What was the solution? I've already checked the variable `VCPKG_TARGET_TRIPLET`. My CMake doesn't detect the lib. vcpkg list shows that the package is installed. – ywiyogo May 25 '20 at 21:33
2

I had the same issue and just solved it either with:

set(CURL_DIR "C:/Libs/vcpkg/installed/x64-windows/share/curl")

or

list(APPEND CMAKE_PREFIX_PATH "C:/Libs/vcpkg/packages/curl_x64-windows/share/curl/")

I installed vcpkg under C:/Libs

ywiyogo
  • 738
  • 2
  • 7
  • 21