Search code examples
c++qtcmakeqt-creatorvcpkg

On Qt Creator project based on CMAKE, how to point to VCPKG?


On (macOS silicon) Qt Creator project based on QMAKE, I had to add the following in order to make it find VCPKG:

QMAKE_APPLE_DEVICE_ARCHS = arm64

CONFIG(debug, debug|release) {
     MODE = debug
     d = d
} else {

}

INCLUDEPATH += $$(VCPKG)/include
     LIBS += -L$$(VCPKG)/$${MODE}/lib
     LIBS += -lfmt$${d}

Considering export VCPKG=~/vcpkg/installed/arm64-osx.

What about CMAKE? I created a C++ project based on it and looks like the following:

cmake_minimum_required(VERSION 3.5)

project(untitled1 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_executable(untitled1 main.cpp)

install(TARGETS untitled1
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})

The vcpkg instructions are for In order to use vcpkg with CMake outside of an IDE:

cmake -B [build directory] -S . -DCMAKE_TOOLCHAIN_FILE=[path to vcpkg]/scripts/buildsystems/vcpkg.cmake

How to use vcpkg with CMake inside of an IDE?


Solution

  • Just as the instruction said, you should not change your CMake files at all and pass this in the command line:

    cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake
    

    This assume the environment variable VCPKG_ROOT is defined to point to the vcpkg installation.

    You can add the toolchain command line argument inside a CMakePresets.json file.

    Then, to ensure that vcpkg installs what you need, I would also create a manifest file:

    {
        "name": "my-project",
        "version-string": "0.1.0",
        "dependencies": [
            "fmt"
            // or any other dependencies
        ]
    }
    

    Then, your CMake file should simply find those packages:

    cmake_minimum_required(VERSION 3.5)
    
    project(untitled1 LANGUAGES CXX)
    
    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
    
    add_executable(untitled1 main.cpp)
    
    install(TARGETS untitled1
        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
    
    find_package(fmt REQUIRED)
    
    target_link_libraries(untitled1 PUBLIC fmt::fmt)
    

    vcpkg will actually output usage examples when installing the packages.

    Here's an example of a preset file that setup the vcpkg toolchain:

    {
        "version": 2,
        "cmakeMinimumRequired": {
            "major": 3,
            "minor": 22,
            "patch": 0
        },
        "configurePresets": [
            {
                "name": "cmake-pedantic",
                "hidden": true,
                "warnings": {
                    "dev": false,
                    "deprecated": true,
                    "uninitialized": true,
                    "unusedCli": true,
                    "systemVars": false
                },
                "errors": {
                    "dev": false,
                    "deprecated": true
                }
            },
            {
                "name": "generator-ninja",
                "hidden": true,
                "generator": "Ninja Multi-Config",
                "binaryDir": "${sourceDir}/build",
                "cacheVariables": {
                    "CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake",
                    "CMAKE_DEBUG_POSTFIX": "d",
                    "CMAKE_MAKE_PROGRAM": "ninja"
                }
            },
            {
                "name": "dev",
                "displayName": "Development",
                "description": "Development preset",
                "inherits": ["generator-ninja"]
            }
        ],
        "buildPresets": [
            {
                "name": "dev-debug",
                "displayName": "Debug",
                "description": "Build with debug informations",
                "configuration": "Debug",
                "configurePreset": "dev"
            },
            {
                "name": "dev-relwithdebinfo",
                "displayName": "RelWithDebInfo",
                "description": "Build with debug informations and optimizations enabled",
                "configuration": "RelWithDebInfo",
                "configurePreset": "dev"
            },
            {
                "name": "dev-release",
                "displayName": "Release",
                "description": "Build with optimizations enabled",
                "configuration": "Release",
                "configurePreset": "dev"
            }
        ],
        "testPresets": [
            {
                "name": "base-test",
                "hidden": true,
                "output": {
                    "outputOnFailure": true
                },
                "execution": {
                    "noTestsAction": "error",
                    "stopOnFailure": true
                }
            },
            {
                "name": "dev-debug",
                "displayName": "Debug",
                "configuration": "Debug",
                "configurePreset": "dev",
                "inherits": "base-test"
            },
            {
                "name": "dev-relwithdebinfo",
                "displayName": "RelWithDebInfo",
                "configuration": "RelWithDebInfo",
                "configurePreset": "dev",
                "inherits": "base-test"
            },
            {
                "name": "dev-release",
                "displayName": "Release",
                "configuration": "Release",
                "configurePreset": "dev",
                "inherits": "base-test"
            }
        ]
    }
    

    With the presence of the preset file, you have to use this command line instead:

    # from the source directory
    cmake --preset dev
    cmake --build --preset dev-debug
    

    Refer to the cmake-presets documentation


    Not recommended

    You can also set the toolchain file in your CMake file. However, it is ill-advise to do so. It will create problems in the long run. You should make your build specification independent of your toolchain files.

    Toolchain files are useful when building the app on multiple platforms and multiple compilers. Hardcoding it is chasing problems.

    Here's how to do it:

    # This will make issues in the future
    set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake")
    

    Do that before any call to project.