---
source_path: "api/build-system.md"
canonical_url: "https://doc.sensory.com/tnl/7.8/api/build-system/"
---

# Integrate with your build

This describes how to add the TrulyNatural SDK to your own application's
build system. Supported build systems include [CMake](https://doc.sensory.com/tnl/7.8/api/build-system.md#build-cmake) (recommended),
[Make](https://doc.sensory.com/tnl/7.8/api/build-system.md#build-make), [Java](https://doc.sensory.com/tnl/7.8/api/build-system.md#build-java), [Python](https://doc.sensory.com/tnl/7.8/api/build-system.md#build-python),
[Gradle on Android](https://doc.sensory.com/tnl/7.8/api/build-system.md#build-android), and [Xcode iOS](https://doc.sensory.com/tnl/7.8/api/build-system.md#build-ios).

The paths below assume the default online documentation install location,
_$HOME/Sensory/TrulyNaturalSDK/7.9.0-pre.0_. If you installed the SDK elsewhere, replace that
prefix with your SDK installation directory. Offline SDK documentation uses the
actual installed path.

If you're using a different build system, take a look at the compiler and
linker flags you'll need listed for [Make](https://doc.sensory.com/tnl/7.8/api/build-system.md#build-make).

Optional C/C++ preprocessor flags such as `-DSNSR_USE_SUBSET` and
`-DSNSR_OMIT_OSS_COMPONENTS` are documented on [Compile-time macros](https://doc.sensory.com/tnl/7.8/api/compile-macros.md#compile-time-macros).

## CMake
- recommended

Add this to your _CMakeLists.txt_ files:

```cmake
list(APPEND CMAKE_MODULE_PATH "$ENV{HOME}/Sensory/TrulyNaturalSDK/7.9.0-pre.0")
include(SnsrLibrary)
```

and to each of your executable targets:

```cmake
target_link_libraries(your-target SnsrLibrary)
```

If you do not want to include any OSS components
(and therefore no STT support) use `SnsrLibraryOmitOSS` instead:

```cmake
target_link_libraries(your-target SnsrLibraryOmitOSS)
```

**Also see these related items:** [CMakeLists.txt](https://doc.sensory.com/tnl/7.8/api/sample/c/index.md#cmakeliststxt) in the [C examples](https://doc.sensory.com/tnl/7.8/api/sample/c/index.md#c-examples) section.

## Make

Set the compiler and linker flags to allow your toolchain to find the `<snsr.h>`
header and the platform-specific `libsnsr.a`.

**Also see these related items:** [Makefile](https://doc.sensory.com/tnl/7.8/api/sample/c/index.md#makefile) in the [C examples](https://doc.sensory.com/tnl/7.8/api/sample/c/index.md#c-examples) section.

### Linux

```make
SNSR_ROOT ?= $(HOME)/Sensory/TrulyNaturalSDK/7.9.0-pre.0
CFLAGS  += -I$(SNSR_ROOT)/include
LDFLAGS += -L$(SNSR_ROOT)/lib/<platform>
LDLIBS  += -lsnsr -lasound -lpthread -lm -ldl -lstdc++
```

Where `<platform>` should be the output of `gcc -dumpmachine`

_(STT only)_ `-lstdc++` is needed for the TrulyNatural STT SDK only.

### macOS

```make
SNSR_ROOT ?= $(HOME)/Sensory/TrulyNaturalSDK/7.9.0-pre.0
CFLAGS  += -I$(SNSR_ROOT)/include
LDFLAGS += -L$(SNSR_ROOT)/lib/macos
LDLIBS  += -lsnsr -framework AudioToolbox -framework Accelerate \
           -framework CoreFoundation -framework Foundation -lm -lstdc++
```

_(STT only)_ `-lstdc++` is needed for the TrulyNatural STT SDK only.

### Windows

Use Visual Studio 2022 or later.

```make
SNSR_ROOT ?= $(HOME)/Sensory/TrulyNaturalSDK/7.9.0-pre.0
CFLAGS  += -I$(SNSR_ROOT)/include
LDFLAGS += -L$(SNSR_ROOT)/lib/x86_64-windows-msvc
LDLIBS  += snsr.lib winmm.lib user32.lib
```

## Java

The Java binding uses JNI to load the native library. Use the Sensory JAR from
the SDK Maven repository at _$HOME/Sensory/TrulyNaturalSDK/7.9.0-pre.0/m2repository_ plus a native
library search path (`java.library.path`) pointing at
_$HOME/Sensory/TrulyNaturalSDK/7.9.0-pre.0/lib/<platform>_ (for example
_$HOME/Sensory/TrulyNaturalSDK/7.9.0-pre.0/lib/macos_ on macOS).

Maven coordinates (desktop JAR, not the Android `@aar`):

```gradle
implementation "com.sensory.speech.snsr:tnl:7.9.0-pre.0"
```

On Linux, set `<platform>` to the output of `gcc -dumpmachine`. On macOS use
`macos`. On Windows use the MSVC library directory under
_$HOME/Sensory/TrulyNaturalSDK/7.9.0-pre.0/lib_ (for example `x86_64-windows-msvc`).

For Gradle, derive the SDK root from the Maven repository directory (its parent
is the SDK install directory) and pass the native library directory to the `run`
task (see [Your first program](https://doc.sensory.com/tnl/7.8/getting-started/your-first-program.md#your-first-program)).

**Also see these related items:** [Java examples](https://doc.sensory.com/tnl/7.8/api/sample/java/index.md#java-examples).

## Python

The [Python][] binding ships as a platform-specific wheel in the SDK installer.
It is **not** published to PyPI. Each wheel bundles the native `snsr` shared
library and a ctypes wrapper (`snsr.Session`, `snsr.Stream`, setting-key
constants, and enums).

Wheels for supported platforms are at _$HOME/Sensory/TrulyNaturalSDK/7.9.0-pre.0/lib/python/_.
Install the wheel whose platform tag matches your host; `pip` and [uv][] refuse
to install a mismatched tag.

| Architecture | Wheel |
|---|---|
| `darwin` | `snsr-7.9.0a0-py3-none-macosx_11_0_universal2.whl` |
| `x86_64-linux` | `snsr-7.9.0a0-py3-none-manylinux_2_27_x86_64.whl` |
| `aarch64-linux` | `snsr-7.9.0a0-py3-none-manylinux_2_33_aarch64.whl` |
| `x86_64-windows` | `snsr-7.9.0a0-py3-none-win_amd64.whl` |

Requires [Python][] 3.10 or later. On Python 3.10 the wheel depends on
`typing-extensions`; Python 3.11 and later do not need that extra package.

### Add `snsr` with uv

[uv][] is the recommended way to resolve the wheel from your project directory.
Point a flat index at the SDK wheel directory and pin the package version to the
PEP 440 string on the wheel filename:
`snsr==7.9.0a0`.

Add to _pyproject.toml_:

```toml
[project]
name = "your-app"
version = "0.1.0"
requires-python = ">=3.10"
dependencies = [
    "snsr==7.9.0a0",
]

[[tool.uv.index]]
name = "snsr-local"
url = "../../lib/python"
explicit = true
format = "flat"

[tool.uv.sources]
snsr = { index = "snsr-local" }
```

The `url` above is correct when your project sits at
_~/Sensory/TrulyNaturalSDK/7.9.0-pre.0/sample/python/_ (same relative path as the shipped samples).
For a project elsewhere, set `url` to the absolute path of
_$HOME/Sensory/TrulyNaturalSDK/7.9.0-pre.0/lib/python_ on your machine. uv reads TOML literally:
it does not expand `~`, `$HOME`, or environment variables in `url`.

Then create a virtual environment and install:

```console
uv venv
uv sync
```

### Add `snsr` with pip

Install the platform wheel directly:

```console
pip install $HOME/Sensory/TrulyNaturalSDK/7.9.0-pre.0/lib/python/snsr-7.9.0a0-py3-none-macosx_11_0_universal2.whl
```

The command above installs the `darwin` wheel (macOS). Use the wheel basename for
your architecture from the table; to list all files, run `ls`
_$HOME/Sensory/TrulyNaturalSDK/7.9.0-pre.0/lib/python/_.

### Version strings

The wheel and `pip`/`uv` use a [PEP 440][] version (for example `7.8.0a1` for a
`7.8.0-pre.1` SDK release). After import, `importlib.metadata.version("snsr")`
returns that form.

The module constant [VERSION](https://doc.sensory.com/tnl/7.8/api/constants.md#version) on the [Constants](https://doc.sensory.com/tnl/7.8/api/constants.md#constants) page carries the same raw
string as the C `SNSR_VERSION` macro (`7.8.0-pre.1+…`). Both refer to the same
SDK build; only the spelling differs.

Runnable sample projects that use this layout are at _~/Sensory/TrulyNaturalSDK/7.9.0-pre.0/sample/python/_.

## Android

The Android library ships as an `@aar` in the SDK's Maven repository.
The snippets below are shown in both Groovy DSL (`settings.gradle`,
`app/build.gradle`) and Kotlin DSL (`settings.gradle.kts`,
`app/build.gradle.kts`); pick whichever matches your project.
The same `@aar` and APIs work unchanged from Java or [Kotlin][] (see
[API overview § Kotlin on Android](https://doc.sensory.com/tnl/7.8/api/overview.md#kotlin-on-android)).

*   If using live audio recording, add the `RECORD_AUDIO` [permission][] to
    the application's _AndroidManifest.xml_ file:

    ```xml
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    ```

*   Add to _settings.gradle_ (Groovy DSL) or _settings.gradle.kts_ (Kotlin DSL):

<!-- tab: groovy -->

**Groovy**

    _settings.gradle_:

    ```gradle
    def snsrRepository = providers.gradleProperty("SNSR_REPOSITORY").get()
    def snsrRepositoryFile = file(snsrRepository)
    if (!snsrRepositoryFile.isAbsolute()) {
        snsrRepositoryFile = file("${System.getProperty('user.home')}/${snsrRepository}")
    }

    dependencyResolutionManagement {
        repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
        repositories {
            google()
            mavenCentral()
            maven { url = snsrRepositoryFile.toURI() }
            mavenLocal()
        }
    }
    ```

<!-- /tab -->

<!-- tab: kotlin-dsl -->

**Kotlin DSL**

    _settings.gradle.kts_:

    ```kotlin
    val snsrRepository: String = providers.gradleProperty("SNSR_REPOSITORY").get()
    var snsrRepositoryFile = file(snsrRepository)
    if (!snsrRepositoryFile.isAbsolute) {
        snsrRepositoryFile = file("${System.getProperty("user.home")}/$snsrRepository")
    }

    dependencyResolutionManagement {
        repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
        repositories {
            google()
            mavenCentral()
            maven { url = snsrRepositoryFile.toURI() }
            mavenLocal()
        }
    }
    ```

<!-- /tab -->

*   Add to _app/build.gradle_ (Groovy DSL) or _app/build.gradle.kts_ (Kotlin DSL):

<!-- tab: groovy -->

**Groovy**

    _app/build.gradle_:

    ```gradle
    /// snsr model utilities
    apply from: '../gradle/model-utils.gradle'

    configurations {
        snsr_model
    }

    dependencies {
      // TrulyNatural code library
      implementation "com.sensory.speech.snsr:${SNSR_LIB_TYPE}:${SNSR_LIB_VERSION}@aar"

      // Any `snsr` task models needed by your app in Maven GAV format, for example
      snsr_model "com.sensory.speech.snsr.model:udt-universal:3.67.1.0@snsr"
    }
    ```

<!-- /tab -->

<!-- tab: kotlin-dsl -->

**Kotlin DSL**

    _app/build.gradle.kts_:

    ```kotlin
    // snsr model utilities (model-utils.gradle stays Groovy; apply from
    // works unchanged in Kotlin DSL projects).
    apply(from = "../gradle/model-utils.gradle")

    val snsrLibType: String by project
    val snsrLibVersion: String by project

    val snsr_model: Configuration by configurations.creating

    dependencies {
        // TrulyNatural code library
        implementation("com.sensory.speech.snsr:$snsrLibType:$snsrLibVersion@aar")

        // Any `snsr` task models needed by your app in Maven GAV format, for example
        snsr_model("com.sensory.speech.snsr.model:udt-universal:3.67.1.0@snsr")
    }
    ```

<!-- /tab -->

*   Copy _util/model-utils.gradle_ from the TrulyNatural installation directory
    to _gradle/model-utils.gradle_ in your application. The file stays in
    Groovy syntax even for Kotlin DSL projects; Gradle's `apply from:`
    handles the cross-DSL apply transparently.

*    Add configuration settings to _gradle.properties_ (file format is
     identical for both DSLs):

    ```gradle
    # Sensory TrulyNatural configuration
    # Relative to the user's home directory; use an absolute path for custom installs.
    SNSR_REPOSITORY=Sensory/TrulyNaturalSDK/7.9.0-pre.0/m2repository
    SNSR_LIB_TYPE=tnl
    SNSR_LIB_VERSION=7.9.0-pre.0
    ```

**Also see these related items:** [Android examples](https://doc.sensory.com/tnl/7.8/api/sample/android/index.md#android-examples).

## iOS

- Add a Bridging header, _ProjectName-Bridging-Header.h_, that includes
  `#!swift #import <snsr.h>`
- Select the application target.
    - In "Capabilities", add "Inter-App Audio Capability".
    - In "Info" > "Custom iOS Target Properties", add
      an `NSMicrophoneUsageDescription` string.
    - In "Build Settings",
        - Add `${SNSR_ROOT}/include` to the "Header Search Paths".
        - Add `${SNSR_ROOT}/lib/ios` to the "Library Search Paths".
        - Add `-lsnsr` to "Other Linker Flags".
    - In "General" > "Frameworks, Libraries, and Embedded Content",
        - Add `Accelerate.framework`
        - Add `AudioToolbox.framework`
- Select the project.
    - Select the "Editor > Add Build Setting > Add User-Defined Setting" menu
      entry.
    - Add `SNSR_ROOT`. Set this variable to the TrulyNatural SDK installation
      directory, _$(HOME)/Sensory/TrulyNaturalSDK/7.9.0-pre.0_

**Also see these related items:** [iOS examples](https://doc.sensory.com/tnl/7.8/api/sample/ios/index.md#ios-examples).

<!-- Reference definitions from includes/links.md -->
[Kotlin]: https://kotlinlang.org/ "Kotlin programming language"
[PEP 440]: https://packaging.python.org/en/latest/specifications/version-specifiers/ "Python version identification and dependency specification"
[permission]: https://developer.android.com/guide/topics/security/permissions.html "Permissions on Android"
[Python]: https://en.wikipedia.org/wiki/Python_(programming_language) "Python programming language"
[uv]: https://docs.astral.sh/uv/ "uv Python package and project manager"

<!-- Abbreviation definitions from includes/abbreviations.md -->
*[API]: Application Programming Interface
*[OSS]: Open-source software
*[SDK]: Software Development Kit
*[STT]: Speech To Text: transformers with language model and CTC decoding
*[TNL]: TrulyNatural, Sensory's large-vocabulary speech recognition technology
*[UDT]: User-Defined Trigger: enrolled wake words and command sets
