---
title: Add ClikaRT to an existing CMake project
description: Link the bundle into a project that already builds, with find_package or add_subdirectory, and the one linker flag serving-runtime consumers need.
---

Your application already builds, and you want it to call ClikaRT. The integration is two lines in the CMake file you already have: declare the package, link one target. This guide adds ClikaRT to an existing app both ways (the prebuilt bundle via `find_package`, the bundle source tree via `add_subdirectory`), then covers the two things integrations trip on: where the libraries are found at run time, and the RTTI flag the serving runtime requires.

ClikaRT needs C++17 or later; if your project predates `set(CMAKE_CXX_STANDARD 17)`, add it.

## Link the bundle with find_package

Say the existing project is a telemetry service with one executable:

```cmake title="CMakeLists.txt (before)"
cmake_minimum_required(VERSION 3.19)
project(telemetry CXX)
set(CMAKE_CXX_STANDARD 17)

add_executable(telemetry src/main.cpp src/collect.cpp)
```

Two lines make ClikaRT available to it. `find_package(ClikaRT CONFIG)` loads the package from the extracted bundle, and the imported target `ClikaRT::ClikaRT` carries the include paths, the libraries, and their link order:

```cmake title="CMakeLists.txt (after)"
cmake_minimum_required(VERSION 3.19)
project(telemetry CXX)
set(CMAKE_CXX_STANDARD 17)

find_package(ClikaRT CONFIG REQUIRED)

add_executable(telemetry src/main.cpp src/collect.cpp)
target_link_libraries(telemetry PRIVATE ClikaRT::ClikaRT)
```

CMake finds the package through `ClikaRT_DIR`, pointing at the bundle's `cmake/` directory:

```bash
cmake -S . -B build -DClikaRT_DIR="$CLIKART_BUNDLE_DIR/cmake"
cmake --build build
```

`-DClikaRT_DIR` is a cache variable, so it is remembered after the first configure. To avoid passing it at all, add the bundle to `CMAKE_PREFIX_PATH` (in a toolchain file, a CMake preset, or the environment) and `find_package` finds it there. A wrong or unset path fails the configure with `Could not find a package configuration file provided by "ClikaRT"`; the fix is always the same, point `ClikaRT_DIR` at `<bundle>/cmake`.

## Where the libraries are found at run time

The package stamps each consumer binary with an rpath to the bundle's platform `lib/` directory, so a freshly built binary runs in place with no library paths to set, `LD_LIBRARY_PATH` included. That rpath names the bundle's absolute path on the build machine. For binaries that ship to other machines, copy the libraries your binary needs from the bundle's `lib/` next to it (or into your package's lib directory) and set your own relative rpath, for example `$ORIGIN/../lib`; the bundle's prebuilt examples ship exactly that way.

## Serving-runtime consumers mirror the library's -fno-rtti

Code that only uses tensors, `ops::`, `io::`, tokenizers, or the HTTP pieces builds with your project's existing flags. Code that uses the serving runtime (`runtime::FunctionModel`, `runtime::Model`, the executor) must be compiled with `-fno-rtti`, matching how the library builds. With RTTI left on, the target fails at link with:

```text
undefined reference to `typeinfo for ClikaRT::runtime::Model'
```

Scope the flag to the targets that touch `runtime::`:

```cmake
target_compile_options(telemetry PRIVATE -fno-rtti)
```

The bundle's own examples set the same flag; it is the one compile-option requirement in the integration.

## Check the bundle into your tree with add_subdirectory

For a monorepo that keeps the bundle in the repository (or fetches it into the tree), the bundle root is also a CMake subproject. It defines the same `ClikaRT::ClikaRT` target with the same options, so consumers cannot tell the difference:

```cmake
add_subdirectory(third_party/clikart)

add_executable(telemetry src/main.cpp src/collect.cpp)
target_link_libraries(telemetry PRIVATE ClikaRT::ClikaRT)
```

No `ClikaRT_DIR` and no configure-time flag are involved; the path in the tree is the whole wiring. Prefer `find_package` when the bundle lives outside the repository (a shared install, a CI cache), `add_subdirectory` when it lives inside.

## Verify

A two-line call in your existing code proves the link end to end:

```cpp title="src/main.cpp (excerpt as a standalone check)"
#include <cstdio>

#include "ClikaRT/clika_rt.h"

int main() {
    std::printf("ClikaRT %s\n", ClikaRT::GetVersionInfo().c_str());
    std::printf("cuda=%d vulkan=%d\n",
                ClikaRT::device::is_cuda_available(), ClikaRT::device::is_vulkan_available());
    return 0;
}
```

```text
ClikaRT 0.6.4
cuda=1 vulkan=1
```

The availability flags reflect the machine, not the build: the same binary prints different backends on different hardware, which is the point. From here, [the tutorial](../getting-started/first-program/01-your-first-program.mdx) covers the API the newly linked target now reaches, and [Quick install](../getting-started/installation.md) has the bundle layout.
