Azure / Azure/azure-sdk-for-cpp
Add version resources to Azure SDK binaries when building on Windows
- Dominant language
- C++
- Stars
- 205
- Forks
- 172
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 37
Description
## Problem
When Azure SDK for C++ packages are built as shared libraries (DLLs) on Windows, the resulting binaries contain no embedded version information. Windows users and administrators rely on the **Details** tab in file properties to identify DLL versions, publisher, and product information. Without a [VERSIONINFO resource](https://learn.microsoft.com/en-us/windows/win32/menurc/versioninfo-resource), the DLL Details tab is empty, making it difficult to:
- Determine which version of an Azure SDK library is deployed
- Diagnose version mismatch issues in production environments
- Satisfy enterprise software inventory and compliance requirements
- Identify the publisher and copyright information
This was originally reported in #5158 which was auto-closed due to inactivity.
## Current State
Each SDK package already defines version information in `src/private/package_version.hpp` with standard macros:
```cpp
#define AZURE_CORE_VERSION_MAJOR 1
#define AZURE_CORE_VERSION_MINOR 17
#define AZURE_CORE_VERSION_PATCH 0
#define AZURE_CORE_VERSION_PRERELEASE "beta.1"
```
The CMake infrastructure already extracts these values via `get_az_version()` in `cmake-modules/AzureVersion.cmake` and sets `AZ_LIBRARY_VERSION` on each target. The `az_vcpkg_export()` macro in `AzureVcpkg.cmake` already handles Windows-specific DLL configuration (export symbols, `dll_import_export.hpp` patching). However, **no `.rc` resource files exist anywhere in the repository** — there is no version resource embedded in any DLL.
## Proposed Solution
Add a Windows version resource (`.rc` file) to each SDK library that is compiled into the DLL when `BUILD_SHARED_LIBS=ON` on Windows. The resource should be generated from a shared template using CMake's `configure_file()`, populated with the version values already parsed from `package_version.hpp`.
## Implementation Plan
### 1. Create a shared `.rc.in` template
Add `cmake-modules/version.rc.in` with a `VERSIONINFO` resource template:
```rc
#include
VS_VERSION_INFO VERSIONINFO
FILEVERSION @AZ_VERSION_MAJOR@, @AZ_VERSION_MINOR@, @AZ_VERSION_PATCH@, 0
PRODUCTVERSION @AZ_VERSION_MAJOR@, @AZ_VERSION_MINOR@, @AZ_VERSION_PATCH@, 0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS @AZ_VERSION_FILEFLAGS@
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE VFT2_UNKNOWN
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904B0"
BEGIN
VALUE "CompanyName", "Microsoft Corporation\0"
VALUE "FileDescription", "@AZ_VERSION_FILE_DESCRIPTION@\0"
VALUE "FileVersion", "@AZ_VERSION_STRING@\0"
VALUE "InternalName", "@AZ_VERSION_TARGET_NAME@\0"
VALUE "LegalCopyright", "Copyright (c) Microsoft Corporation. All rights reserved.\0"
VALUE "OriginalFilename", "@AZ_VERSION_TARGET_NAME@.dll\0"
VALUE "ProductName", "Microsoft Azure SDK for C++\0"
VALUE "ProductVersion", "@AZ_VERSION_STRING@\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0409, 0x04B0
END
END
```
### 2. Add a CMake helper function
Add `az_add_version_resource()` to `AzureVersion.cmake` (or a new `AzureVersionResource.cmake` module). This function should:
- Accept the target name and a human-readable file description
- Require that `get_az_version()` has already been called (use the parsed `VERSION_MAJOR`, `VERSION_MINOR`, `VERSION_PATCH` values)
- Only activate when `WIN32 AND BUILD_SHARED_LIBS` are both true (no-op otherwise)
- Set `AZ_VERSION_FILEFLAGS` to `VS_FF_PRERELEASE` when `VERSION_PRERELEASE` is non-empty, and `0` otherwise
- Call `configure_file()` on the `.rc.in` template to produce a target-specific `.rc` file in `${CMAKE_CURRENT_BINARY_DIR}`
- Add the generated `.rc` file to the target's sources via `target_sources()`
### 3. Integrate into each library's CMakeLists.txt
After the existing `get_az_version()` and `set_target_properties(... VERSION ...)` calls, add:
```cmake
az_add_version_resource(azure-core "Microsoft Azure Core SDK for C++")
```
This must be added to all 20 SDK packages that have `package_version.hpp` files:
- `azure-core`, `azure-core-amqp`, `azure-core-test`, `azure-core-tracing-opentelemetry`
- `azure-identity`
- `azure-security-attestation`
- `azure-security-keyvault-administration`, `azure-security-keyvault-certificates`, `azure-security-keyvault-keys`, `azure-security-keyvault-secrets`
- `azure-storage-blobs`, `azure-storage-common`, `azure-storage-files-datalake`, `azure-storage-files-shares`, `azure-storage-queues`
- `azure-messaging-eventhubs`, `azure-messaging-eventhubs-checkpointstore-blob`
- `azure-data-appconfiguration`, `azure-data-tables`
- `azure-template`
### 4. Update `get_az_version()` to export individual version components
Currently `get_az_version()` only sets `AZ_LIBRARY_VERSION` in the parent scope. It should also set `AZ_VERSION_MAJOR`, `AZ_VERSION_MINOR`, `AZ_VERSION_PATCH`, and `AZ_VERSION_PRERELEASE` in the parent scope so the version resource function can use them without re-parsing.
## Testing Plan
### Build Verification
- Build `azure-core` as a DLL on Windows (`-DBUILD_SHARED_LIBS=ON`) and verify the resulting `.dll` has a **Details** tab with correct version, company, and description
- Verify the `VS_FF_PRERELEASE` flag is set when building a pre-release version
- Build as a static library and verify no `.rc` file is compiled (no-op path)
### Cross-Platform Verification
- Build on Linux/macOS and verify the version resource logic is completely skipped with no warnings or errors
### Version Accuracy
- Verify the embedded `FileVersion` and `ProductVersion` match the values in `package_version.hpp`
- Verify the `OriginalFilename` matches the actual DLL output name
### CI Integration
- Ensure the existing Windows CI pipelines (`Win2022_Win32Api_debug_tests_winhttp_x86`, etc.) pass with the new `.rc` files
- Add a CI step or test that reads the version resource from a built DLL using `powershell [System.Diagnostics.FileVersionInfo]::GetVersionInfo()` and validates it matches expected values
### Multi-Package Verification
- Build at least 2-3 additional packages (e.g., `azure-identity`, `azure-storage-blobs`) as DLLs and verify each has correct, distinct version resources
Contributor guide
Assessment
This issue has not been assessed yet.