# How to Integrate VMAware into an Existing C++ Project as a Header-Only Library

>  Easily integrate VMAware into your C++ project as a header-only library. Simply copy the header file, compile with C++11 or newer, and use the static API for VM detection and branding. No linking required.

- Repository: [Louis/vmaware](https://github.com/kernelwernel/vmaware)
- Tags: how-to-guide
- Published: 2026-03-05

---

**To integrate VMAware as a header-only library, copy [`src/vmaware.hpp`](https://github.com/kernelwernel/vmaware/blob/main/src/vmaware.hpp) into your project, ensure you are compiling with C++11 or newer, and call the static API functions such as `VM::detect()` and `VM::brand()` without any linking steps.**

VMAware is a modern, header-only C++ library for virtual machine detection that requires no external dependencies or separate compilation. According to the kernelwernel/vmaware source code, the entire implementation resides in a single public header file located at [`src/vmaware.hpp`](https://github.com/kernelwernel/vmaware/blob/main/src/vmaware.hpp), making integration into existing codebases straightforward. This guide explains exactly how to add VMAware to your project and use its static API to detect virtualized environments.

## Step 1: Add the Header to Your Project

VMAware distributes its functionality through a single public header. You have three primary methods to incorporate it into your build.

### Option A: Copy the Header File

Copy [`src/vmaware.hpp`](https://github.com/kernelwernel/vmaware/blob/main/src/vmaware.hpp) from the repository into your project's source tree:

```text
myproject/
 ├─ src/
 │   └─ vmaware.hpp   ← copy from kernelwernel/vmaware repo
 └─ CMakeLists.txt

```

### Option B: Add the Repository as a Subdirectory

Clone the repository into an external directory without copying individual files:

```text
myproject/
 ├─ external/
 │   └─ vmaware/       ← clone the repository here
 └─ CMakeLists.txt

```

### Option C: Configure Include Paths

Add the repository's `src/` directory to your compiler's include path without moving files.

**For CMake:**

```cmake
target_include_directories(my_target PRIVATE "${CMAKE_SOURCE_DIR}/external/vmaware/src")

```

**For GCC or Clang:**

```bash
g++ -Iexternal/vmaware/src -std=c++20 main.cpp -o myapp

```

**For Visual Studio:**

Navigate to **Project → Properties → C/C++ → General → Additional Include Directories** and add `$(ProjectDir)external\vmaware\src`.

## Step 2: Enable C++11 or Newer

VMAware requires at least **C++11** to compile. The header detects the compiler version using the `VMA_CPLUSPLUS` macro and aborts compilation for older language standards.

Configure your build system with the appropriate compiler flags:

- **CMake**: `target_compile_features(my_target PUBLIC cxx_std_11)` (or `cxx_std_17`, `cxx_std_20`)
- **GCC/Clang**: `-std=c++11`, `-std=c++17`, or `-std=c++20`
- **Visual Studio**: `/std:c++14`, `/std:c++17`, or `/std:c++20`

## Step 3: Include the Header and Use the Static API

Include the header in your translation units. The header guards (`#ifndef VMAWARE_HEADER`) prevent multiple inclusion issues.

```cpp
#include "vmaware.hpp"

```

The library exposes a completely static API through the `VM` namespace. No objects require construction or destruction, and no initialization functions need calling.

**Core detection functions:**

- **`VM::detect()`**: Returns `true` if a virtual machine is detected
- **`VM::brand()`**: Returns a `std::string` identifier (e.g., `"VirtualBox"`, `"VMware"`)
- **`VM::type()`**: Returns the enumerated brand type as `VM::brand_enum`
- **`VM::percentage()`**: Returns a certainty score from 0-100
- **`VM::add_custom()`**: Registers user-defined detection techniques

## Complete Integration Example

Below is a minimal example demonstrating full integration with CMake.

**main.cpp:**

```cpp
#include <iostream>
#include "vmaware.hpp"

int main() {
    if (VM::detect()) {
        std::cout << "Virtual machine detected!\n";
    } else {
        std::cout << "Running on bare metal.\n";
    }

    std::cout << "VM brand:   " << VM::brand() << '\n';
    std::cout << "VM type:    " << static_cast<int>(VM::type()) << '\n';
    std::cout << "Confidence: " << static_cast<int>(VM::percentage()) << "%\n";

    return 0;
}

```

**CMakeLists.txt:**

```cmake
cmake_minimum_required(VERSION 3.14)
project(VMAwareDemo CXX)

add_executable(${PROJECT_NAME} main.cpp)

# Add VMAware include directory

target_include_directories(${PROJECT_NAME} PRIVATE 
    "${CMAKE_CURRENT_SOURCE_DIR}/external/vmaware/src"
)

# Require at least C++11 (using C++20 here for modern features)

target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_20)

```

No linking against external libraries is required because all implementation details reside within the header.

## Key Source Files for Reference

When working with the VMAware codebase, these files provide authoritative implementation details:

- **[`src/vmaware.hpp`](https://github.com/kernelwernel/vmaware/blob/main/src/vmaware.hpp)**: Contains the complete header-only implementation, all detection logic, and the public API
- **[`src/cli.cpp`](https://github.com/kernelwernel/vmaware/blob/main/src/cli.cpp)**: Optional command-line interface demonstrating practical usage patterns
- **[`docs/documentation.md`](https://github.com/kernelwernel/vmaware/blob/main/docs/documentation.md)**: Detailed technical documentation covering detection techniques and API specifics
- **[`CMakeLists.txt`](https://github.com/kernelwernel/vmaware/blob/main/CMakeLists.txt)**: Example build configuration showing proper include directory setup

## Summary

- VMAware is distributed as a single header file [`src/vmaware.hpp`](https://github.com/kernelwernel/vmaware/blob/main/src/vmaware.hpp) with no external dependencies
- Integration requires only adding the header to your include path and compiling with C++11 or newer
- The API is entirely static—call `VM::detect()`, `VM::brand()`, and other functions without instantiating objects or linking libraries
- Detection functions return boolean results, string identifiers, enumerated types, and confidence percentages

## Frequently Asked Questions

### Does VMAware require any external libraries or runtime dependencies?

No. As implemented in [`src/vmaware.hpp`](https://github.com/kernelwernel/vmaware/blob/main/src/vmaware.hpp), VMAware is completely self-contained and header-only. The library uses only standard C++ library features and system APIs available on the target platform. No dynamic linking, static linking, or package manager dependencies are necessary.

### What is the minimum C++ standard required to compile VMAware?

VMAware requires **C++11** or newer. The header actively checks the `VMA_CPLUSPLUS` macro value and will produce a compilation error if used with C++98 or C++03. While C++11 is the minimum, using C++17 or C++20 provides access to additional language features that may improve detection reliability on modern compilers.

### Can I extend VMAware with custom detection techniques?

Yes. The `VM::add_custom()` static function allows registration of user-defined detection techniques. Pass your custom detection function and a weight value to integrate proprietary checks alongside the built-in VM detection heuristics without modifying the library source code in [`src/vmaware.hpp`](https://github.com/kernelwernel/vmaware/blob/main/src/vmaware.hpp).

### How do I verify the header is properly integrated without writing test code?

Compile the included CLI tool located in [`src/cli.cpp`](https://github.com/kernelwernel/vmaware/blob/main/src/cli.cpp) as a smoke test. This file provides a ready-made executable that exercises the full API including `VM::detect()` and `VM::brand()`. If this compiles and runs correctly using your include paths and compiler flags, your project integration is configured correctly.