# Building OpenTelemetry C++ SDK with Visual Studio 2019, CMake and Ninja ## Preface These instructions are focused on developers and integrators, providing a hassle-free and FAST option of building OpenTelemetry C++ SDK with Visual Studio on Windows. The process is optimized for both scenarios: - SDK developer experience on developer machine. - final product CI/CD pipeline. ## Build System Components Visual Studio 2019 is a Full-featured integrated development environment (IDE) for Android, iOS, Windows, web, and cloud. There are three editions: - FREE [Community Edition](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=Community&rel=16) - [Professional Edition](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=Professional&rel=16) - [Enterprise Edition](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=Enterprise&rel=16) There is also no-IDE 'headless' set of command line tools available as `Visual Studio 2019 Build Tools` package. You may install it on Windows via [Chocolatey package manager](https://community.chocolatey.org/packages/visualstudio2019buildtools). You may also use Visual Studio with Windows 10 Subsystem for Linux to cross-compile the SDK [targeting Linux distributions](https://code.visualstudio.com/docs/cpp/config-wsl). Linux build process is largely identical to Windows process described below, with `tools/setup-buildtools.sh` and `tools/build.sh` running on Linux. Older versions of Visual Studio, such as 2015 and 2017 are known to work well with CMake and Ninja. However, these old versions are not covered by instructions below. If you would like to contribute additional instructions for older versions, feel free to contribute a Pull Request detailing your build experience with older versions. [CMake](https://cmake.org/) is cross-platform free and open-source software for build automation, testing, packaging and installation of software by using a compiler-independent method. CMake is not a build system but rather it generates another system's build files. [MSBuild](https://docs.microsoft.com/en-us/visualstudio/msbuild/msbuild?view=vs-2019) is a default build system used by Visual Studio for loading and building software projects. [Ninja](https://ninja-build.org/) is a small build system with a focus on speed. It differs from other build systems in two major respects: it is designed to have its input files generated by a higher-level build system, and it is designed to run builds as fast as possible. [Chocolatey package manager](https://chocolatey.org/) has the largest online registry of Windows packages. Chocolatey packages encapsulate everything required to manage a particular piece of software into one deployment artifact by wrapping installers, executables, zips, and/or scripts into a compiled package file. [vcpkg](https://vcpkg.io/en/index.html) is a free C/C++ package manager for acquiring and managing libraries. Choose from over 1500 open source libraries to download and build in a single step or add your own private libraries to simplify your build process. Maintained by the Microsoft C++ team and open source contributors. ## Installing Prerequisites Please install the following software: - Install Visual Studio 2019 with C/C++ development tools, including CMake tools. [This article](https://docs.microsoft.com/en-us/cpp/build/cmake-projects-in-visual-studio?view=msvc-160) explains the fundamentals of working with CMake projects in Visual Studio. - Install [Git tools for Windows](https://git-scm.com/downloads). Setup script below uses Chocolatey to install the following components: - `vswhere` - utility to auto-discover Visual Studio installation. - `cmake` - `git` - `vcpkg` to download, compile and install 3rd party C++ libraries from source. List of C++ dependencies compiled and installed via `vcpkg`: - [Google Test](https://github.com/google/googletest) - [Google Benchmark](https://github.com/google/benchmark) - [Microsoft GSL](https://github.com/microsoft/GSL) - [nlohmann/json](https://github.com/nlohmann/json) - [Abseil](https://github.com/abseil/abseil-cpp) - [Protocol Buffers](https://github.com/protocolbuffers/protobuf) - [gRPC](https://github.com/grpc/grpc) - [Prometheus C++ client](https://github.com/jupp0r/prometheus-cpp) - [cURL](https://github.com/curl/curl) ## Command Line Build Process Start `Command Prompt` as Administrator and execute the following commands: ```console git clone --recursive https://github.com/open-telemetry/opentelemetry-cpp cd opentelemetry-cpp tools\setup-buildtools.cmd tools\build.cmd ``` Let's dissect the flow: ```console git clone --recursive https://github.com/open-telemetry/opentelemetry-cpp ``` SDK will be cloned recursively with remote submodule dependencies. ```console cd opentelemetry-cpp tools\setup-buildtools.cmd ``` The necessary build tools are installed. This step requires elevation to install additional tooling, e.g. CMake to `Program Files`. The necessary dependencies are being built using [vcpkg package manager](https://vcpkg.io/en/index.html). This one-time step is time-consuming - about up to 5-10 minutes. It has to be done once during the initial installation and configuration of build tools and dependencies. ```console tools\build.cmd ``` The build of all SDK components is done using CMake + ninja in less than couple minutes. Above script shows you how to build both configurations: - `nostd` - OpenTelemetry implementation of standard containers. - `stdlib` - Standard Template Library containers. You may execute this workflow in a docker container. Please refer to generic instructions that detail how to [run build build tools in a docker container](https://docs.microsoft.com/en-us/visualstudio/install/build-tools-container?view=vs-2019). ## Building in Visual Studio 2019 IDE - Run as Administrator: `tools\setup-buildtools.cmd` to install the necessary build tooling. This script installs all build tools and builds all 3rd party dependencies from source using [vcpkg package manager](https://vcpkg.io/en/index.html). - Launch Visual Studio 2019 IDE. - Use `Open a local folder` option to open the folder where you cloned the source code. - Right-click on `CMakeLists.txt` and choose `Generate Cache for opentelemetry-cpp`. - In the top bar menu - select `Build -> Build All` to build SDK, Exporters and Tests. - You can use [Google Test Adapter](https://marketplace.visualstudio.com/items?itemName=ChristianSoltenborn.GoogleTestAdapter) Visual Studio extension to run all SDK and Exporter tests in IDE. - You can individually select and run only given tests or examples. Visual Studio provides an excellent debugging and troubleshooting experience, with incremental builds using Ninja typically taking just one click to build and less than a few seconds for the build to complete. ## Build time comparison between `MSBuild` and `Ninja` After the initial set of 3rd party dependencies have been built via `tools\setup-buildtools.cmd`, we can benchmark the OpenTelemetry C++ SDK build times with [MSBuild](https://docs.microsoft.com/en-us/visualstudio/msbuild/msbuild?view=vs-2019) vs with [Ninja](https://ninja-build.org/). [ptime utility](https://community.chocolatey.org/packages/ptime) may be used to measure the total execution time for two build configurations built in one run: `nostd-debug` and `stdlib-debug`. ### MSBuild build timing ```console set CMAKE_GEN=Visual Studio 16 2019 ptime build.cmd ... Execution time: 543.701 s ``` ### Ninja build timing ```console REM Unset CMAKE_GEN= - default is ninja with autodetection of ninja.exe tool path set CMAKE_GEN= ptime build.cmd ... Execution time: 105.158 s ``` ## Conclusion It is strongly recommended to build the SDK with *Ninja* since it is at least x5 times faster than MSBuild for a full clean build. Incremental builds with *Ninja* are also considerably faster. Each incremental build is taking about 10 seconds total for 2 build configurations. Absolute time may differ depending on machine being benchmarked. Relative ratio on most machines demonstrates that building with *Ninja* build system greatly optimizes your development cycle. Not only it saves your development time, optimizes your CI/CD cycle, but it is also much more environmentally friendly.