---
sidebar_position: 0
sidebar_label: TinyORM
hide_table_of_contents: true
description: How to compile the TinyORM C++ library on Windows and Linux.
keywords: [c++ orm, building, tinyorm]
---

import APITable from '@theme/APITable'
import CodeBlock from '@theme/CodeBlock'
import TabItem from '@theme/TabItem'
import Tabs from '@theme/Tabs'

import RootFolder from '@theme/RootFolder'
import RootFolderInput from '@theme/RootFolderInput'
import {
    shell,
    application, bash, pwsh,
    application_label, bash_label, pwsh_label
} from '@theme/constants'
import {
    applicationFolder,
    applicationFolderPath,
    convertToCmakeEnvVariable,
    rootFolderPath
} from '@theme/utils/rootFolderUtils'

# Building: TinyORM

- [Introduction](#introduction)
    - [Common Prerequisites](#common-prerequisites)
    - [Windows Prerequisites](#windows-prerequisites)
- [Folders structure](#folders-structure)
- [Getting started](#getting-started)
- [vcpkg](#vcpkg)
- [C preprocessor macros](#c-preprocessor-macros)
- [Building with CMake](#building-with-cmake)
    - [Configure & Build](#configure-and-build-cmake)
    - [CMake build options](#cmake-build-options)
    - [Consume TinyOrm library](#consume-tinyorm-library-cmake)
- [Building with qmake](#building-with-qmake)
    - [Install dependencies](#install-dependencies)
    - [Configure & Build](#configure-and-build-qmake)
    - [qmake build options](#qmake-build-options)
    - [Consume TinyOrm library](#consume-tinyorm-library-qmake)
    - [Auto-configuration internals](#auto-configuration-internals)
      - [Environment files](#environment-files)
    - [Manual configuration internals](#manual-configuration-internals)
- [Ccache support](#ccache-support)

## Introduction

The build systems supported out of the box are `CMake` and `qmake`.

:::caution
All examples below assume that `pwsh` runs on `Windows` and `bash` runs on `Linux`.
:::

#### Common Prerequisites

Install the required [dependencies](dependencies.mdx) before starting.

#### Windows Prerequisites

##### Build environment scripts

The `Visual Studio` does not provide `vcvars` scripts for `pwsh`, you can use [`vcvars64.ps1`](https://github.com/silverqx/TinyORM/tree/main/tools/vcvars64.ps1) provided by `TinyORM` in the `tools/` folder. Place them on the `$env:Path` user/system path and they will be available system-wide.

The same is true for the `Qt Framework`, it doesn't provide `qtenv` scripts for `pwsh` too. You can create your own script, place it on the `$env:Path` user/system path and it will be available system-wide.

Here is one simple example for `pwsh`.

<Tabs groupId={shell}>
<TabItem value='qtenv6.ps1' label='qtenv6.ps1'>

```powershell
Write-Host 'Setting up environment for Qt 6.5.3 usage...' -ForegroundColor Magenta
$env:Path = 'C:\Qt\6.5.3\msvc2019_64\bin;' + $env:Path
. E:\dotfiles\bin\vcvars64.ps1
```

</TabItem>
<TabItem value='qtenv5.ps1' label='qtenv5.ps1'>

```powershell
Write-Host 'Setting up environment for Qt 5.15.2 usage...' -ForegroundColor Magenta
$env:Path = 'C:\Qt\5.15.2\msvc2019_64\bin;' + $env:Path
. E:\dotfiles\bin\vcvars64.ps1
```

</TabItem>
</Tabs>

And here for Linux:


<Tabs groupId={shell}>
<TabItem value='qtenv6' label='qtenv6'>

```bash
echo 'Setting up environment for Qt 6.5.3 usage...'

export PATH=/opt/Qt/6.5.3/gcc_64/bin${PATH:+:}$PATH
export LD_LIBRARY_PATH=/opt/Qt/6.5.3/gcc_64/lib${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH
```

</TabItem>
<TabItem value='qtenv5' label='qtenv5'>

```bash
echo 'Setting up environment for Qt 5.15.2 usage...'

export PATH=/opt/Qt/5.15.2/gcc_64/bin${PATH:+:}$PATH
export LD_LIBRARY_PATH=/opt/Qt/5.15.2/gcc_64/lib${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH
```

</TabItem>
</Tabs>

##### Allow symbolic links unprivileged

Open `Local Security Policy`, go to `Local Policies - User Rights Assignment`, open `Create symbolic links` and add your user account or user group, restart when it doesn't apply immediately.

## Folders structure

All `tinyorm.org` examples are based on the following folders structure. The `tom` folder will contain a [migrations console application](building/migrations.mdx).

:::tip
You can set the root and application folder paths in the form below and they will be used across the whole www.tinyorm.org website. 🥳 The pwsh shell is supposed to use on Windows and the bash shell on Linux, but it is not a requirement.
:::

<Tabs groupId={shell}>
<TabItem value={pwsh} label={pwsh_label} className='tiny-tree'>
<div className='tiny-root-folder-info-wrapper'>
    <span className='tiny-root-folder-info-prefix'>Current pwsh path</span>&nbsp;
    <RootFolder groupId={pwsh} />
</div>
<RootFolderInput groupId={pwsh} label={pwsh_label} />
<RootFolderInput groupId={application} label={application_label} />

```text



├──
│   ├── HelloWorld/
│   |   ├── HelloWorld/
│   |   ├── HelloWorld-builds-cmake/
│   |   |   └── build-debug/
│   |   └── HelloWorld-builds-qmake/
│   |       └── build-debug/
│   ├── TinyORM/
│   |   ├── TinyORM/
│   |   ├── TinyORM-builds-cmake/
│   |   │   ├── build-gcc-debug/
│   |   │   ├── build-gcc-release/
│   |   │   └── build-clang-debug/
│   |   └── TinyORM-builds-qmake/
│   |       ├── build-debug/
│   |       ├── build-TinyORM-Desktop_Qt_5_15_2_MSVC2019_64bit-Debug/
│   |       └── build-TinyORM-Desktop_Qt_5_15_2_MSYS2_UCRT64_64bit-Release/
│   └── tom/
│       ├── tom/
│       │   └── database/
│       │       ├── migrations/
│       │       ├── seeders/
│       │       ├── migrations.pri
│       │       └── seeders.pri
│       ├── tom-builds-cmake/
│       │   └── build-TinyORM-Desktop_Qt_6_5_3_MSVC2019_64bit-Debug/
│       └── tom-builds-qmake/
│           ├── build-TinyORM-Desktop_Qt_5_15_3_MSYS2_UCRT64_64bit-Release/
│           └── build-TinyORM-Desktop_Qt_6_5_3_MSVC2019_64bit-Debug/
├── tmp/
└── vcpkg/
```

</TabItem>
<TabItem value={bash} label={bash_label} className='tiny-tree'>
<div className='tiny-root-folder-info-wrapper'>
    <span className='tiny-root-folder-info-prefix'>Current bash path</span>&nbsp;
    <RootFolder groupId={bash} />
</div>
<RootFolderInput groupId={bash} label={bash_label} />
<RootFolderInput groupId={application} label={application} />

```text



├──
│   ├── HelloWorld/
│   |   ├── HelloWorld/
│   |   ├── HelloWorld-builds-cmake/
│   |   |   └── build-debug/
│   |   └── HelloWorld-builds-qmake/
│   |       └── build-debug/
│   ├── TinyORM/
│   |   ├── TinyORM/
│   |   ├── TinyORM-builds-cmake/
│   |   │   ├── build-gcc-debug/
│   |   │   ├── build-gcc-release/
│   |   │   └── build-clang-debug/
│   |   └── TinyORM-builds-qmake/
│   |       ├── build-debug/
│   |       ├── build-TinyORM-Desktop_Qt_5_15_2_GCC_64bit-Debug/
│   |       └── build-TinyORM-Desktop_Qt_5_15_2_clang13_64bit_ccache-Release/
│   └── tom/
│       ├── tom/
│       │   └── database/
│       │       ├── migrations/
│       │       ├── seeders/
│       │       ├── migrations.pri
│       │       └── seeders.pri
│       ├── tom-builds-cmake/
│       │   └── build-TinyORM-Desktop_Qt_6_5_3_clang14_64bit_ccache-Debug/
│       └── tom-builds-qmake/
│           ├── build-TinyORM-Desktop_Qt_6_5_3_GCC_64bit-Debug/
│           └── build-TinyORM-Desktop_Qt_6_5_3_clang14_64bit_ccache-Release/
├── tmp/
└── vcpkg/
```

</TabItem>
</Tabs>

:::danger
Avoid paths with spaces with the `qmake` build system, it will not compile.
:::

<a id='qtcreator-default-build-directory' />

:::tip
You can force the `QtCreator` to generate a build folders structure as is described above.

To generate the required folders structure set the `Settings` - `Build & Run` - `Default Build Properties` - `Default build directory` to:<br/>
`../%{Project:Name}-builds-%{BuildSystem:Name}/%{JS: Util.asciify("build-%{Project:Name}-%{Kit:FileSystemName}-%{BuildConfig:Name}")}`
:::

## Getting started

Prepare compilation environment, we need to put the Qt Framework and Visual Studio MSVC compiler on the path on Windows. The compiler is already on the path on Linux and you can export `PATH` and `LD_LIBRARY_PATH` for Qt Framework, or use our `qtenvX` scripts described above.

<Tabs groupId={shell}>
<TabItem value={pwsh} label={pwsh_label}>
<CodeBlock className='language-powershell'>
{`mkdir ${rootFolderPath(pwsh)}
cd ${rootFolderPath(pwsh)}
$env:Path = 'C:\\Qt\\6.5.3\\msvc2019_64\\bin;' + $env:Path
vcvars64.ps1`}
</CodeBlock>
</TabItem>
<TabItem value={bash} label={bash_label}>
<CodeBlock className='language-bash'>
{`mkdir -p ${rootFolderPath(bash)}
cd ${rootFolderPath(bash)}
export PATH=/opt/Qt/6.5.3/gcc_64/bin$\{PATH:+:\}$PATH
export LD_LIBRARY_PATH=/opt/Qt/6.5.3/gcc_64/lib$\{LD_LIBRARY_PATH:+:\}$LD_LIBRARY_PATH`}
</CodeBlock>
</TabItem>
</Tabs>

:::tip
You can also use the [`tools/Add-FolderOnPath.ps1`](https://github.com/silverqx/TinyORM/blob/main/tools/Add-FolderOnPath.ps1) pwsh script to fastly prepend a path or <abbr title='Current working directory'>pwd</abbr> on the system `PATH`.
:::

## vcpkg

Installing the `vcpkg` is highly recommended, it simplifies installation of the `range-v3` and `tabulate` dependencies.

<Tabs groupId={shell}>
<TabItem value={pwsh} label={pwsh_label}>

```powershell
git clone git@github.com:microsoft/vcpkg.git
cd vcpkg
.\bootstrap-vcpkg.bat
```

</TabItem>
<TabItem value={bash} label={bash_label}>

```bash
git clone git@github.com:microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
```

</TabItem>
</Tabs>

Add `vcpkg` on the system path, add the following to the `.bashrc` or `.zshrc` on Linux.

<CodeBlock className='language-bash'>
{`export PATH=${rootFolderPath(bash)}/vcpkg\${PATH:+:}$PATH`}
</CodeBlock>

On Windows, open the `Environment variables` dialog and add `vcpkg` on the user `PATH`.

Or you can export it for the current session only.

<Tabs groupId={shell}>
<TabItem value={pwsh} label={pwsh_label}>
<CodeBlock className='language-powershell'>
{`$env:Path = "${rootFolderPath(pwsh, false)}\\vcpkg;" + $env:Path`}
</CodeBlock>
</TabItem>
<TabItem value={bash} label={bash_label}>
<CodeBlock className='language-bash'>
{`export PATH=${rootFolderPath(bash)}/vcpkg\${PATH:+:}$PATH`}
</CodeBlock>
</TabItem>
</Tabs>

#### Set up `vcpkg` environment

To export `vcpkg` environment variables globally, add it to the `.bashrc` or `.zshrc` on Linux, and you can use the `Environment variables` dialog on Windows.

```bash title='Linux'
export VCPKG_DEFAULT_TRIPLET=x64-linux
#export VCPKG_DEFAULT_HOST_TRIPLET=x64-linux
export VCPKG_MAX_CONCURRENCY=11
export VCPKG_OVERLAY_PORTS="$HOME/.local/share/vcpkg/ports"
export VCPKG_OVERLAY_TRIPLETS="$HOME/.local/share/vcpkg/triplets"
export VCPKG_ROOT="$HOME/Code/c/vcpkg"
```

:::info
It is recommended to define these variables globally because the `CMake` and `qmake` build system are able to detect the `vcpkg` installation from them so you don't have to configure them manually to detect the `vcpkg` installation.
:::

:::tip
On Windows, it's always better to create these types of variables as user variables instead of system variables in the `Environment variables` dialog.
:::

## C preprocessor macros

The following table summarizes all the C preprocessor macros defined in the `TinyORM` library. These C macros are configured by `CMake` or `qmake` build systems. They are not sorted alphabetically, but they are sorted by how significant they are.

In the `CMake` build system, all the C macros are auto-detected / auto-configured or controlled by [`CMake build options`](#cmake-build-options), so you don't have to care too much about them.

In the `qmake` build is important whether you are building `TinyORM` library or you are building your application and linking against `TinyORM` library. When you are building the `TinyORM` library, all the C macros are auto-detected / auto-configured or controlled by [`qmake build options`](#qmake-build-options), so you don't have to care too much about them.

But a special situation is when you are building your application / library and you are linking against `TinyORM` library. In this particular case, you must configure all these C macros manually! For this reason, the [`TinyOrm.pri`](https://github.com/silverqx/TinyORM/blob/main/qmake/TinyOrm.pri) has been created, so that's not a big deal either. Little more info [here](#consume-tinyorm-library-qmake).

<div id='apitable-c-macros'>
<APITable>

| C Macro Name                      | Description |
| --------------------------------- | ----------- |
| `TINYORM_LINKING_SHARED`          | <u>__Must__</u> be defined when you are linking against `TinyORM` shared build (`dll` library), exported classes and functions will be tagged with `__declspec(dllimport)` on `msvc` and `visibility("default")` on `GCC >= 4`. |
| `TINYORM_BUILDING_SHARED`         | Defined when `TinyORM` is built as a `dll` library (shared build). |
| `TINYORM_DEBUG`                   | Defined in the debug build. |
| `TINYORM_NO_DEBUG`                | Defined in the release build. |
| `TINYORM_DEBUG_SQL`               | Defined in the debug build. |
| `TINYORM_NO_DEBUG_SQL`            | Defined in the release build. |
| `TINYORM_MYSQL_PING`              | Enable `Orm::MySqlConnection::pingDatabase()` method.<br/><small>Defined when [`mysql_ping`](#mysql_ping) <small>(qmake)</small> / [`MYSQL_PING`](#MYSQL_PING) <small>(cmake)</small> configuration `build option` is enabled.</small> |
| `TINYORM_DISABLE_ORM`             | Controls the compilation of all `ORM-related` source code, when this macro  is `defined`, then only the `query builder` without `ORM` is compiled. Also excludes `ORM-related` unit tests.<br/><small>Defined when [`disable_orm`](#disable_orm) <small>(qmake)</small> / [`ORM`](#ORM) <small>(cmake)</small> configuration `build option` is enabled <small>(qmake)</small> / disabled <small>(cmake)</small>.</small> |
| `TINYORM_EXTERN_CONSTANTS`        | Defined when extern constants are used. Extern constants are enabled by default for shared builds and disabled for static builds.<br/><small>Described at [`qmake`](#extern_constants) / [`CMake`](#INLINE_CONSTANTS) how it works.</small> |
| `TINYORM_INLINE_CONSTANTS`        | Defined when global inline constants are used.<br/><small>Defined when [`inline_constants`](#inline_constants) <small>(qmake)</small> / [`INLINE_CONSTANTS`](#INLINE_CONSTANTS) <small>(cmake)</small> configuration `build option` is enabled.</small> |
| `TINYORM_TESTS_CODE`              | Enable code needed by unit tests, eg. connection overriding in the `Orm::Tiny::Model`.<br/><small>Defined when [`build_tests`](#build_tests) <small>(qmake)</small> / [`BUILD_TESTS`](#BUILD_TESTS) <small>(cmake)</small> configuration `build option` is enabled.</small> |
| `TINYORM_DISABLE_THREAD_LOCAL`    | Remove all [`thread_local`](https://en.cppreference.com/w/c/language/storage_duration) storage duration specifiers, it disables multi-threading support.<br/><small>Defined when [`disable_thread_local`](#disable_thread_local) <small>(qmake)</small> / [`DISABLE_THREAD_LOCAL`](#DISABLE_THREAD_LOCAL) <small>(cmake)</small> configuration `build option` is enabled.</small> |
| `TINYTOM_MIGRATIONS_DIR`          | Default migrations path for the `make:migration` command, can be an absolute or relative path (to the <abbr title='Current working directory'>pwd</abbr>).<br/><small>Default value: `database/migrations` <small>(relative to the pwd)</small></small><br/><small>Defined by [`TOM_MIGRATIONS_DIR`](#TOM_MIGRATIONS_DIR) <small>(cmake)</small> configuration build option.<br/><small>(qmake note) You can use `DEFINES += TINYTOM_MIGRATIONS_DIR="\"database/migrations\""` on the command-line or set it in the __main__ [`conf.pri`](https://github.com/silverqx/TinyORM/blob/main/conf.pri.example#L65-L70) file.</small></small> |
| `TINYTOM_MODELS_DIR`              | Default models path for the `make:model` command, can be an absolute or relative path (to the <abbr title='Current working directory'>pwd</abbr>).<br/><small>Default value: `database/models` <small>(relative to the pwd)</small></small><br/><small>Defined by [`TOM_MODELS_DIR`](#TOM_MODELS_DIR) <small>(cmake)</small> configuration build option.<br/><small>(qmake note) You can use `DEFINES += TINYTOM_MODELS_DIR="\"database/models\""` on the command-line or set it in the __main__ [`conf.pri`](https://github.com/silverqx/TinyORM/blob/main/conf.pri.example#L72-L73) file.</small></small> |
| `TINYTOM_SEEDERS_DIR`             | Default seeders path for the `make:seeder` command, can be an absolute or relative path (to the <abbr title='Current working directory'>pwd</abbr>).<br/><small>Default value: `database/seeders` <small>(relative to the pwd)</small></small><br/><small>Defined by [`TOM_SEEDERS_DIR`](#TOM_SEEDERS_DIR) <small>(cmake)</small> configuration build option.<br/><small>(qmake note) You can use `DEFINES += TINYTOM_SEEDERS_DIR="\"database/seeders\""` on the command-line or set it in the __main__ [`conf.pri`](https://github.com/silverqx/TinyORM/blob/main/conf.pri.example#L75-L76) file.</small></small> |
| `TINYORM_USING_PCH`               | Defined if building with precompiled headers.<br/><small>Controlled by [`qmake`](#precompile_header) / [`CMake`](#CMAKE_DISABLE_PRECOMPILE_HEADERS).</small> |

</APITable>
</div>

## Building with CMake

:::tip
If something is not clear, you can still look at GitHub Action [`workflows`](https://github.com/silverqx/TinyORM/tree/main/.github/workflows) how a building is done.
:::

First, create a basic folder structure and then clone the `TinyORM` project.

<Tabs groupId={shell}>
<TabItem value={pwsh} label={pwsh_label}>
<CodeBlock className='language-powershell'>
{`cd ${rootFolderPath(pwsh)}
mkdir ${applicationFolder()}/TinyORM/TinyORM-builds-cmake/build-debug\n
cd ${applicationFolder()}/TinyORM
git clone git@github.com:silverqx/TinyORM.git`}
</CodeBlock>
</TabItem>
<TabItem value={bash} label={bash_label}>
<CodeBlock className='language-bash'>
{`cd ${rootFolderPath(bash)}
mkdir -p ${applicationFolder()}/TinyORM/TinyORM-builds-cmake/build-debug\n
cd ${applicationFolder()}/TinyORM
git clone git@github.com:silverqx/TinyORM.git`}
</CodeBlock>
</TabItem>
</Tabs>

### Configure & Build <small>(cmake)</small> {#configure-and-build-cmake}

Now you are ready to configure the `TinyORM` library.

```bash
cd TinyORM-builds-cmake/build-debug
```

<Tabs groupId={shell}>
<TabItem value={pwsh} label={pwsh_label}>
<CodeBlock className='language-powershell'>
{`cmake.exe \`
-S "${applicationFolderPath(pwsh)}/TinyORM/TinyORM" \`
-B "${applicationFolderPath(pwsh)}/TinyORM/TinyORM-builds-cmake/build-debug" \`
-G 'Ninja' \`
-D CMAKE_BUILD_TYPE:STRING='Debug' \`
-D CMAKE_TOOLCHAIN_FILE:FILEPATH="${rootFolderPath(pwsh)}/vcpkg/scripts/buildsystems/vcpkg.cmake" \`
-D CMAKE_INSTALL_PREFIX:PATH="${rootFolderPath(pwsh)}/tmp/TinyORM" \`
-D BUILD_TESTS:BOOL=OFF \`
-D MATCH_EQUAL_EXPORTED_BUILDTREE:BOOL=ON \`
-D MYSQL_PING:BOOL=OFF \`
-D TOM:BOOL=ON \`
-D TOM_EXAMPLE:BOOL=OFF \`
-D VERBOSE_CONFIGURE:BOOL=ON`}
</CodeBlock>
</TabItem>
<TabItem value={bash} label={bash_label}>
<CodeBlock className='language-bash'>
{`cmake \\
-S "${applicationFolderPath(bash)}/TinyORM/TinyORM" \\
-B "${applicationFolderPath(bash)}/TinyORM/TinyORM-builds-cmake/build-debug" \\
-G 'Ninja' \\
-D CMAKE_BUILD_TYPE:STRING='Debug' \\
-D CMAKE_TOOLCHAIN_FILE:FILEPATH="${rootFolderPath(bash)}/vcpkg/scripts/buildsystems/vcpkg.cmake" \\
-D CMAKE_INSTALL_PREFIX:PATH="${rootFolderPath(bash)}/tmp/TinyORM" \\
-D VERBOSE_CONFIGURE:BOOL=ON \\
-D BUILD_TESTS:BOOL=OFF \\
-D MYSQL_PING:BOOL=OFF \\
-D TOM:BOOL=ON \\
-D TOM_EXAMPLE:BOOL=OFF \\
-D MATCH_EQUAL_EXPORTED_BUILDTREE:BOOL=ON`}
</CodeBlock>
</TabItem>
</Tabs>

##### CMake `STRICT_MODE` option

The `STRICT_MODE` `CMake` configuration option was added in `TinyORM` `v0.35.0`. This option was added to avoid the propagation of aggressive strict warning compiler/linker options and Qt definitions from the `TinyORM` library to user code through the [`TinyOrm::CommonConfig`](https://github.com/silverqx/TinyORM/blob/main/cmake/CommonModules/TinyCommon.cmake) interface library.

`TinyORM` uses the strictest warning level options, virtually anything that can be enabled is enabled to produce a better code. I highly recommend enabling this option to produce better code and to follow good practices. It also helps to follow the `ISOCPP` [C++ Core Guidelines](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines) standards.

If you want to enable these strict warning options in your code, you can enable the `STRICT_MODE` `CMake` configuration option and they will be propagated to your code. You can also enabled it globally using the `TINYORM_STRICT_MODE` environment variable, and the value of this environment variable will be picked up during initial CMake configuration as the default value for the `STRICT_MODE` `CMake` configuration option.

You can achieve the same result by manually linking against the `TinyOrm::CommonConfig` interface library when the `STRICT_MODE` is set to `OFF`.

```cmake
target_link_libraries(<target> PRIVATE TinyOrm::CommonConfig)
```

:::info
The recommended way is to set the `TINYORM_STRICT_MODE` environment variable to `1` or `ON`.
:::

#### Build TinyORM

And build. You don't have to install it, you can use the build tree directly if you want.

```bash
cmake --build . --target all
cmake --install .
```

Or build and install in one step.

```bash
cmake --build . --target install
```

:::info
CMake multi-config generators like `Ninja Multi-Config` or `Visual Studio 16 2019` are also supported.
:::

### CMake build options

<div className='apitable-build-options'>
<APITable>

| Option Name                       | Default | Description |
| --------------------------------- | ------- | ----------- |
| `BUILD_SHARED_LIBS`               | `ON`    | Build as a shared/static library. |
| `BUILD_TESTS`                     | `OFF`   | Build TinyORM unit tests. |
| `INLINE_CONSTANTS`                | `OFF`   | Use inline constants instead of extern constants in the `shared build`.<br/>`OFF` is highly recommended for the `shared build`;<br/>is always `ON` for the `static build`.<br/><small>Available when: `BUILD_SHARED_LIBS`</small> |
| `MSVC_RUNTIME_DYNAMIC`            | `ON`    | Use MSVC dynamic runtime library (`-MD`) instead of static (`-MT`), also considers a Debug configuration (`-MTd`, `-MDd`).<br/><small>Available when: `MSVC AND NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY`</small> |
| `MYSQL_PING`                      | `OFF`   | Enable `Orm::MySqlConnection::pingDatabase()` method. |
| `ORM`                             | `ON`    | Controls the compilation of all `ORM-related` source code, when this option is `disabled`, then only the `query builder` without `ORM` is compiled. Also excludes `ORM-related` unit tests. |
| `STRICT_MODE`                     | `OFF`   | Controls propagation of strict compiler/linker options and Qt definitions using the `TinyOrm::CommonConfig` interface library to the user code.<br/><small>(highly recommended; can also be set with the `TINYORM_STRICT_MODE` environment variable; described [here](#cmake-strict_mode-option))</small>. |
| `TOM`                             | `ON`    | Controls the compilation of all `Tom-related` source code, when this option is `disabled`, then it also excludes `Tom-related` unit tests. |
| `TOM_EXAMPLE`                     | `OFF`   | Build the <abbr title='TinyORM Migrations'>`tom`</abbr> console application example. |
| `TOM_MIGRATIONS_DIR`              | `-`     | Default migrations path for the `make:migration` command, can be an absolute or relative path (to the <abbr title='Current working directory'>pwd</abbr>).<br/><small>Default value: `database/migrations` <small>(relative to the pwd)</small></small> |
| `TOM_MODELS_DIR`                  | `-`     | Default models path for the `make:model` command, can be an absolute or relative path (to the <abbr title='Current working directory'>pwd</abbr>).<br/><small>Default value: `database/models` <small>(relative to the pwd)</small></small> |
| `TOM_SEEDERS_DIR`                 | `-`     | Default seeders path for the `make:seeder` command, can be an absolute or relative path (to the <abbr title='Current working directory'>pwd</abbr>).<br/><small>Default value: `database/seeders` <small>(relative to the pwd)</small></small> |
| `VERBOSE_CONFIGURE`               | `OFF`   | Show information about `PACKAGES_FOUND` / `PACKAGES_NOT_FOUND` in the CMake configure output. |

</APITable>
</div>

Advanced `TinyORM` options.

<div className='apitable-build-options'>
<APITable>

| Option Name                       | Default | Description |
| --------------------------------- | ------- | ----------- |
| `DISABLE_THREAD_LOCAL`            | `OFF`   | Remove all [`thread_local`](https://en.cppreference.com/w/c/language/storage_duration) storage duration specifiers, it disables multi-threading support. |
| <small>`MATCH_EQUAL_EXPORTED_BUILDTREE`</small> | `OFF` | Exported package configuration from the build tree is considered to match only when `the build type` of application/library that is linking against the TinyORM library __is equal__.<br/><small>Available when:<br/>`CMAKE_EXPORT_PACKAGE_REGISTRY AND NOT TINY_IS_MULTI_CONFIG`</small> |

</APITable>
</div>

Important `CMake` options.

<div className='apitable-build-options'>
<APITable>

| Option Name                        | Default | Description |
| ---------------------------------- | ------- | ----------- |
| `CMAKE_DISABLE_PRECOMPILE_HEADERS` | `OFF`   | Disable precompiled headers. |
| `CMAKE_CXX_COMPILER`               | `auto`  | The full path to the `C++` compiler. |
| `CMAKE_CXX_COMPILER_LAUNCHER`      | `-`     | Default compiler launcher to use for the `C++` compiler.<br/>Can be used to enable `ccache`, eg. `ccache.exe` on `MinGW` or `/usr/bin/ccache` on `Linux`. |
| `CMAKE_EXPORT_PACKAGE_REGISTRY`    | `ON`    | Enable the `export(TinyOrm)` command.<br/>`TinyORM` sets this variable to `ON` by default. |
| `CMAKE_VERBOSE_MAKEFILE`           | `OFF`   | Enable verbose output from Makefile builds. |

</APITable>
</div>

### Consume TinyOrm library <small>(cmake)</small> {#consume-tinyorm-library-cmake}

In your application or library `CMakeLists.txt` file add following `find_package()` call.

```cmake
find_package(TinyOrm 0.16.0 CONFIG REQUIRED)
```

If the `TinyORM` build tree is not exported to the CMake's [`User Package Registry`](https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html#user-package-registry) then also add the `TinyORM` build tree or `CMAKE_INSTALL_PREFIX` folder to the `CMAKE_PREFIX_PATH`, so CMake can find TinyORM's package configuration file during `find_package(TinyOrm)` call.

<Tabs groupId={shell}>
<TabItem value={pwsh} label={`cmake (${pwsh})`}>
<CodeBlock className='language-cmake'>
{`# build tree
list(APPEND CMAKE_PREFIX_PATH "${convertToCmakeEnvVariable(pwsh, applicationFolderPath(pwsh))}/TinyORM/TinyORM-builds-cmake/build-debug")\n
# installation folder - CMAKE_INSTALL_PREFIX
list(APPEND CMAKE_PREFIX_PATH "${convertToCmakeEnvVariable(pwsh, rootFolderPath(pwsh))}/tmp/TinyORM")`}
</CodeBlock>
</TabItem>
<TabItem value={bash} label={`cmake (${bash})`}>
<CodeBlock className='language-cmake'>
{`# build tree
list(APPEND CMAKE_PREFIX_PATH "${convertToCmakeEnvVariable(bash, applicationFolderPath(bash))}/TinyORM/TinyORM-builds-cmake/build-debug")\n
# installation folder - CMAKE_INSTALL_PREFIX
list(APPEND CMAKE_PREFIX_PATH "${convertToCmakeEnvVariable(bash, rootFolderPath(bash))}/tmp/TinyORM")`}
</CodeBlock>
</TabItem>
</Tabs>

Or as an alternative, you can set `CMAKE_PREFIX_PATH` environment variable.

<a id='tinyorm-on-path-cmake' />

As the last thing, do not forget to add `TinyOrm0d.dll` on the path on Windows and on the `LD_LIBRARY_PATH` on Linux, so your application can find it during execution.

<Tabs groupId={shell} name='tinyorm-on-path'>
<TabItem value={pwsh} label={pwsh_label}>
<CodeBlock className='language-powershell'>
{`$env:Path = "${applicationFolderPath(pwsh, false)}\\TinyORM\\TinyORM-builds-cmake\\build-debug;" + $env:Path`}
</CodeBlock>
</TabItem>
<TabItem value={bash} label={bash_label}>
<CodeBlock className='language-bash'>
{`export LD_LIBRARY_PATH=${applicationFolderPath(bash)}/TinyORM/TinyORM-builds-cmake/build-debug\${PATH:+:}$PATH`}
</CodeBlock>
</TabItem>
</Tabs>

Now you can try the [`HelloWorld CMake`](building/hello-world.mdx#hello-world-with-cmake) example.

:::info
You can also try the [`FetchContent`](hello-world.mdx#fetchcontent) method to fastly link against the `TinyORM` library.
:::

## Building with qmake

First, create a basic folder structure and then clone the `TinyORM` project.

<Tabs groupId={shell}>
<TabItem value={pwsh} label={pwsh_label}>
<CodeBlock className='language-powershell'>
{`cd ${rootFolderPath(pwsh)}
mkdir ${applicationFolder()}/TinyORM/TinyORM-builds-qmake\n
cd ${applicationFolder()}/TinyORM
git clone git@github.com:silverqx/TinyORM.git`}
</CodeBlock>
</TabItem>
<TabItem value={bash} label={bash_label}>
<CodeBlock className='language-bash'>
{`cd ${rootFolderPath(bash)}
mkdir -p ${applicationFolder()}/TinyORM/TinyORM-builds-qmake\n
cd ${applicationFolder()}/TinyORM
git clone git@github.com:silverqx/TinyORM.git`}
</CodeBlock>
</TabItem>
</Tabs>

### Install dependencies

With the `qmake` build system, you have to install `TinyORM` dependencies manually. We will use the `vcpkg` package manager.

```bash
cd ../../vcpkg

vcpkg search range-v3
vcpkg search tabulate
vcpkg install range-v3 tabulate
vcpkg list
```

On `Linux`, you can install the `range-v3` library and some other [dependencies](dependencies.mdx#install-dependencies) with the package manager.

### Configure & Build <small>(qmake)</small> {#configure-and-build-qmake}

#### Open QtCreator IDE

:::tip
I recommend creating a new [`Session`](https://doc.qt.io/qtcreator/creator-project-managing-sessions.html) in the `QtCreator`, this way you will have all the examples in one place and as a bonus, everything will be in the same place when you close and reopen `QtCreator IDE`. You can name it `tinyorm.org` or `TinyORM examples`, it is up to you.
:::

:::tip
If you are using sessions, you can use a single `clangd` instance for all projects in this session in the `QtCreator IDE`. One significant advantage of this method is that the `.qtc_clangd/` folder will not be created in the build folder, but will be stored globally in the Roaming profile. You can enable it in the `Settings` - `C++` - `Clangd` - `Sessions with a single clangd instance`.
:::

#### Configure TinyORM

Now you are ready to configure the `TinyORM` library. There are two ways how to configure the `TinyORM` library and it's the new `Auto-configure` feature added in `TinyORM` `v0.34.0` using the `.env` files and the old way using the `conf.pri` files.

##### Auto-configuration and tiny_dotenv

This is the new recommended method to auto-configure TinyORM's `qmake` build system and also the dependencies, it was added in `TinyORM` `v0.34.0`. You need to copy the prepared `.env.(win32|unix|mingw).example` file to the `.env.(win32|unix|mingw)`. One `.env` example file is prepared for each supported platform.

All prepared `.env.(win32|unix|mingw).example` files are simple and clear. You can also create a common `.env` file that is included before the platform-specific `.env.(win32|unix|mingw)` files.

<Tabs groupId={shell}>
<TabItem value={pwsh} label={pwsh_label}>
<CodeBlock className='language-powershell'>
{`cd ${applicationFolderPath(pwsh)}/TinyORM/TinyORM\n
cp .env.win32.example .env.win32`}
</CodeBlock>
</TabItem>
<TabItem value={bash} label={bash_label}>
<CodeBlock className='language-bash'>
{`cd ${applicationFolderPath(bash)}/TinyORM/TinyORM\n
cp .env.unix.example .env.unix`}
</CodeBlock>
</TabItem>
</Tabs>

And that is all, if you have correctly set all `qmake` variables in this `.env.(win32|unix|mingw)` file or you have correctly set environment variables, then the `qmake` build system should be able to `auto-detect` all dependencies . 🔥

:::info
The [`Auto-configuration`](#auto-configuration-internals) and [`Environment files`](#environment-files) internals are described at the end to make this section more clear.
:::

:::tip
The `Auto-configuration` feature can be turned off using the [`disable_autoconf`](#disable_autoconf) `qmake` configuration option (eg. `CONFIG*=disable_autoconf`).
:::

:::tip
The `tiny_dotenv` feature can be turned off using the [`disable_dotenv`](#disable_dotenv) `qmake` configuration option (eg. `CONFIG*=disable_dotenv`).
:::

##### Manual configuration (conf.pri)

This is the old method used before `TinyORM` `v0.34.0`. You need to copy the `conf.pri.example` files to `conf.pri` (there are four, one for every project or sub-project) and manually update the `INCLUDEPATH` and `LIBS` to configure TinyORM's `qmake` build dependencies. This way you can override any `qmake` build options or variables.

To disable the [`Auto-configuration`](#auto-configuration-internals) feature you must define the [`disable_autoconf`](#disable_autoconf) `qmake` configuration option (eg. `CONFIG*=disable_autoconf`) because from `TinyORM` `v0.34.0` is the `Auto-configuration` feature enabled by default.

You can also remove all `.env` files or turn off the `tiny_dotenv` feature using `CONFIG*=disable_dotenv`. You can use them all at once if you want, `.env` and also `conf.pri` files.

`conf.pri` files are nicely commented on, so you can see what needs to be modified.

<Tabs groupId={shell}>
<TabItem value={pwsh} label={pwsh_label}>
<CodeBlock className='language-powershell'>
{`cd ${applicationFolderPath(pwsh)}/TinyORM/TinyORM\n
cp conf.pri.example conf.pri
cp tests/conf.pri.example tests/conf.pri
cp tests/testdata_tom/conf.pri.example tests/testdata_tom/conf.pri
cp examples/tom/conf.pri.example examples/tom/conf.pri`}
</CodeBlock>
</TabItem>
<TabItem value={bash} label={bash_label}>
<CodeBlock className='language-bash'>
{`cd ${applicationFolderPath(bash)}/TinyORM/TinyORM\n
cp conf.pri.example conf.pri
cp tests/conf.pri.example tests/conf.pri
cp tests/testdata_tom/conf.pri.example tests/testdata_tom/conf.pri
cp examples/tom/conf.pri.example examples/tom/conf.pri`}
</CodeBlock>
</TabItem>
</Tabs>

:::info
The [`Manual configuration`](#manual-configuration-internals) internals are described at the end to make this section more clear.
:::

:::note
The `Manual configuration` is still relevant if you have any non-standard installation of the `vcpkg` or `MySQL` and the `Auto-configuration` feature fails.
:::

##### Opening TinyORM.pro (main project file)

Now you can open the `TinyORM.pro` project in the `QtCreator IDE`.

This will open the `Configure Project` tab, select some kit and update build folder paths to meet our [folders structure](#folders-structure) or like you want.

<img src={require('./assets/img/tinyorm/qmake-configure_project.png').default}
    alt='TinyORM - QtCreator - Configure Project' width='760' />

:::tip
You can force the `QtCreator` to generate a build folders structure as is described [above](#qtcreator-default-build-directory).
:::

You are ready to configure build options, hit <kbd>Ctrl</kbd>+<kbd>5</kbd> to open `Project Settings` tab and select `Build` in the left sidebar to open the `Build Settings`, it should look similar to the following picture.

Disable `QML debugging and profiling` and `Qt Quick Compiler`, they are not used.

<img src={require('./assets/img/tinyorm/qmake-build_settings.png').default}
    alt='TinyORM - QtCreator - Build Settings' width='760' />

If you want to change some `TinyORM` build options, you can pass them to the `Build Steps` - `qmake TinyORM.pro` - `Additional arguments` input field. It can look like this.

<img src={require('./assets/img/tinyorm/qmake-additional_arguments.png').default}
    alt='TinyORM - QtCreator - Build Settings - Additional arguments' width='660' />

#### Build TinyORM

Everything is ready for build, you can press <kbd>Ctrl</kbd>+<kbd>b</kbd> to build the project.

### qmake build options

<div className='apitable-build-options'>
<APITable>

| `CONFIG` <small>Option Name</small> | Default | Description |
| ----------------------------------- | ------- | ----------- |
| `build_tests`                       | `OFF`   | Build TinyORM unit tests. |
| `disable_autoconf`                  | `OFF`   | Disable the [`Auto-configuration`](#auto-configuration-internals) feature <small>(auto-configuration is enabled by default from `TinyORM` `v0.34.0`)</small>. |
| `disable_dotenv`                    | `OFF`   | Disable the [`tiny_dotenv`](#environment-files) feature <small>(environment files are enabled by default from `TinyORM` `v0.34.0`)</small>. |
| `disable_thread_local`              | `OFF`   | Remove all [`thread_local`](https://en.cppreference.com/w/c/language/storage_duration) storage duration specifiers, it disables multi-threading support. |
| `disable_orm`                       | `OFF`   | Controls the compilation of all `ORM-related` source code, when this option is `enabled`, then only the `query builder` without `ORM` is compiled. Also excludes `ORM-related` unit tests. |
| `disable_tom`                       | `OFF`   | Controls the compilation of all `Tom-related` source code, when this option is `disabled`, then it also excludes `Tom-related` unit tests. |
| `extern_constants`                  | `ON`    | Use `extern` constants instead of `inline` constants in the `shared build`.<br/>`ON` is highly recommended for the `shared build` <small>(by default)</small>;<br/>is always `OFF` for the `static build`.<br/><small>Available when: <code>CONFIG(shared\|dll):!inline_constants</code></small> |
| `inline_constants`                  | `OFF`   | Use `inline` constants instead of `extern` constants in the `shared build`.<br/>`OFF` is highly recommended for the `shared build`;<br/>is always `ON` for the `static build`. |
| `link_pkgconfig_off`                | `OFF`   | Link against `mysqlclient` or `libmariadb` with `PKGCONFIG`.<br/>Used only in the `Unix` and `MinGW` __shared__ build <small>(exactly <code>win32-g++\|win32-clang-g++</code>)</small> and when `mysql_ping` is also defined to link against `mysqlclient` or `libmariadb`, [source code](https://github.com/silverqx/TinyORM/blob/main/conf.pri.example#L132).<br/><small>Available when: `unix:mysql_ping` or <code>(win32-g++\|win32-clang-g++):mysql_ping:!static:!staticlib</code></small> |
| `mysql_ping`                        | `OFF`   | Enable `Orm::MySqlConnection::pingDatabase()` method. |
| `tiny_ccache_win32`                 | `ON`    | Enable compiler cache. [Homepage](https://ccache.dev/)<br/><small>It works only on Windows systems. It works well with the MSYS2 `g++`, `clang++`, `msvc`, and `clang-cl` with `msvc`. It disables `precompile_header` as they are not supported on Windows and changes the `-Zi` compiler option to the `-Z7` for debug builds as the `-Zi` compiler option is not supported ([link](https://github.com/ccache/ccache/issues/1040) to the issue).</small> |
| `tom_example`                       | `OFF`   | Build the <abbr title='TinyORM Migrations'>`tom`</abbr> console application example. |

</APITable>
</div>

Advanced `TinyORM` options.

<div className='apitable-build-options'>
<APITable>

| Option Name | Default | Description |
| ----------- | ------- | ----------- |
| `ubsan`     | `OFF`   | Allows to enable [UBSan](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html) sanitizer (Clang only). |

</APITable>
</div>

Important `qmake` options.

<div className='apitable-build-options'>
<APITable>

| `CONFIG` <small>Option Name</small> | Default | Description |
| ----------------------------------- | ------- | ----------- |
| `ccache`                            | `OFF`   | Enable compiler cache. [Homepage](https://ccache.dev/)<br/><small>It works only on the Unix systems. It works well with the `g++` and `clang++` and also supports precompiled headers.</small> |
| `precompile_header`                 | `-`     | Enable precompiled headers, you can disable them with:<br/> `CONFIG-=precompile_header`.<br/><small>The `precompile_header` is enabled by default on `msvc`, `g++`, `clang++`, `clang-cl` on `Windows` and disabled by default on `linux`.</small> |
| `static`<br/>`staticlib`            | `OFF`   | Build as a `static` library (lib only). |
| `static_runtime`                    | `OFF`   | Link against the `shared` (dynamic) or `static` run-time library.<br/><small>The `-MD` becomes `-MT` and `-MDd` becomes `-MTd`. It works only on `MSVC` and `MinGW` or `MSYS2`.<br/>Please <u>don't use</u> this option.<br/>Available when: `msvc` or `mingw`</small> |

</APITable>
</div>

### Consume TinyOrm library <small>(qmake)</small> {#consume-tinyorm-library-qmake}

The [`TinyOrm.pri`](https://github.com/silverqx/TinyORM/blob/main/qmake/TinyOrm.pri) file is available to simplify the integration of the `TinyORM` library into your application. It sets up and configures the `CONFIG` and `DEFINES` qmake variables, adds the `TinyORM`, <abbr title='TinyORM Migrations'>`tom`</abbr>, and `vcpkg` header files on the system `INCLUDEPATH` (cross-platform using the `-isystem` or `-imsvc`), links against the TinyORM `shared` or `static` library using the `LIBS`.

You can use it to configure the `TinyORM` library when you are linking against it. It does a very similar thing like the CMake's `Find Modules` feature.

#### Requirements

It has a few requirements, you need to:

 - specify path to the `TinyORM` qmake features (`.prf` files) using the `QMAKEFEATURES` variable that can only be set in the `.qmake.conf` file
 - specify `qmake` or `environment` variables to find the `vcpkg` installation <small>(`TINY_VCPKG_ROOT` and `TINY_VCPKG_TRIPLET`)</small>
 - specify path to the `TinyORM` build folder <small>(`TINYORM_BUILD_TREE`)</small>
   - you can specify it __manually__
   - or you can use [Partial guessing of the `TINYORM_BUILD_TREE`](#partial-guessing-of-the-tinyorm_build_tree)
 - build your application with the same `CONFIG` `qmake` variables that were used  when building the `TinyORM` library

Let's explain one by one.

##### `QMAKEFEATURES`

Create the `.qmake.conf` file in your application root folder with the following content.

```qmake
# Path to the PARENT folder of the TinyORM source folder
TINY_MAIN_DIR = $$clean_path(<your_path>)
# To find .env and .env.$$QMAKE_PLATFORM files in YOUR project
TINY_DOTENV_ROOT = $$PWD

# Path to the TinyORM build folder (specified manually)
TINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_5_3_MSVC2019_64bit-Debug/)
# vcpkg - range-v3 and tabulate
TINY_VCPKG_ROOT = $$quote(<your_path>/vcpkg/)
#TINY_VCPKG_TRIPLET = x64-windows

# To find .prf files, needed by eg. CONFIG += tiny_system_headers inline/extern_constants
QMAKEFEATURES *= $$quote($$TINY_MAIN_DIR/TinyORM/qmake/features)
```

You can move all `qmake` variables that are part of the `qmake` configuration process to the `.env` file if you want (recommended), this is possible because the `TinyOrm.pri` enables the [`Environment files`](#environment-files) feature by default.

You can look at the [Auto-configure using .qmake.conf and .env](hello-world.mdx#auto-configure-using-qmake_conf-and-env) example for `Hello world` project of what must stay in the `qmake.conf` file and what can be moved to the `.env` files.

:::tip
You can use the [Partial guessing of the `TINYORM_BUILD_TREE`](#partial-guessing-of-the-tinyorm_build_tree) if you don't like to specify it manually.
:::

##### Variables affecting `TinyOrm.pri`

You must define the following variables before the `TinyOrm.pri` is included:

| Variable Name        | Description |
| -------------------- | ----------- |
| `TINYORM_BUILD_TREE` | Path to the `TinyORM` build folder. |
| `TINY_VCPKG_ROOT`    | Path to the `vcpkg` installation folder.<br/>If not defined, then it tries to use the `VCPKG_ROOT` environment variable. |
| `TINY_VCPKG_TRIPLET` | The `vcpkg` `triplet` to use <small>(vcpkg/installed/$$TINY_VCPKG_TRIPLET/)</small>.<br/>If not defined, then it tries to guess the `vcpkg` `triplet` based on the current compiler and OS (based on the `QMAKESPEC`), and as the last thing, it tries to use the `VCPKG_DEFAULT_TRIPLET` environment variable. |

These variables will be set after the configuration is done:

| Variable Name                 | Description |
| ----------------------------- | ----------- |
| `TINY_BUILD_SUBFOLDER`        | Folder by release type if `CONFIG+=debug_and_release` is defined <small>(/debug, /release, or an empty string)</small>. |
| `TINY_CCACHE_BUILD`           | To correctly link `ccache` build against a `ccache` build <small>(_ccache or an empty string)</small>. |
| `TINY_MSVC_VERSION`           | The `msvc` compiler string <small>(MSVC2022 or MSVC2019)</small>. |
| `TINY_QT_VERSION_UNDERSCORED` | Underscored `Qt` version <small>(eg. 6_5_3)</small>. |
| `TINY_RELEASE_TYPE_CAMEL`     | Build type string <small>(Debug, Profile, or Release)</small>. |
| `TINY_VCPKG_INCLUDE`          | Path to the `vcpkg` `include` folder <small>(vcpkg/installed/&lt;triplet&gt;/include/)</small>. |

Then you simply include the `TinyOrm.pri` in your project file.

```qmake title='AnyProject.pro'
include($$TINY_MAIN_DIR/TinyORM/qmake/TinyOrm.pri)
```

And that is all, now you should be able to link against the `TinyORM` library. 👌

##### Manual configuration examples

Frankly, there is no reason to use the Manual configuration (define the variables described below before the `TinyOrm.pri` inclusion), the only reason to use it is when you want more control over this process or want to define everything yourself. I'll leave this section here to show how things work.

You will have to link against the `TinyORM` library manually if you don't set the `TINYORM_BUILD_TREE` `qmake` variable before the inclusion of the `TinyOrm.pri` file. The `INCLUDEPATH` is auto-detected every time.

<Tabs groupId={shell}>
<TabItem value={pwsh} label={pwsh_label}>

```qmake {9}
# Link against TinyORM library
# ---
TINY_MAIN_DIR = $$clean_path(<your_path>)

# Configure TinyORM library
include($$TINY_MAIN_DIR/TinyORM/qmake/TinyOrm.pri)

# TinyORM library path
TINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake)
LIBS += $$quote(-L$$TINYORM_BUILD_TREE/build-TinyORM-Desktop_Qt_6_5_3_MSVC2019_64bit-Debug/src$${TINY_BUILD_SUBFOLDER}/)
LIBS += -lTinyOrm
```

</TabItem>
<TabItem value={bash} label={bash_label}>

```qmake {9}
# Link against TinyORM library
# ---
TINY_MAIN_DIR = $$clean_path(<your_path>)

# Configure TinyORM library
include($$TINY_MAIN_DIR/TinyORM/qmake/TinyOrm.pri)

# TinyORM library path
TINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake)
LIBS += $$quote(-L$$TINYORM_BUILD_TREE/build-TinyORM-Desktop_Qt_6_5_3_GCC_64bit-Debug/src$${TINY_BUILD_SUBFOLDER}/)
LIBS += -lTinyOrm
```

</TabItem>
</Tabs>

The same is true for the `vcpkg` include path. If you don't set the `TINY_VCPKG_ROOT` or have not defined the `VCPKG_ROOT` environment variable, then you need to set up the `INCLUDEPATH` for the `vcpkg` that provides the `range-v3` and `tabulate` header files.

<Tabs groupId={shell}>
<TabItem value={pwsh} label={pwsh_label}>

```qmake
# vcpkg - range-v3 and tabulate
# ---
INCLUDEPATH += $$quote(<your_path>/vcpkg/installed/x64-windows/include/)
```

</TabItem>
<TabItem value={bash} label={bash_label}>

```qmake
# vcpkg - range-v3 and tabulate
# ---
QMAKE_CXXFLAGS += -isystem $$shell_quote(<your_path>/vcpkg/installed/x64-linux/include/)
```

</TabItem>
</Tabs>

You can also use TinyORM's `qmake` function `tiny_add_system_includepath()` which handles `INCLUDEPATH` in a cross-platform way:

```qmake
# vcpkg - range-v3 and tabulate
# ---
tiny_add_system_includepath(<your_path>/vcpkg/installed/x64-linux/include/)
```

Do not forget to add `TinyOrm0.dll` on the path on Windows and on the `LD_LIBRARY_PATH` on Linux, so your application can find it during execution.

<Tabs groupId={shell} name='tinyorm-on-path'>
<TabItem value={pwsh} label={pwsh_label}>
<CodeBlock className='language-powershell'>
{`$env:Path = "${applicationFolderPath(pwsh, false)}\\TinyORM\\TinyORM-builds-qmake\\build-debug;" + $env:Path`}
</CodeBlock>
</TabItem>
<TabItem value={bash} label={bash_label}>
<CodeBlock className='language-bash'>
{`export LD_LIBRARY_PATH=${applicationFolderPath(bash)}/TinyORM/TinyORM-builds-qmake/build-debug\${PATH:+:}$PATH`}
</CodeBlock>
</TabItem>
</Tabs>

:::tip
On Linux `-isystem` marks the directory as a system directory, it prevents warnings.

On Windows you can use `QMAKE_CXXFLAGS_WARN_ON = -external:anglebrackets -external:W0`, it applies a warning level 0 to the angel bracket includes; `#include <file>`.

With the `clang-cl` with `MSVC` you can use `-imsvc`.
:::

### Auto-configuration internals

The `qmake` build system does not support `auto-configuration` of dependencies out of the box but `TinyORM` from `v0.34.0` added its own `Auto-configuration` feature along with the `tiny_dotenv` qmake feature. These new features allow us to `auto-configure` `TinyORM` project, and with their help, the `conf.pri` files can be <u>skipped entirely</u>.

While it adds additional complexity to the `qmake` configuration process, the benefits are significant.

The `Auto-configuration` feature is designed to find the `vcpkg` and `MySQL` installations, and `tiny_dotenv` to include the `.env` and `.env.(win32|unix|mingw)` files in the project's root folder. These new features can be configured using `qmake` and `environment` variables, and they also contain some guessing logic if these variables are not defined.

The `Auto-configuration` feature can be turned off using the [`disable_autoconf`](#disable_autoconf) `qmake` configuration option (eg. `CONFIG*=disable_autoconf`).

These are <u>`qmake`</u> and <u>`environment`</u> variables that affect the `Auto-configuration` feature:

| Variable Name        | Description |
| -------------------- | ----------- |
| `TINY_VCPKG_ROOT`    | Path to the `vcpkg` installation folder.<br/>If not defined, then it tries to use the `VCPKG_ROOT` environment variable. |
| `TINY_VCPKG_TRIPLET` | The `vcpkg` `triplet` to use <small>(vcpkg/installed/$$TINY_VCPKG_TRIPLET/)</small>.<br/>If not defined, then it tries to guess the `vcpkg` `triplet` based on the current compiler and OS (based on the `QMAKESPEC`), and as the last thing, it tries to use the `VCPKG_DEFAULT_TRIPLET` environment variable. |
| `TINY_MYSQL_ROOT`    | Path to the `MySQL` installation folder.<br/>If not defined, then it tries to guess the `MySQL` installation folder (`win32` only): <code>$$(ProgramFiles)/MySQL/MySQL Server (8.1&vert;8.0&vert;5.7)/</code> |

You can set these variables in the `.env` (recommended) or `conf.pri` files, in the `.qmake.conf` file (or wherever you want), or as environment variables.

These variables will be set after `auto-configuration` is done:

| Variable Name        | Description |
| -------------------- | ----------- |
| `TINY_VCPKG_INCLUDE` | Path to the `vcpkg` `include` folder <small>(vcpkg/installed/&lt;triplet&gt;/include/)</small>. |
| `TINY_MYSQL_INCLUDE` | Path to the `MySQL` `include` folder <small>(MySQL Server 8.1/include/)</small>. |
| `TINY_MYSQL_LIB`     | Path to the `MySQL` `lib` folder <small>(MySQL Server 8.1/lib/)</small>. |

The `TINY_MYSQL_INCLUDE` and `TINY_MYSQL_LIB` are only set on `win32` platform except `mingw`.

#### Environment files

The `tiny_dotenv` feature allows us to define the `.env` and `.env.$$TINY_DOTENV_PLATFORM` files in the project's root folder. These files are loaded as early as possible so you can affect the `qmake` configuration process. On the other hand, the `conf.pri` files are loaded as late as possible, and they can be used to override the `qmake` configuration.

The `.env` file is included <u>first</u> and is included on all platforms.

There is only one requirement for this feature to work correctly, and that is to set the `TINY_DOTENV_ROOT` `qmake` variable to the project's root folder. This variable is __already__ set in the `.qmake.conf` file for the `TinyORM` project.

Then the following names are taken into account: .env, .env.win32, .env.unix, .env.mingw

```qmake title='.qmake.conf'
# To find .env and .env.$$QMAKE_PLATFORM files
TINY_DOTENV_ROOT = $$PWD
```

The `tiny_dotenv` feature can be turned off using the [`disable_dotenv`](#disable_dotenv) `qmake` configuration option (eg. `CONFIG*=disable_dotenv`).

:::caution
`Environment files` don't work in the `CMake` builds.
:::

#### Partial guessing of the `TINYORM_BUILD_TREE`

You don't have to manually define the `TINYORM_BUILD_TREE` in `.env` or `.qmake.conf` files. The `TINYORM_BUILD_TREE` absolute path can be put together for you (this is happening inside the `variables.pri` file) and `TinyORM` build folder name can be guessed for you too.

You must define the following variables before the `TinyOrm.pri` will be included to make this real (set them in the `.qmake.conf`):

| Variable Name     | Description |
| ----------------- | ----------- |
| `TINY_MAIN_DIR`   | Path to the __PARENT__ folder of the `TinyORM` source folder. |
| `TINY_BUILD_TREE` | Path to the __current__ build tree - `TINY_BUILD_TREE = $$shadowed($$PWD)`. |

The `TINY_MAIN_DIR` is required for another features anyway (so it should already be set) and all that's left is to set the `TINY_BUILD_TREE`.

```qmake title='.qmake.conf'
# Path to the current build tree (used to guess the TinyORM build tree)
TINY_BUILD_TREE = $$shadowed($$PWD)
```

If you will follow this pattern or logic then you can switch `QtCreator Kits` and the `TINYORM_BUILD_TREE` will be __auto-generated__ correctly and will always point to the correct `TinyORM` build tree.

It works this way, all is happening inside the `variables.pri`, it takes a build folder name for the __current__ project eg. `build-HelloWorld-Desktop_Qt_6_5_3_MSVC2022_64bit-Debug`, replaces the `HelloWorld` with the `TinyORM` and as we already know the `TinyORM` build folder location we can simply concatenate these paths like `$$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_5_3_MSVC2022_64bit-Debug`.

:::caution
This will only work if you follow the recommended [`Folders structure`](#folders-structure).
:::

### Manual configuration internals

There is not much to say about the `Manual configuration` feature. It uses `conf.pri` files (there are four, one for every project or sub-project), and every project has prepared its own `conf.pri.example` file for faster initial configuration.

These `conf.pri.example` files are nicely commented on, so you can see what needs to be modified. The `conf.pri` files are loaded as late as possible, and they can be used to override the `qmake` configuration.

If the `Auto-configuration` feature is disabled and there are no `conf.pri` files, then the `TinyORM` `qmake` configuration or build will fail at 100%.

These `conf.pri` files are intended for configuring qmake's `INCLUDEPATH` and `LIBS`, `CONFIG` or eg. `QMAKE_LFLAGS`, or any other `qmake` options or variables.

## Ccache support

The TinyORM supports the [`ccache`](https://ccache.dev/) out of the box for all [supported compilers](supported-compilers.mdx). For qmake you can enable it using the `CONFIG+=ccache` on Linux or `CONFIG+=tiny_ccache_win32` on Windows. For CMake you can set the `CMAKE_CXX_COMPILER_LAUNCHER=ccache`.

On `Linux` it's clear, the ccache is fully supported and works also with the `precompiled headers`. But was necessary to add some workarounds to the `qmake`/`CMake` build systems to make out of the box support on `Windows`. When you enable the `ccache` on `Windows` then the build system disables `precompiled headers` and replaces the `-Zi` compiler option with the `-Z7` (link to the [issue](https://github.com/ccache/ccache/issues/1040)).

:::tip
You can install the ccache using the `scoop install ccache` command on Windows.
:::
