Adding Azure Storage Client Library from vcpkg to a CMake Project

Phong Cao
3 min readAug 18, 2020

--

Azure Storage Client Library, vcpkg and CMake
Images from logodix.com and freeiconshop.com

The Azure Storage Client Library for C++ allows building applications against Microsoft Azure Storage. It supports both Windows and Linux platforms and has many dependencies during install. Therefore, it’s recommended to use a cross-platform library manager to install it.

vcpkg is a cross-platform C++ library manager, which provides the latest version of the Azure Storage Client Library. It’s been constantly evolving and is easy to be integrated with Azure Pipelines.

In this post, we’ll learn about how to integrate the Azure Storage Client Library, which is installed via vcpkg, to a CMake project targeting both Windows and Linux platforms.

Installing the Azure Storage Client Library

To install the Azure Storage Client Library through vcpkg, we need vcpkg installed first.

Windows:

> git clone https://github.com/microsoft/vcpkg.git
> .\vcpkg\bootstrap-vcpkg.bat
> .\vcpkg\vcpkg install azure-storage-cpp:x64-windows

Linux:

$ git clone https://github.com/microsoft/vcpkg.git
$ ./vcpkg/bootstrap-vcpkg.sh
$ ./vcpkg/vcpkg install azure-storage-cpp

This process not only installs azure-storage-cpp but also all of its dependencies such as cpprestsdk and boost so it may take up to 15-30 minutes to complete.

CMake Project Integration

Before we dive into the CMakeLists.txt file, when generating a project, remember to invoke the cmake command with -DCMAKE_TOOLCHAIN_FILE=[vcpkg directory]/scripts/buildsystems/vcpkg.cmake so that vcpkg packages can be referenced from our project.

To access the Azure Storage Client Library’s header files, we need to search for its include directories and include them:

find_path(WASTORAGE_INCLUDE_DIR was/blob.h)
include_directories(${WASTORAGE_INCLUDE_DIR})

blob.h can be replaced by any file that exists in the was directory.

Next is finding the required libraries so that we can link them later:

if (NOT WIN32)
find_library(WASTORAGE_LIBRARY azurestorage)
find_library(CPPREST_LIBRARY cpprest)
find_library(BOOST_LOG_LIBRARY boost_log)
find_library(BOOST_THREAD_LIBRARY boost_thread)
find_library(SSL_LIBRARY ssl)
find_library(XML2_LIBRARY xml2)
find_library(LZMA_LIBRARY lzma)
find_library(UUID_LIBRARY uuid)
find_library(Z_LIBRARY z)
find_library(CRYPTO_LIBRARY crypto)
else()
find_library(WASTORAGE_LIBRARY wastorage)
find_library(CPPREST_LIBRARY
NAMES cpprest cpprest_2_10)
endif()

Notes: some libraries are named differently on Windows and Linux by vcpkg (Release 2020.06 at the time of writing):
1. The Azure Storage Client Library is libazurestorage.a file on Linux and wastorage.lib file on Windows.
2. The cpprestsdk library is libcpprest.a file on Linux and cpprest_2_10.lib file on Windows.

Finally, link our project to generate the executable file:

add_executable(my_example ./src/main.cc)
if(NOT WIN32)
target_link_libraries(my_example
${OPENSSL_LIBRARY}
${WASTORAGE_LIBRARY}
${CPPREST_LIBRARY}
${BOOST_LOG_LIBRARY}
${BOOST_THREAD_LIBRARY}
${SSL_LIBRARY}
${XML2_LIBRARY}
${LZMA_LIBRARY}
${UUID_LIBRARY}
${Z_LIBRARY}
${CRYPTO_LIBRARY}
${CMAKE_DL_LIBS}
)
else()
target_link_libraries(my_example
${OPENSSL_LIBRARY}
${WASTORAGE_LIBRARY}
${CPPREST_LIBRARY}
)
endif()

Notes for Windows: when building for Debug configuration, the executable expects cpprest_2_10.dll file, which is missing from the output folder. The workaround is duplicating cpprest_2_10d.dll file and renaming it to cpprest_2_10.dll.

Using the Azure Storage Client Library

Now we are ready to use the Azure Storage Client Library. The following sample code constructs an Azure Blob client, which is used to access the Azure Blob Storage:

#include <was/storage_account.h>
#include <was/blob.h>
auto storage_account = azure::storage::cloud_storage_account::parse(
_XPLATSTR("STORAGE_CONNECTION_STRING"));
auto blob_client = storage_account.create_cloud_blob_client();

Note that most methods of the Azure Storage Client Library use utility::string_t type, which is defined as std::string on Linux and std::wstring on Windows by default so we can use the following method to easily convert between those types:

#include <locale>
#include <codecvt>
utility::string_t to_string_t(const std::string& str) {
#ifdef _WIN32
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::wstring wstr = converter.from_bytes(str);
return wstr;
#else
return str;
#endif
}
...// Using to_string_t
const std::string storage_connection_string = "...";
auto storage_account = azure::storage::cloud_storage_account::parse(
to_string_t(storage_connection_string));

Thank you for reading this post. Check out this example project on GitHub to learn more about the Azure Storage Client Library for C++.

Links

--

--

Phong Cao
Phong Cao

Responses (3)