azure-sdk-for-cpp/samples/integration/cmake-vcpkg/README.md
Ronnie Geraghty b391d65809
Docs links coversion: docs.microsoft.com -> learn.microsoft.com (#6276)
* Docs links coversion: docs.microsoft.com -> learn.microsoft.com
Some markdown formatting

* Adding "msrc" to cspell words

* Undoing things auto formatter did

* Appling Ahson's suggestions
2024-12-16 09:32:19 -08:00

15 KiB

Develop an Azure C++ App using vcpkg and CMake

Perquisite

  1. Any Text Editor
  2. A terminal
  3. A C++ compiler
  4. git

Steps

Install CMake

  • Go to the CMake Downloads page to download an installer for your OS. The installer approach is recommended for simplicity. Optionally you can download the latest version of the CMake source instead. When asked, select the option to add CMake to your PATH.
  • After installing CMake, run the following command to verify CMake has been installed properly:
cmake --version
  • You should get an output denoting the currently install version of CMake. Like this:
cmake version 3.30.2
  • If you don't see the expected output you may need to restart your computer.

Install vcpkg

  • To install vcpkg you'll first need to clone the vcpkg repo. The recommended approach is to clone vcpkg to a central location on your development environment and not in your C++ Project directory. In this example vcpkg is cloned to the home dir.
cd ~
git clone https://github.com/microsoft/vcpkg.git
  • Once the vcpkg repo is cloned traverse into the new directory and run the bootstrap-vcpkg script.

    • If you're on Windows run:
    cd .\vcpkg\
    .\bootstrap-vcpkg.bat
    
    • If you're on MacOS or Linux, run:
    cd vcpkg
    ./bootstrap-vcpkg.sh
    
  • After bootstrapping vcpkg, add it to your path so you can access the vcpkg executable from your project directory. Remember to replace the path in the command example with the path to the vcpkg directory you cloned earlier.

    • On Windows Powershell, enter:
    $env:Path = "$env:Path;C:\path\to\vcpkg"
    
    • On MacOS or Linux systems, enter:
    export PATH=$PATH:/path/to/vcpkg
    
  • Traverse back to your project directory and run the following to verify the vcpkg directory was added to your path:

vcpkg --version
  • You should get an output resembling the following (The hash at the end of the line will most likely not match as a new version has probably released):
vcpkg package management program version 2024-08-01-fd884a0d390d12783076341bd43d77c3a6a15658

Project Setup

  • In your terminal, traverse back to the root of your project.

  • Let's start by creating our main C++ file.

    • On Windows Powershell, enter:
    echo main > main.cpp
    
    • On MacOS and Linux, enter:
    touch main.cpp
    
  • Now lets create our CMakeLists.txt to use with CMake.

    • On Windows Powershell, enter:
    echo cmake > CMakeLists.txt
    
    • On MacOS and Linux systems, enter:
    touch CMakeLists.txt
    
  • We'll also create a build directory to store all out build related artifacts.

    • On Windows Powershell, MacOs and Linux systems, enter:
    mkdir build
    

Setup CMakeLists.txt file

  • Now open the CMakeLists.txt file in your text editor and delete any contents inside it.
  • To set up a extremely basic CMake project, replace the contents of your CMakeLists.txt file with the following:
cmake_minimum_required(VERSION 3.30.0)
project(azure_sample VERSION 0.1.0 LANGUAGES C CXX)

add_executable(azure_sample main.cpp)
  • To test our project setup so far lets also open our main.cpp file and replace it's contents with the following hello world code:
#include <iostream>

int main() {
    std::cout << "Hello World!"<<std::endl;
    return 0;
}
  • Now, in the terminal lets run the command to configure our CMake build.
cmake -B ./build
  • You should see the build directory populate with some directories and files.
  • Now lets try building the project with:
cmake --build ./build
  • The output of the build should contain a line stating where the executable that was built was placed. By default it should be in your build directory under a new Debug directory with the name azure_sample.exe if your on Windows or azure_sample if your on MacOS or Linux.

  • Lets try running our new executable.

    • If your on Windows Powershell, enter:
    .\build\Debug\azure_sample.exe
    
    • If your on MacOS or Linux, enter:
    ./build/azure_sample
    
  • You should get the following out put:

Hello World!

Install packages with vcpkg

  • In this example we'll be using vcpkg in what's known as manifest mode.
  • First we'll start by moving back to the root directory of our project, and creating a new vcpkg application with the following command:
vcpkg new --application
  • You should now have a vcpkg.json and vcpkg-configuration.json file in your project directory with the following contents:

    • vcpkg.json
    {}
    
    • vcpkg-configuration.json It's okay if the hash on the baseline property doesn't match.
    {
      "default-registry": {
        "kind": "git",
        "baseline": "6af584dd59aa5bdba75dae6781ec74614e03e5b9",
        "repository": "https://github.com/microsoft/vcpkg"
      },
      "registries": [
        {
          "kind": "artifact",
          "location": "https://github.com/microsoft/vcpkg-ce-catalog/archive/refs/heads/main.zip",
          "name": "microsoft"
        }
      ]
    }
    
  • Now we can add the Azure Key Vault and Identity libraries from the Azure SDK for C++ to our project, by entering the following command:

vcpkg add port azure-identity-cpp azure-security-keyvault-secrets-cpp
  • Your vcpkg.json file should now look like this:
{
  "dependencies": [
    "azure-identity-cpp",
    "azure-security-keyvault-secrets-cpp"
  ]
}

Integrate CMake with vcpkg

  • To integrate CMake with vcpkg we need to add the vcpkg.cmake module to our CMake toolchain. You can do this either by setting CMAKE_TOOLCHAIN_FILE in your CMakeLists.txt file like this:
cmake_minimum_required(VERSION 3.30.0)

# Remember to replace the path below with the path where you cloned vcpkg
set(CMAKE_TOOLCHAIN_FILE "/path/to/vcpkg-root/scripts/buildsystems/vcpkg.cmake")

project(azure_sample VERSION 0.1.0 LANGUAGES C CXX)

add_executable(azure_sample main.cpp)
  • Or by specifying the toolchain file in the CMake configuration command like this:
cmake -DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg-root/scripts/buildsystems/vcpkg.cmake -B build
  • I'd recommend specifying the toolchain file in the CMakeLists.txt for now as it will shorten the commands you have to enter.

  • We'll also need to tell CMake to find and link our two Azure packages. We can do that by updating our CMakeLists.txt to the following:

cmake_minimum_required(VERSION 3.30.0)

# Remember to replace the path below with the path where you cloned vcpkg
set(CMAKE_TOOLCHAIN_FILE "/path/to/vcpkg-root/scripts/buildsystems/vcpkg.cmake")

project(azure_sample VERSION 0.1.0 LANGUAGES C CXX)

find_package(azure-identity-cpp CONFIG REQUIRED)
find_package(azure-security-keyvault-secrets-cpp CONFIG REQUIRED)

add_executable(azure_sample main.cpp)

target_link_libraries(azure_sample PRIVATE
    Azure::azure-identity
    Azure::azure-security-keyvault-secrets
)

Create an Azure Key Vault resource

  • To create an Azure Key Vault resource you'll need an Azure subscription.
  • We'll use the Azure CLI to create our Key Vault resource and authenticate to Azure.
  • Go to the Azure CLI Install page for instructions on how to install the Azure CLI on your dev environment.
  • Use the following command to authenticate with the Azure CLI
az login
  • Use the pop up windows to login to Azure.

  • Then use the following command to create your Key Vault resource, and remember to replace <your-resource-group-name> and <your-key-vault-name> with your own, unique names:

    az keyvault create --resource-group <your-resource-group-name> --name <your-key-vault-name>
    
  • In the output you should see a list of properties with a vaultUri property. We'll set that to an environment variable to be used in our program with the following command:

    • In a Windows Powershell terminal, enter:
    $env:AZURE_KEYVAULT_URL = "https://<your-key-vault-name>.vault.azure.net/"
    
    • In a MacOS or Linux terminal, enter:
    export AZURE_KEYVAULT_URL="https://<your-key-vault-name>.vault.azure.net/"
    
  • Finally, you'll need to make sure your Azure account has the proper permissions to work with Key Vault Secrets. You can do this by assigning yourself the "Key Vault Secrets Officer" role on the Access Control (IAM) page of your Key Vault resource in the Azure portal.

Add our Azure C++ Code

  • Now we'll update our main.cpp file with the following code to use Azure Key Vault:
#include <azure/identity.hpp> 
#include <azure/keyvault/secrets.hpp> 
#include <iostream>

using namespace Azure::Security::KeyVault::Secrets;

int main(){
    std::cout<<"Starting Program!"<<std::endl;

    try{
        // Set Key Vault URL string
        auto const keyVaultUrl = std::getenv("AZURE_KEYVAULT_URL");

        // Create Default Azure Credential to Authenticate. 
        // It will pick up on our AzureCLI login
         auto credential = std::make_shared<Azure::Identity::DefaultAzureCredential>();

        // Create Key Vault Secret Client
        SecretClient secretClient(keyVaultUrl, credential);

        // Create a Secret
        std::string secretName("MySampleSecret");
        std::string secretValue("My super secret value");
        secretClient.SetSecret(secretName, secretValue);

        // Get the Secret
        KeyVaultSecret secret = secretClient.GetSecret(secretName).Value;
        std::string valueString = secret.Value.HasValue()? secret.Value.Value() : "NONE RETURNED";
        std::cout<<"Secret is returned with name "<<secret.Name<<" and value "<<valueString<<std::endl;

    }catch (const Azure::Core::RequestFailedException& ex){
        std::cout << std::underlying_type<Azure::Core::Http::HttpStatusCode>::type(ex.StatusCode)<<std::endl;
    }

    std::cout<<"End of Program!"<<std::endl;
}

Rebuild and Run

  • After updating our CMakeLists.txt file we'll want to delete the CMake cache. Lets just delete and recreate the ./build directory.

    • In a Windows Powershell terminal, enter:
    Remove-Item -Path .\build\ -Recurse -Force
    
    • In a MacOS or Linux terminal, enter:
    rm -rf ./build
    
  • Now we'll re-add our ./build directory by entering the following command:

mkdir build
  • Reconfigure CMake with the following command:
cmake -B ./build
  • Then we'll build our project with the following command:
cmake --build ./build
  • Next we'll run our program:

    • If your on Windows Powershell, enter:
    .\build\Debug\azure_sample.exe
    
    • If your on MacOS or Linux, enter:
    ./build/azure_sample 
    
  • The program should output the following:

Starting Program!
Secret is returned with name MySampleSecret and value My super secret value
End of Program!

Getting the project ready for git

  • To begin collaborating with others on our Azure C++ project we'll need to change a few things about the way the project has been configured. We need to make sure any file paths we've used are not contained in build files we want to share.
  • Currently our CMakeLists.txt file has a path to the vcpkg.cmake toolchain file on our local machine.
  • Lets remove the set(CMAKE_TOOLCHAIN_FILE "/path/to/vcpkg-root/scripts/buildsystems/vcpkg.cmake") line from the CMakeLists.txt file so it now looks like this:
cmake_minimum_required(VERSION 3.30.0)

project(azure_sample VERSION 0.1.0 LANGUAGES C CXX)

find_package(azure-identity-cpp CONFIG REQUIRED)
find_package(azure-security-keyvault-secrets-cpp CONFIG REQUIRED)

add_executable(azure_sample main.cpp)

target_link_libraries(azure_sample PRIVATE
    Azure::azure-identity
    Azure::azure-security-keyvault-secrets
)
  • Now use the following command to create a CMakeUserPresets.json file. We'll use this file to store our environment specific configurations.

    • In a Windows Powershell terminal, enter:
    echo {} > CMakeUserPresets.json
    
    • In a MacOS or Linux terminal, enter:
    touch CMakeUserPresets.json
    
  • Now open the newly created CMakeUserPresets.json file and replace its contents with the following:

{
    "version": 3,
    "cmakeMinimumRequired": {
      "major": 3,
      "minor": 30,
      "patch": 0
    },
    "configurePresets": [
      {
        "name": "default",
        "displayName": "Default Config",
        "description": "Default build using Ninja generator",
        "binaryDir": "${sourceDir}/build/",
        "cacheVariables": {
          "CMAKE_BUILD_TYPE": "Debug",
          "CMAKE_TOOLCHAIN_FILE": "/path/to/vcpkg/root/scripts/buildsystems/vcpkg.cmake"
        }
      }
    ],
    "buildPresets": [
      {
        "name": "default",
        "configurePreset": "default"
      }
    ]
  }
  • Replace the value of the CMAKE_TOOLCHAIN_FILE property with the path to the vcpkg cmake toolchain file. Note: this will be the same path we used for this property in our CMakeLists.txt file earlier.

  • Now that we're using presets with CMake, our CMake project will configure differently. Lets clean our build directory so the CMake Cache doesn't conflict with our new configuration.

    • In a Windows Powershell terminal, enter:
    Remove-Item -Path .\build\ -Recurse -Force
    
    • In a MacOS or Linux terminal, enter:
    rm -rf ./build
    
  • Now we'll re-add our ./build directory by entering the following command:

mkdir build
  • Now to configure our CMake project will run the following command:
cmake --preset default
  • Then we can build the project with this next command:
cmake --build --preset default
  • Finally we can run our program again with these commands:

    • If your on Windows Powershell, enter:
    .\build\Debug\azure_sample.exe
    
    • If your on MacOS or Linux, enter:
    ./build/azure_sample 
    
  • The last thing we need to do to get our project ready for collaboration with git is add a .gitignore file that specifies that the CMakeUserPresets.json file should not be included in source control.

  • To creat the .gitignore file use the following commands:

    • If your on Windows Powershell, enter:
    echo ignore > .gitignore
    
    • If your on MacOS or Linux, enter:
    touch .gitignore
    
  • Then open the .gitignore file in your editor and replace its contents with the following

build 
CMakeUserPresets.json
  • Now you can push your project up to git, and collaboraters can clone it to work on the project with you. They will need to make sure they have properly set up their C++ compiler, CMake, adn vcpkg. They will also need to create their own CMakeUsersPresets.json file to point to where they installed the vcpkg.cmake module.