Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save milnak/67e5b7bf036c26827a8eee2911028e37 to your computer and use it in GitHub Desktop.
Save milnak/67e5b7bf036c26827a8eee2911028e37 to your computer and use it in GitHub Desktop.
Visual Studio VC Build Tools w/vcpkg, CMake and Ninja, plus Qt

Visual Studio VC Build Tools w/vcpkg, CMake and Ninja, plus Qt

Install Build Tools

winget.exe install `
  --id Microsoft.VisualStudio.2022.BuildTools `
  --override '--passive --wait `
  --add Microsoft.VisualStudio.Workload.VCTools `
  --add Microsoft.VisualStudio.Component.VC.ATL `
  --includeRecommended'

Components that will be installed are:

Microsoft.VisualStudio.Workload.VCTools (Desktop development with C++):

  • Microsoft.Component.MSBuild (MSBuild)
  • Microsoft.VisualStudio.Component.TextTemplating (Text Template Transformation)
  • Microsoft.VisualStudio.Component.VC.CoreBuildTools (C++ Build Tools core features)
  • Microsoft.VisualStudio.Component.VC.CoreIde (C++ core features)
  • Microsoft.VisualStudio.Component.VC.Redist.14.Latest (C++ 2022 Redistributable Update)
  • Microsoft.VisualStudio.ComponentGroup.NativeDesktop.Core (C++ core desktop features)
  • Microsoft.VisualStudio.Component.VC.ATL (C++ ATL for latest v143 build tools)

Recommended (--includeRecommended):

  • Microsoft.VisualStudio.Component.TestTools.BuildTools (Testing tools core features - Build Tools)
  • Microsoft.VisualStudio.Component.VC.ASAN (C++ AddressSanitzer)
  • Microsoft.VisualStudio.Component.VC.CMake.Project (C++ CMake tools for Windows)
  • Microsoft.VisualStudio.Component.VC.Tools.x86.x64 (MSVC v143 - VS 2022 C++ x64/x86 build tools (Latest))
  • Microsoft.VisualStudio.Component.Windows11SDK.22621 (Windows 11 SDK (10.0.22621.0)

See: Build Tools Component Directory

Install Paths for installed tools:

  • MSVC: C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC
  • CMake: C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake
  • Ninja: C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja
  • Windows Kits: C:\Program Files (x86)\Windows Kits\10

Install CMake

Even though CMake is included with Build Tools, it's an older version. Install using:

winget.exe install --id 'Kitware.CMake'

This will install the latest version and add it to the PATH.

Install Ninja

Even though Ninja is included with Build Tools, it's an older version. Install using:

winget.exe install --id 'Ninja-build.Ninja'

This will install the latest version and add it to the PATH.

Install vcpkg

git.exe clone https://github.com/microsoft/vcpkg.git C:\VCPKG

Push-Location 'C:\VCPKG\scripts'
.\bootstrap.ps1 -disableMetrics
Pop-Location

Set Environment Variables

From start, run "Edit the system environment variables", Click "Environment Variables...", then to "User variables":

  • Edit Path and add C:\VCPKG
  • Create new variable VCPKG_ROOT and set to C:\VCPKG

Browse vcpkg public packages

Create Simple Project

From Tutorial: Install and use packages with vcpkg

mkdir helloworld-vcpkg; cd helloworld-vcpkg
mkdir src

# Creates "vcpkg.json" and "vcpkg-configuration.json".
vcpkg.exe new --application

# Adds "dependencies": [ "fmt" ] to "vcpkg.json".
vcpkg.exe add port fmt

CMakeLists.txt

cmake_minimum_required(VERSION 3.15)
project(helloworld LANGUAGES CXX)

find_package(fmt CONFIG REQUIRED)

add_executable(HelloWorld src/main.cpp)
target_link_libraries(HelloWorld PRIVATE fmt::fmt)

Tip: To format, install cmake-format using pip install cmake-format, then run cmake-format --in-place .\CMakeLists.txt

src/main.cpp

#include <vector>
#include <fmt/core.h>
#include <fmt/ranges.h> // formatting of ranges and tuples

int main()
{
    fmt::print("Hello World!\n");
    std::vector<int> v{1, 2, 3};
    fmt::print("{}\n", v);
    return 0;
}

Build and Run (msvc)

Note that you don't need to open the Visual Studio Build environment. "vcpkg.cmake" will find the Build Tools installatioon location.

cmake.exe -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" -B build

cmake.exe --build build

.\build\Debug\HelloWorld.exe

Build and Run (presets / ninja)

Important: To use ninja, the build tools must be in the path. The easiest way to do this is to open "Developer PowerShell for VS 2022", and use the following commands. Alternately, you can add all of the tool paths (cl.exe, rc.exe) to your PATH.

CMake project presets can be specified in a CMakePresets.json file and referenced from the command line.

CMakePresets.json

{
  "version": 2,
  "configurePresets": [
    {
      "name": "ninja-build",
      "generator": "Ninja",
      "binaryDir": "${sourceDir}/build",
      "cacheVariables": {
        "CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
      }
    }
  ]
}

Build using the "ninja-build" preset:

rm .\build\CMakeCache.txt

# Adding `--debug-output` can help debug issues.
cmake.exe --preset=ninja-build

ninja.exe -C build

.\build\HelloWorld.exe

Create cmake project with library and ctest support

Create folders and vcpkg configuration:

mkdir cmake-catch2-lib; cd cmake-catch2-lib
mkdir libfact

vcpkg.exe new --application
vcpkg.exe add port catch2

CMakeLists.txt

cmake_minimum_required(VERSION 3.5)

project(
  fact
  LANGUAGES CXX
  VERSION 1.0)

find_package(Catch2 3 REQUIRED)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# preparetestlibrary()

# main executable (fact)
add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME} PRIVATE libfact)

# library (libfact)
add_subdirectory(libfact)

# test (fact_test)
add_executable(fact_test fact_test.cpp)
target_link_libraries(fact_test PRIVATE libfact Catch2::Catch2WithMain)

include(CTest)
include(Catch)
catch_discover_tests(fact_test)

fact_test.cpp

// from https://github.com/catchorg/Catch2
#include <catch2/catch_test_macros.hpp>

#include "libfact/fact.hpp"

TEST_CASE("factorials are computed")
{
    REQUIRE(factorial(1) == 1);
    REQUIRE(factorial(2) == 2);
    REQUIRE(factorial(3) == 6);
    REQUIRE(factorial(10) == 3628800);
}

libfact\CMakeLists.txt

cmake_minimum_required(VERSION 3.25)

project(libfact)

add_library(${PROJECT_NAME} fact.cpp)

# target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)

libfact\fact.cpp

#include "fact.hpp"

unsigned int factorial(unsigned int number)
{
    return number <= 1 ? number : factorial(number - 1) * number;
}

libfact\fact.hpp

#ifndef FACT_HPP
#define FACT_HPP

unsigned int factorial(unsigned int number);

#endif

main.cpp

#include <iostream>
#include "libfact/fact.hpp"

int main(int argc, char **argv)
{
    std::cout << "factorial(5) = " << factorial(5) << std::endl;

    return 0;
}

Build and Test:

cmake.exe -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" -B build
cmake.exe --build build --config RelWithDebInfo

# Should return "factorial(5) = 120".
build\RelWithDebInfo\fact.exe

# Should return "100% tests passed, 0 tests failed out of 1".
cd build
ctest.exe --verbose

Build Qt Project (qt_world_summit_2019_cmake_vcpkg_app)

Clone Qt Project

git.exe clone https://github.com/alcroito/qt_world_summit_2019_cmake_vcpkg_app.git
cd qt_world_summit_2019_cmake_vcpkg_app

Fix CMakeLists.txt

Change lines 15-17 to read:

find_package(botan CONFIG REQUIRED)

set(CMAKE_CXX_STANDARD 20)

Without the first change, you will get a "Could NOT find Botan" errors.

Without the second change, you will get "syntax error: identifier 'contiguous_range'" errors.

Create "vcpkg-configuration.json" and "vcpkg.json".

vcpkg.exe new --application

Add dependendent vcpkg ports

See qt5 package list at https://vcpkg.io/en/packages?query=qt5

Note that building qtwebengine will fail with:

Buildtree path is too long. Build will fail! Pass --x-buildtrees-root= to vcpkg!

This is because port "qt5" brings in that library, so we can't use "vcpkg.exe add port qt5".

Instead, we'll include only the specific Qt ports that are required, which will be faster to set up.

To determine what ports are needed, build and then look for errors about missing libraries, e.g. "Could NOT find Botan"

vcpkg.exe add port botan qt5-base qt5-quickcontrols qt5-quickcontrols2

Create makefiles

cmake.exe -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" -B build

cmake.exe --build build

Run app

Note that this project uses a hard coded encryption key! See DocumentHandler::setupEncryptionKey()

Don't use this for encrypting secret information as-is!

.\build\Debug\encrypted_texteditor.exe

Uninstalling VCPKG

When no longer needed.

Remove-Item -Verbose -Recurse -Force -LiteralPath 'C:\VCPKG'
Remove-Item -Verbose -Recurse -Force -LiteralPath "$env:LOCALAPPDATA\vcpkg"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment