* 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 |
||
|---|---|---|
| .. | ||
| .gitignore | ||
| CMakeLists.txt | ||
| CMakeUserPresets.example.json | ||
| main.cpp | ||
| README.md | ||
| vcpkg-configuration.json | ||
| vcpkg.json | ||
Develop an Azure C++ App using vcpkg and CMake
Perquisite
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
builddirectory 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.txtfile in your text editor and delete any contents inside it. - To set up a extremely basic CMake project, replace the contents of your
CMakeLists.txtfile 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.cppfile 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
builddirectory under a newDebugdirectory with the nameazure_sample.exeif your on Windows orazure_sampleif 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.jsonandvcpkg-configuration.jsonfile in your project directory with the following contents:vcpkg.json
{}vcpkg-configuration.jsonIt's okay if the hash on thebaselineproperty 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.jsonfile 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.cmakemodule to our CMake toolchain. You can do this either by settingCMAKE_TOOLCHAIN_FILEin yourCMakeLists.txtfile 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.txtfor 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.txtto 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
vaultUriproperty. 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.cppfile 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.txtfile we'll want to delete the CMake cache. Lets just delete and recreate the./builddirectory.- 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
./builddirectory 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.txtfile has a path to thevcpkg.cmaketoolchain file on our local machine. - Lets remove the
set(CMAKE_TOOLCHAIN_FILE "/path/to/vcpkg-root/scripts/buildsystems/vcpkg.cmake")line from theCMakeLists.txtfile 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.jsonfile. 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.jsonfile 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_FILEproperty with the path to the vcpkg cmake toolchain file. Note: this will be the same path we used for this property in ourCMakeLists.txtfile 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
./builddirectory 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
.gitignorefile that specifies that theCMakeUserPresets.jsonfile should not be included in source control. -
To creat the
.gitignorefile 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
.gitignorefile 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.jsonfile to point to where they installed thevcpkg.cmakemodule.