From f0bab89da65953965c670a577390e788dae57a18 Mon Sep 17 00:00:00 2001 From: silverqx Date: Fri, 24 May 2024 21:46:28 +0200 Subject: [PATCH] Deploy website - based on f23e84eac62ef6b41c3747072404af1a310f0a8b --- 404.html | 2 +- ...078a9.4772f861.js => 0ab078a9.3d783b04.js} | 2 +- ...faf8d.488a21d5.js => 8a8faf8d.2e50ae37.js} | 2 +- ...ee7f3.0f0c7251.js => feaee7f3.956a0aab.js} | 2 +- ...n.7897363c.js => runtime~main.b7a1387b.js} | 2 +- building/hello-world.html | 4 ++-- building/migrations.html | 4 ++-- building/tinyorm.html | 20 +++++++++---------- database/getting-started.html | 2 +- database/migrations.html | 2 +- database/query-builder.html | 2 +- database/seeding.html | 2 +- dependencies.html | 2 +- features-summary.html | 2 +- index.html | 2 +- search.html | 2 +- sponsors.html | 2 +- supported-compilers.html | 2 +- tinydrivers/getting-started.html | 2 +- tinyorm/casts.html | 2 +- tinyorm/collections.html | 2 +- tinyorm/getting-started.html | 2 +- tinyorm/relationships.html | 2 +- tinyorm/serialization.html | 2 +- 24 files changed, 35 insertions(+), 35 deletions(-) rename assets/js/{0ab078a9.4772f861.js => 0ab078a9.3d783b04.js} (99%) rename assets/js/{8a8faf8d.488a21d5.js => 8a8faf8d.2e50ae37.js} (99%) rename assets/js/{feaee7f3.0f0c7251.js => feaee7f3.956a0aab.js} (99%) rename assets/js/{runtime~main.7897363c.js => runtime~main.b7a1387b.js} (78%) diff --git a/404.html b/404.html index 3fc3e3ce5..d6e1a9cd9 100644 --- a/404.html +++ b/404.html @@ -14,7 +14,7 @@ - + diff --git a/assets/js/0ab078a9.4772f861.js b/assets/js/0ab078a9.3d783b04.js similarity index 99% rename from assets/js/0ab078a9.4772f861.js rename to assets/js/0ab078a9.3d783b04.js index 7129c7a65..da6a896f8 100644 --- a/assets/js/0ab078a9.4772f861.js +++ b/assets/js/0ab078a9.3d783b04.js @@ -1 +1 @@ -"use strict";(self.webpackChunktinyorm_org=self.webpackChunktinyorm_org||[]).push([[395],{993:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>O,contentTitle:()=>_,default:()=>I,frontMatter:()=>T,metadata:()=>v,toc:()=>R});var s=i(4848),d=i(8453),r=i(8774),l=i(6684),c=i(2364),t=i(9365),o=i(1470),a=i(5556),h=i.n(a),x=i(6694);function j(e){let{groupId:n}=e;return(0,s.jsx)("span",{children:(0,x.OZ)(n)})}j.propTypes={groupId:h().string.isRequired};const u=j;var p=i(4164),m=i(6362);const b={rootFolderInput:"rootFolderInput_ottS",input:"input_OR7e",application:"application_fjej"};function f(e){let{groupId:n,label:i}=e;const{rootFolder:d,setRootFolder:r}=(0,m.A)(),l=(0,x.T3)(n),c=l?"application":"root",t=l?"\nThis folder name is common for all shells (eg. pwsh, bash, ...)":"";return(0,s.jsx)("form",{name:"tinyorm-root-folder-form",className:(0,p.A)(b.rootFolderInput,b[n],n),onSubmit:e=>{e.preventDefault(),e.stopPropagation()},children:(0,s.jsx)("input",{name:"tinyorm-root-folder-input",className:(0,p.A)(b.input,b[n],n),placeholder:`Enter ${c} folder...`,title:`This ${c} folder will be used in all ${i} examples at tinyorm.org${t}`,onChange:e=>{r(n,e.target.value)},value:d[n]??(0,x.bw)(n)})})}f.propTypes={groupId:h().string.isRequired,label:h().string.isRequired};const g=f;var y=i(7324);const T={sidebar_position:0,sidebar_label:"TinyORM",hide_table_of_contents:!0,description:"How to compile the TinyORM C++ library on Windows and Linux.",keywords:["c++ orm","building","tinyorm"]},_="Building: TinyORM",v={id:"building/tinyorm",title:"Building: TinyORM",description:"How to compile the TinyORM C++ library on Windows and Linux.",source:"@site/docs/building/tinyorm.mdx",sourceDirName:"building",slug:"/building/tinyorm",permalink:"/building/tinyorm",draft:!1,unlisted:!1,tags:[],version:"current",sidebarPosition:0,frontMatter:{sidebar_position:0,sidebar_label:"TinyORM",hide_table_of_contents:!0,description:"How to compile the TinyORM C++ library on Windows and Linux.",keywords:["c++ orm","building","tinyorm"]},sidebar:"tinyormSidebar",previous:{title:"Getting Started",permalink:"/tinydrivers/getting-started"},next:{title:"Hello world",permalink:"/building/hello-world"}},O={},R=[{value:"Introduction",id:"introduction",level:2},{value:"Common Prerequisites",id:"common-prerequisites",level:4},{value:"Windows Prerequisites",id:"windows-prerequisites",level:4},{value:"Build environment scripts",id:"build-environment-scripts",level:5},{value:"Allow symbolic links unprivileged",id:"allow-symbolic-links-unprivileged",level:5},{value:"Folders structure",id:"folders-structure",level:2},{value:"Getting started",id:"getting-started",level:2},{value:"vcpkg",id:"vcpkg",level:2},{value:"Set up vcpkg environment",id:"set-up-vcpkg-environment",level:4},{value:"C preprocessor macros",id:"c-preprocessor-macros",level:2},{value:"Building with CMake",id:"building-with-cmake",level:2},{value:"Configure & Build (cmake)",id:"configure-and-build-cmake",level:3},{value:"CMake STRICT_MODE option",id:"cmake-strict_mode-option",level:5},{value:"Build TinyORM",id:"build-tinyorm",level:4},{value:"CMake build options",id:"cmake-build-options",level:3},{value:"Consume TinyOrm library (cmake)",id:"consume-tinyorm-library-cmake",level:3},{value:"Building with qmake",id:"building-with-qmake",level:2},{value:"Install dependencies",id:"install-dependencies",level:3},{value:"Configure & Build (qmake)",id:"configure-and-build-qmake",level:3},{value:"Open QtCreator IDE",id:"open-qtcreator-ide",level:4},{value:"Configure TinyORM",id:"configure-tinyorm",level:4},{value:"Auto-configuration and tiny_dotenv",id:"auto-configuration-and-tiny_dotenv",level:5},{value:"Manual configuration (conf.pri)",id:"manual-configuration-confpri",level:5},{value:"Opening TinyORM.pro (main project file)",id:"opening-tinyormpro-main-project-file",level:5},{value:"Build TinyORM",id:"build-tinyorm-1",level:4},{value:"qmake build options",id:"qmake-build-options",level:3},{value:"Consume TinyOrm library (qmake)",id:"consume-tinyorm-library-qmake",level:3},{value:"Requirements",id:"requirements",level:4},{value:"QMAKEFEATURES",id:"qmakefeatures",level:5},{value:"Variables affecting TinyOrm.pri",id:"variables-affecting-tinyormpri",level:5},{value:"Manual configuration examples",id:"manual-configuration-examples",level:5},{value:"Auto-configuration internals",id:"auto-configuration-internals",level:3},{value:"Environment files",id:"environment-files",level:4},{value:"Partial guessing of the TINYORM_BUILD_TREE",id:"partial-guessing-of-the-tinyorm_build_tree",level:4},{value:"Manual configuration internals",id:"manual-configuration-internals",level:3},{value:"Ccache support",id:"ccache-support",level:2}];function M(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",h5:"h5",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,d.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"building-tinyorm",children:"Building: TinyORM"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#introduction",children:"Introduction"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#common-prerequisites",children:"Common Prerequisites"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#windows-prerequisites",children:"Windows Prerequisites"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#folders-structure",children:"Folders structure"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#getting-started",children:"Getting started"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#vcpkg",children:"vcpkg"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#c-preprocessor-macros",children:"C preprocessor macros"})}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#building-with-cmake",children:"Building with CMake"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#configure-and-build-cmake",children:"Configure & Build"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#cmake-build-options",children:"CMake build options"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#consume-tinyorm-library-cmake",children:"Consume TinyOrm library"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#building-with-qmake",children:"Building with qmake"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#install-dependencies",children:"Install dependencies"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#configure-and-build-qmake",children:"Configure & Build"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#qmake-build-options",children:"qmake build options"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#consume-tinyorm-library-qmake",children:"Consume TinyOrm library"})}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#auto-configuration-internals",children:"Auto-configuration internals"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#environment-files",children:"Environment files"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#manual-configuration-internals",children:"Manual configuration internals"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#ccache-support",children:"Ccache support"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsxs)(n.p,{children:["The build systems supported out of the box are ",(0,s.jsx)(n.code,{children:"CMake"})," and ",(0,s.jsx)(n.code,{children:"qmake"}),"."]}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["All examples below assume that ",(0,s.jsx)(n.code,{children:"pwsh"})," runs on ",(0,s.jsx)(n.code,{children:"Windows"})," and ",(0,s.jsx)(n.code,{children:"bash"})," runs on ",(0,s.jsx)(n.code,{children:"Linux"}),"."]})}),"\n",(0,s.jsx)(n.h4,{id:"common-prerequisites",children:"Common Prerequisites"}),"\n",(0,s.jsxs)(n.p,{children:["Install the required ",(0,s.jsx)(n.a,{href:"/dependencies",children:"dependencies"})," before starting."]}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"QSqlDatabase"})," depends on ",(0,s.jsx)(n.code,{children:"QCoreApplication"})," from ",(0,s.jsx)(n.code,{children:"Qt v6.5.3"})," so you must create the ",(0,s.jsx)(n.code,{children:"QCoreApplication"})," instance before you will call anything from the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library. \ud83e\udee4 The change was made ",(0,s.jsx)(n.a,{href:"https://github.com/qt/qtbase/commit/8d2bdc9cd5482eace12ba7e45304857bd24db0e6#diff-1d355c25c0b0eddec2be48253407780c4dc510d986739aec61e1ec892ccaf86e",children:"here"}),"."]})}),"\n",(0,s.jsx)(n.h4,{id:"windows-prerequisites",children:"Windows Prerequisites"}),"\n",(0,s.jsx)(n.h5,{id:"build-environment-scripts",children:"Build environment scripts"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"Visual Studio"})," does not provide ",(0,s.jsx)(n.code,{children:"vcvars"})," scripts for ",(0,s.jsx)(n.code,{children:"pwsh"}),", you can use ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/tree/main/tools/vcvars64.ps1",children:(0,s.jsx)(n.code,{children:"vcvars64.ps1"})})," provided by ",(0,s.jsx)(n.code,{children:"TinyORM"})," in the ",(0,s.jsx)(n.code,{children:"tools/"})," folder. Place them on the ",(0,s.jsx)(n.code,{children:"$env:Path"})," user/system path and they will be available system-wide."]}),"\n",(0,s.jsxs)(n.p,{children:["The same is true for the ",(0,s.jsx)(n.code,{children:"Qt Framework"}),", it doesn't provide ",(0,s.jsx)(n.code,{children:"qtenv"})," scripts for ",(0,s.jsx)(n.code,{children:"pwsh"})," too. You can create your own script, place it on the ",(0,s.jsx)(n.code,{children:"$env:Path"})," user/system path and it will be available system-wide."]}),"\n",(0,s.jsxs)(n.p,{children:["Here is one simple example for ",(0,s.jsx)(n.code,{children:"pwsh"}),"."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:"qtenv6.ps1",label:"qtenv6.ps1",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-powershell",children:"#!/usr/bin/env pwsh\n\nSet-StrictMode -Version 3.0\n\nWrite-Host 'Setting up environment for Qt 6.7.0 usage...' -ForegroundColor Magenta\nWrite-Host\n\n$Script:QtRoot = $env:TINY_QT_ROOT ?? 'C:\\Qt'\n\n$env:Path = \"$Script:QtRoot\\6.7.0\\msvc2019_64\\bin;\" + $env:Path\n\n. vcvars64.ps1\n"})})}),(0,s.jsx)(t.A,{value:"qtenv5.ps1",label:"qtenv5.ps1",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-powershell",children:"#!/usr/bin/env pwsh\n\nSet-StrictMode -Version 3.0\n\nWrite-Host 'Setting up environment for Qt 5.15.2 usage...' -ForegroundColor Magenta\nWrite-Host\n\n$Script:QtRoot = $env:TINY_QT_ROOT ?? 'C:\\Qt'\n\n$env:Path = \"$Script:QtRoot\\5.15.2\\msvc2019_64\\bin;\" + $env:Path\n\n. vcvars64.ps1\n"})})})]}),"\n",(0,s.jsxs)(n.p,{children:["And here for ",(0,s.jsx)(n.code,{children:"Linux"}),"."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:"qtenv6",label:"qtenv6",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'#!/usr/bin/env sh\n\necho \'Setting up environment for Qt 6.7.0 usage...\'\n\nQtRoot="${TINY_QT_ROOT:-/opt/Qt}"\n\nexport PATH="$QtRoot/6.7.0/gcc_64/bin"${PATH:+:}$PATH\nexport LD_LIBRARY_PATH="$QtRoot/6.7.0/gcc_64/lib"${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH\n'})})}),(0,s.jsx)(t.A,{value:"qtenv5",label:"qtenv5",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'#!/usr/bin/env sh\n\necho \'Setting up environment for Qt 5.15.2 usage...\'\n\nQtRoot="${TINY_QT_ROOT:-/opt/Qt}"\n\nexport PATH="$QtRoot/5.15.2/gcc_64/bin"${PATH:+:}$PATH\nexport LD_LIBRARY_PATH="$QtRoot/5.15.2/gcc_64/lib"${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH\n'})})})]}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["These scripts consider the ",(0,s.jsx)(n.code,{children:"TINY_QT_ROOT"})," environment variable that should point to the ",(0,s.jsx)(n.code,{children:"Qt"})," installation folder, you can define this environment variable globally in your OS."]})}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["You can't execute these ",(0,s.jsx)(n.code,{children:"qtenvX"})," scripts, they have to be sourced like ",(0,s.jsx)(n.code,{children:"source qtenvX"})," or ",(0,s.jsx)(n.code,{children:". qtenvX"}),"."]})}),"\n",(0,s.jsx)(n.h5,{id:"allow-symbolic-links-unprivileged",children:"Allow symbolic links unprivileged"}),"\n",(0,s.jsxs)(n.p,{children:["Open ",(0,s.jsx)(n.code,{children:"Local Security Policy"}),", go to ",(0,s.jsx)(n.code,{children:"Local Policies - User Rights Assignment"}),", open ",(0,s.jsx)(n.code,{children:"Create symbolic links"})," and add your user account or user group, restart when it doesn't apply immediately."]}),"\n",(0,s.jsx)(n.h2,{id:"folders-structure",children:"Folders structure"}),"\n",(0,s.jsxs)(n.p,{children:["All ",(0,s.jsx)(n.code,{children:"tinyorm.org"})," examples are based on the following folders structure. The ",(0,s.jsx)(n.code,{children:"tom"})," folder will contain a ",(0,s.jsx)(n.a,{href:"/building/migrations",children:"migrations console application"}),"."]}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["You can set the root and application folder paths in the form below and they will be used across the whole ",(0,s.jsx)(n.a,{href:"http://www.tinyorm.org",children:"www.tinyorm.org"})," website. \ud83e\udd73 The pwsh shell is supposed to use on Windows and the bash shell on Linux, but it is not a requirement."]})}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsxs)(t.A,{value:y.b,label:y.ux,className:"tiny-tree",children:[(0,s.jsx)("div",{className:"tiny-root-folder-info-wrapper",children:(0,s.jsxs)(n.p,{children:[(0,s.jsx)("span",{className:"tiny-root-folder-info-prefix",children:"Current pwsh path"}),"\xa0",(0,s.jsx)(u,{groupId:y.b})]})}),(0,s.jsx)(g,{groupId:y.b,label:y.ux}),(0,s.jsx)(g,{groupId:y.pW,label:y.kl}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-text",children:"\n\n\n\u251c\u2500\u2500\n\u2502 \u251c\u2500\u2500 HelloWorld/\n\u2502 | \u251c\u2500\u2500 HelloWorld/\n\u2502 | \u251c\u2500\u2500 HelloWorld-builds-cmake/\n\u2502 | | \u2514\u2500\u2500 build-debug/\n\u2502 | \u2514\u2500\u2500 HelloWorld-builds-qmake/\n\u2502 | \u2514\u2500\u2500 build-debug/\n\u2502 \u251c\u2500\u2500 TinyORM/\n\u2502 | \u251c\u2500\u2500 TinyORM/\n\u2502 | \u251c\u2500\u2500 TinyORM-builds-cmake/\n\u2502 | \u2502 \u251c\u2500\u2500 build-gcc-debug/\n\u2502 | \u2502 \u251c\u2500\u2500 build-gcc-release/\n\u2502 | \u2502 \u2514\u2500\u2500 build-clang-debug/\n\u2502 | \u2514\u2500\u2500 TinyORM-builds-qmake/\n\u2502 | \u251c\u2500\u2500 build-debug/\n\u2502 | \u251c\u2500\u2500 build-TinyORM-Desktop_Qt_5_15_2_MSVC2019_64bit-Debug/\n\u2502 | \u2514\u2500\u2500 build-TinyORM-Desktop_Qt_5_15_2_MSYS2_UCRT64_64bit-Release/\n\u2502 \u2514\u2500\u2500 tom/\n\u2502 \u251c\u2500\u2500 tom/\n\u2502 \u2502 \u2514\u2500\u2500 database/\n\u2502 \u2502 \u251c\u2500\u2500 migrations/\n\u2502 \u2502 \u251c\u2500\u2500 seeders/\n\u2502 \u2502 \u251c\u2500\u2500 migrations.pri\n\u2502 \u2502 \u2514\u2500\u2500 seeders.pri\n\u2502 \u251c\u2500\u2500 tom-builds-cmake/\n\u2502 \u2502 \u2514\u2500\u2500 build-TinyORM-Desktop_Qt_6_7_0_MSVC2019_64bit-Debug/\n\u2502 \u2514\u2500\u2500 tom-builds-qmake/\n\u2502 \u251c\u2500\u2500 build-TinyORM-Desktop_Qt_5_15_3_MSYS2_UCRT64_64bit-Release/\n\u2502 \u2514\u2500\u2500 build-TinyORM-Desktop_Qt_6_7_0_MSVC2019_64bit-Debug/\n\u251c\u2500\u2500 tmp/\n\u2514\u2500\u2500 vcpkg/\n"})})]}),(0,s.jsxs)(t.A,{value:y.xj,label:y.gg,className:"tiny-tree",children:[(0,s.jsx)("div",{className:"tiny-root-folder-info-wrapper",children:(0,s.jsxs)(n.p,{children:[(0,s.jsx)("span",{className:"tiny-root-folder-info-prefix",children:"Current bash path"}),"\xa0",(0,s.jsx)(u,{groupId:y.xj})]})}),(0,s.jsx)(g,{groupId:y.xj,label:y.gg}),(0,s.jsx)(g,{groupId:y.pW,label:y.pW}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-text",children:"\n\n\n\u251c\u2500\u2500\n\u2502 \u251c\u2500\u2500 HelloWorld/\n\u2502 | \u251c\u2500\u2500 HelloWorld/\n\u2502 | \u251c\u2500\u2500 HelloWorld-builds-cmake/\n\u2502 | | \u2514\u2500\u2500 build-debug/\n\u2502 | \u2514\u2500\u2500 HelloWorld-builds-qmake/\n\u2502 | \u2514\u2500\u2500 build-debug/\n\u2502 \u251c\u2500\u2500 TinyORM/\n\u2502 | \u251c\u2500\u2500 TinyORM/\n\u2502 | \u251c\u2500\u2500 TinyORM-builds-cmake/\n\u2502 | \u2502 \u251c\u2500\u2500 build-gcc-debug/\n\u2502 | \u2502 \u251c\u2500\u2500 build-gcc-release/\n\u2502 | \u2502 \u2514\u2500\u2500 build-clang-debug/\n\u2502 | \u2514\u2500\u2500 TinyORM-builds-qmake/\n\u2502 | \u251c\u2500\u2500 build-debug/\n\u2502 | \u251c\u2500\u2500 build-TinyORM-Desktop_Qt_5_15_2_GCC_64bit-Debug/\n\u2502 | \u2514\u2500\u2500 build-TinyORM-Desktop_Qt_5_15_2_clang13_64bit_ccache-Release/\n\u2502 \u2514\u2500\u2500 tom/\n\u2502 \u251c\u2500\u2500 tom/\n\u2502 \u2502 \u2514\u2500\u2500 database/\n\u2502 \u2502 \u251c\u2500\u2500 migrations/\n\u2502 \u2502 \u251c\u2500\u2500 seeders/\n\u2502 \u2502 \u251c\u2500\u2500 migrations.pri\n\u2502 \u2502 \u2514\u2500\u2500 seeders.pri\n\u2502 \u251c\u2500\u2500 tom-builds-cmake/\n\u2502 \u2502 \u2514\u2500\u2500 build-TinyORM-Desktop_Qt_6_7_0_clang14_64bit_ccache-Debug/\n\u2502 \u2514\u2500\u2500 tom-builds-qmake/\n\u2502 \u251c\u2500\u2500 build-TinyORM-Desktop_Qt_6_7_0_GCC_64bit-Debug/\n\u2502 \u2514\u2500\u2500 build-TinyORM-Desktop_Qt_6_7_0_clang14_64bit_ccache-Release/\n\u251c\u2500\u2500 tmp/\n\u2514\u2500\u2500 vcpkg/\n"})})]})]}),"\n",(0,s.jsx)(n.admonition,{type:"danger",children:(0,s.jsxs)(n.p,{children:["Avoid paths with spaces with the ",(0,s.jsx)(n.code,{children:"qmake"})," build system, it will not compile."]})}),"\n",(0,s.jsx)(r.A,{id:"qtcreator-default-build-directory"}),"\n",(0,s.jsxs)(n.admonition,{type:"tip",children:[(0,s.jsxs)(n.p,{children:["You can force the ",(0,s.jsx)(n.code,{children:"QtCreator"})," to generate a build folders structure as is described above."]}),(0,s.jsxs)(n.p,{children:["To generate the required folders structure set the ",(0,s.jsx)(n.code,{children:"Settings"})," - ",(0,s.jsx)(n.code,{children:"Build & Run"})," - ",(0,s.jsx)(n.code,{children:"Default Build Properties"})," - ",(0,s.jsx)(n.code,{children:"Default build directory"})," to:",(0,s.jsx)("br",{}),"\n",(0,s.jsx)(n.code,{children:'../%{Project:Name}-builds-%{BuildSystem:Name}/%{JS: Util.asciify("build-%{Project:Name}-%{Kit:FileSystemName}-%{BuildConfig:Name}")}'})]})]}),"\n",(0,s.jsx)(n.h2,{id:"getting-started",children:"Getting started"}),"\n",(0,s.jsxs)(n.p,{children:["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 ",(0,s.jsx)(n.code,{children:"PATH"})," and ",(0,s.jsx)(n.code,{children:"LD_LIBRARY_PATH"})," for Qt Framework, or use our ",(0,s.jsx)(n.code,{children:"qtenvX"})," scripts described above."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:y.b,label:y.ux,children:(0,s.jsx)(c.A,{className:"language-powershell",children:`mkdir ${(0,x.Sn)(y.b)}\ncd ${(0,x.Sn)(y.b)}\n$env:Path = 'C:\\Qt\\6.7.0\\msvc2019_64\\bin;' + $env:Path\nvcvars64.ps1`})}),(0,s.jsx)(t.A,{value:y.xj,label:y.gg,children:(0,s.jsx)(c.A,{className:"language-bash",children:`mkdir -p ${(0,x.Sn)(y.xj)}\ncd ${(0,x.Sn)(y.xj)}\nexport PATH=/opt/Qt/6.7.0/gcc_64/bin\${PATH:+:}$PATH\nexport LD_LIBRARY_PATH=/opt/Qt/6.7.0/gcc_64/lib\${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH`})})]}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["You can also use the ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/tools/Add-FolderOnPath.ps1",children:(0,s.jsx)(n.code,{children:"tools/Add-FolderOnPath.ps1"})})," pwsh script to fastly prepend a path or ",(0,s.jsx)("abbr",{title:"Current working directory",children:"pwd"})," on the system ",(0,s.jsx)(n.code,{children:"PATH"}),"."]})}),"\n",(0,s.jsx)(n.h2,{id:"vcpkg",children:"vcpkg"}),"\n",(0,s.jsxs)(n.p,{children:["Installing the ",(0,s.jsx)(n.code,{children:"vcpkg"})," is highly recommended, it simplifies installation of the ",(0,s.jsx)(n.code,{children:"range-v3"})," and ",(0,s.jsx)(n.code,{children:"tabulate"})," dependencies."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:y.b,label:y.ux,children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-powershell",children:"git clone git@github.com:microsoft/vcpkg.git\ncd vcpkg\n.\\bootstrap-vcpkg.bat\n"})})}),(0,s.jsx)(t.A,{value:y.xj,label:y.gg,children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"git clone git@github.com:microsoft/vcpkg.git\ncd vcpkg\n./bootstrap-vcpkg.sh\n"})})})]}),"\n",(0,s.jsxs)(n.p,{children:["Add ",(0,s.jsx)(n.code,{children:"vcpkg"})," on the system path, add the following to the ",(0,s.jsx)(n.code,{children:".bashrc"})," or ",(0,s.jsx)(n.code,{children:".zshrc"})," on Linux."]}),"\n",(0,s.jsx)(c.A,{className:"language-bash",children:`export PATH=${(0,x.Sn)(y.xj)}/vcpkg\${PATH:+:}$PATH`}),"\n",(0,s.jsxs)(n.p,{children:["On Windows, open the ",(0,s.jsx)(n.code,{children:"Environment variables"})," dialog and add ",(0,s.jsx)(n.code,{children:"vcpkg"})," on the user ",(0,s.jsx)(n.code,{children:"PATH"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Or you can export it for the current session only."}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:y.b,label:y.ux,children:(0,s.jsx)(c.A,{className:"language-powershell",children:`$env:Path = "${(0,x.Sn)(y.b,!1)}\\vcpkg;" + $env:Path`})}),(0,s.jsx)(t.A,{value:y.xj,label:y.gg,children:(0,s.jsx)(c.A,{className:"language-bash",children:`export PATH=${(0,x.Sn)(y.xj)}/vcpkg\${PATH:+:}$PATH`})})]}),"\n",(0,s.jsxs)(n.h4,{id:"set-up-vcpkg-environment",children:["Set up ",(0,s.jsx)(n.code,{children:"vcpkg"})," environment"]}),"\n",(0,s.jsxs)(n.p,{children:["To export ",(0,s.jsx)(n.code,{children:"vcpkg"})," environment variables globally, add it to the ",(0,s.jsx)(n.code,{children:".bashrc"})," or ",(0,s.jsx)(n.code,{children:".zshrc"})," on Linux, and you can use the ",(0,s.jsx)(n.code,{children:"Environment variables"})," dialog on Windows."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:"title='Linux'",children:'export VCPKG_DEFAULT_TRIPLET=x64-linux\n#export VCPKG_DEFAULT_HOST_TRIPLET=x64-linux\nexport VCPKG_MAX_CONCURRENCY=11\nexport VCPKG_OVERLAY_PORTS="$HOME/.local/share/vcpkg/ports"\nexport VCPKG_OVERLAY_TRIPLETS="$HOME/.local/share/vcpkg/triplets"\nexport VCPKG_ROOT="$HOME/Code/c/vcpkg"\n'})}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["It is recommended to define these variables globally because the ",(0,s.jsx)(n.code,{children:"CMake"})," and ",(0,s.jsx)(n.code,{children:"qmake"})," build system are able to detect the ",(0,s.jsx)(n.code,{children:"vcpkg"})," installation from them so you don't have to configure them manually to detect the ",(0,s.jsx)(n.code,{children:"vcpkg"})," installation."]})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["On Windows, it's always better to create these types of variables as user variables instead of system variables in the ",(0,s.jsx)(n.code,{children:"Environment variables"})," dialog."]})}),"\n",(0,s.jsx)(n.h2,{id:"c-preprocessor-macros",children:"C preprocessor macros"}),"\n",(0,s.jsxs)(n.p,{children:["The following table summarizes all the C preprocessor macros defined in the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library. These C macros are configured by ",(0,s.jsx)(n.code,{children:"CMake"})," or ",(0,s.jsx)(n.code,{children:"qmake"})," build systems. They are not sorted alphabetically, but they are sorted by how significant they are."]}),"\n",(0,s.jsxs)(n.p,{children:["In the ",(0,s.jsx)(n.code,{children:"CMake"})," build system, all the C macros are auto-detected / auto-configured or controlled by ",(0,s.jsx)(n.a,{href:"#cmake-build-options",children:(0,s.jsx)(n.code,{children:"CMake build options"})}),", so you don't have to care too much about them."]}),"\n",(0,s.jsxs)(n.p,{children:["In the ",(0,s.jsx)(n.code,{children:"qmake"})," build is important whether you are building ",(0,s.jsx)(n.code,{children:"TinyORM"})," library or you are building your application and linking against ",(0,s.jsx)(n.code,{children:"TinyORM"})," library. When you are building the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library, all the C macros are auto-detected / auto-configured or controlled by ",(0,s.jsx)(n.a,{href:"#qmake-build-options",children:(0,s.jsx)(n.code,{children:"qmake build options"})}),", so you don't have to care too much about them."]}),"\n",(0,s.jsxs)(n.p,{children:["But a special situation is when you are building your application / library and you are linking against ",(0,s.jsx)(n.code,{children:"TinyORM"})," library. In this particular case, you must configure all these C macros manually! For this reason, the ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/qmake/TinyOrm.pri",children:(0,s.jsx)(n.code,{children:"TinyOrm.pri"})})," has been created, so that's not a big deal either. Little more info ",(0,s.jsx)(n.a,{href:"#consume-tinyorm-library-qmake",children:"here"}),"."]}),"\n",(0,s.jsx)("div",{id:"apitable-c-macros",children:(0,s.jsx)(l.A,{children:(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"C Macro Name"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_LINKING_SHARED"})}),(0,s.jsxs)(n.td,{children:[(0,s.jsx)("u",{children:(0,s.jsx)(n.strong,{children:"Must"})})," be defined when you are linking against ",(0,s.jsx)(n.code,{children:"TinyORM"})," shared build (",(0,s.jsx)(n.code,{children:"dll"})," library), exported classes and functions will be tagged with ",(0,s.jsx)(n.code,{children:"__declspec(dllimport)"})," on ",(0,s.jsx)(n.code,{children:"msvc"})," and ",(0,s.jsx)(n.code,{children:'visibility("default")'})," on ",(0,s.jsx)(n.code,{children:"GCC >= 4"}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_BUILDING_SHARED"})}),(0,s.jsxs)(n.td,{children:["Defined when ",(0,s.jsx)(n.code,{children:"TinyORM"})," is built as a ",(0,s.jsx)(n.code,{children:"dll"})," library (shared build)."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_DEBUG"})}),(0,s.jsx)(n.td,{children:"Defined in the debug build."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_NO_DEBUG"})}),(0,s.jsx)(n.td,{children:"Defined in the release build."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_DEBUG_SQL"})}),(0,s.jsx)(n.td,{children:"Defined in the debug build."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_NO_DEBUG_SQL"})}),(0,s.jsx)(n.td,{children:"Defined in the release build."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_MYSQL_PING"})}),(0,s.jsxs)(n.td,{children:["Enable ",(0,s.jsx)(n.code,{children:"Orm::MySqlConnection::pingDatabase()"})," method.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Defined when ",(0,s.jsx)(n.a,{href:"#mysql_ping",children:(0,s.jsx)(n.code,{children:"mysql_ping"})})," ",(0,s.jsx)("small",{children:"(qmake)"})," / ",(0,s.jsx)(n.a,{href:"#MYSQL_PING",children:(0,s.jsx)(n.code,{children:"MYSQL_PING"})})," ",(0,s.jsx)("small",{children:"(cmake)"})," configuration ",(0,s.jsx)(n.code,{children:"build option"})," is enabled."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_DISABLE_ORM"})}),(0,s.jsxs)(n.td,{children:["Controls the compilation of all ",(0,s.jsx)(n.code,{children:"ORM-related"})," source code, when this macro is ",(0,s.jsx)(n.code,{children:"defined"}),", then only the ",(0,s.jsx)(n.code,{children:"query builder"})," without ",(0,s.jsx)(n.code,{children:"ORM"})," is compiled. Also excludes ",(0,s.jsx)(n.code,{children:"ORM-related"})," unit tests.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Defined when ",(0,s.jsx)(n.a,{href:"#disable_orm",children:(0,s.jsx)(n.code,{children:"disable_orm"})})," ",(0,s.jsx)("small",{children:"(qmake)"})," / ",(0,s.jsx)(n.a,{href:"#ORM",children:(0,s.jsx)(n.code,{children:"ORM"})})," ",(0,s.jsx)("small",{children:"(cmake)"})," configuration ",(0,s.jsx)(n.code,{children:"build option"})," is enabled ",(0,s.jsx)("small",{children:"(qmake)"})," / disabled ",(0,s.jsx)("small",{children:"(cmake)"}),"."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_EXTERN_CONSTANTS"})}),(0,s.jsxs)(n.td,{children:["Defined when extern constants are used. Extern constants are enabled by default for shared builds and disabled for static builds.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Described at ",(0,s.jsx)(n.a,{href:"#extern_constants",children:(0,s.jsx)(n.code,{children:"qmake"})})," / ",(0,s.jsx)(n.a,{href:"#INLINE_CONSTANTS",children:(0,s.jsx)(n.code,{children:"CMake"})})," how it works."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_INLINE_CONSTANTS"})}),(0,s.jsxs)(n.td,{children:["Defined when global inline constants are used.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Defined when ",(0,s.jsx)(n.a,{href:"#inline_constants",children:(0,s.jsx)(n.code,{children:"inline_constants"})})," ",(0,s.jsx)("small",{children:"(qmake)"})," / ",(0,s.jsx)(n.a,{href:"#INLINE_CONSTANTS",children:(0,s.jsx)(n.code,{children:"INLINE_CONSTANTS"})})," ",(0,s.jsx)("small",{children:"(cmake)"})," configuration ",(0,s.jsx)(n.code,{children:"build option"})," is enabled."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_TESTS_CODE"})}),(0,s.jsxs)(n.td,{children:["Enable code needed by unit tests, eg. connection overriding in the ",(0,s.jsx)(n.code,{children:"Orm::Tiny::Model"}),".",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Defined when ",(0,s.jsx)(n.a,{href:"#build_tests",children:(0,s.jsx)(n.code,{children:"build_tests"})})," ",(0,s.jsx)("small",{children:"(qmake)"})," / ",(0,s.jsx)(n.a,{href:"#BUILD_TESTS",children:(0,s.jsx)(n.code,{children:"BUILD_TESTS"})})," ",(0,s.jsx)("small",{children:"(cmake)"})," configuration ",(0,s.jsx)(n.code,{children:"build option"})," is enabled."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_DISABLE_THREAD_LOCAL"})}),(0,s.jsxs)(n.td,{children:["Remove all ",(0,s.jsx)(n.a,{href:"https://en.cppreference.com/w/c/language/storage_duration",children:(0,s.jsx)(n.code,{children:"thread_local"})})," storage duration specifiers, it disables multi-threading support.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Defined when ",(0,s.jsx)(n.a,{href:"#disable_thread_local",children:(0,s.jsx)(n.code,{children:"disable_thread_local"})})," ",(0,s.jsx)("small",{children:"(qmake)"})," / ",(0,s.jsx)(n.a,{href:"#DISABLE_THREAD_LOCAL",children:(0,s.jsx)(n.code,{children:"DISABLE_THREAD_LOCAL"})})," ",(0,s.jsx)("small",{children:"(cmake)"})," configuration ",(0,s.jsx)(n.code,{children:"build option"})," is enabled."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYTOM_MIGRATIONS_DIR"})}),(0,s.jsxs)(n.td,{children:["Default migrations path for the ",(0,s.jsx)(n.code,{children:"make:migration"})," command, can be an absolute or relative path (to the ",(0,s.jsx)("abbr",{title:"Current working directory",children:"pwd"}),").",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Default value: ",(0,s.jsx)(n.code,{children:"database/migrations"})," ",(0,s.jsx)("small",{children:"(relative to the pwd)"})]}),(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Defined by ",(0,s.jsx)(n.a,{href:"#TOM_MIGRATIONS_DIR",children:(0,s.jsx)(n.code,{children:"TOM_MIGRATIONS_DIR"})})," ",(0,s.jsx)("small",{children:"(cmake)"})," configuration build option.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["(qmake note) You can use ",(0,s.jsx)(n.code,{children:'DEFINES += TINYTOM_MIGRATIONS_DIR="\\"database/migrations\\""'})," on the command-line or set it in the ",(0,s.jsx)(n.strong,{children:"main"})," ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/conf.pri.example#L65-L70",children:(0,s.jsx)(n.code,{children:"conf.pri"})})," file."]})]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYTOM_MODELS_DIR"})}),(0,s.jsxs)(n.td,{children:["Default models path for the ",(0,s.jsx)(n.code,{children:"make:model"})," command, can be an absolute or relative path (to the ",(0,s.jsx)("abbr",{title:"Current working directory",children:"pwd"}),").",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Default value: ",(0,s.jsx)(n.code,{children:"database/models"})," ",(0,s.jsx)("small",{children:"(relative to the pwd)"})]}),(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Defined by ",(0,s.jsx)(n.a,{href:"#TOM_MODELS_DIR",children:(0,s.jsx)(n.code,{children:"TOM_MODELS_DIR"})})," ",(0,s.jsx)("small",{children:"(cmake)"})," configuration build option.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["(qmake note) You can use ",(0,s.jsx)(n.code,{children:'DEFINES += TINYTOM_MODELS_DIR="\\"database/models\\""'})," on the command-line or set it in the ",(0,s.jsx)(n.strong,{children:"main"})," ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/conf.pri.example#L72-L73",children:(0,s.jsx)(n.code,{children:"conf.pri"})})," file."]})]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYTOM_SEEDERS_DIR"})}),(0,s.jsxs)(n.td,{children:["Default seeders path for the ",(0,s.jsx)(n.code,{children:"make:seeder"})," command, can be an absolute or relative path (to the ",(0,s.jsx)("abbr",{title:"Current working directory",children:"pwd"}),").",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Default value: ",(0,s.jsx)(n.code,{children:"database/seeders"})," ",(0,s.jsx)("small",{children:"(relative to the pwd)"})]}),(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Defined by ",(0,s.jsx)(n.a,{href:"#TOM_SEEDERS_DIR",children:(0,s.jsx)(n.code,{children:"TOM_SEEDERS_DIR"})})," ",(0,s.jsx)("small",{children:"(cmake)"})," configuration build option.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["(qmake note) You can use ",(0,s.jsx)(n.code,{children:'DEFINES += TINYTOM_SEEDERS_DIR="\\"database/seeders\\""'})," on the command-line or set it in the ",(0,s.jsx)(n.strong,{children:"main"})," ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/conf.pri.example#L75-L76",children:(0,s.jsx)(n.code,{children:"conf.pri"})})," file."]})]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_USING_PCH"})}),(0,s.jsxs)(n.td,{children:["Defined if building with precompiled headers.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Controlled by ",(0,s.jsx)(n.a,{href:"#qmake-precompile_header",children:(0,s.jsx)(n.code,{children:"qmake"})})," / ",(0,s.jsx)(n.a,{href:"#CMAKE_DISABLE_PRECOMPILE_HEADERS",children:(0,s.jsx)(n.code,{children:"CMake"})}),"."]})]})]})]})]})})}),"\n",(0,s.jsx)(n.h2,{id:"building-with-cmake",children:"Building with CMake"}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["If something is not clear, you can still look at GitHub Action ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/tree/main/.github/workflows",children:(0,s.jsx)(n.code,{children:"workflows"})})," how a building is done."]})}),"\n",(0,s.jsxs)(n.p,{children:["First, create a basic folder structure and then clone the ",(0,s.jsx)(n.code,{children:"TinyORM"})," project."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:y.b,label:y.ux,children:(0,s.jsx)(c.A,{className:"language-powershell",children:`cd ${(0,x.Sn)(y.b)}\nmkdir ${(0,x.np)()}/TinyORM/TinyORM-builds-cmake/build-debug\n\ncd ${(0,x.np)()}/TinyORM\ngit clone git@github.com:silverqx/TinyORM.git`})}),(0,s.jsx)(t.A,{value:y.xj,label:y.gg,children:(0,s.jsx)(c.A,{className:"language-bash",children:`cd ${(0,x.Sn)(y.xj)}\nmkdir -p ${(0,x.np)()}/TinyORM/TinyORM-builds-cmake/build-debug\n\ncd ${(0,x.np)()}/TinyORM\ngit clone git@github.com:silverqx/TinyORM.git`})})]}),"\n",(0,s.jsxs)(n.h3,{id:"configure-and-build-cmake",children:["Configure & Build ",(0,s.jsx)("small",{children:"(cmake)"})]}),"\n",(0,s.jsxs)(n.p,{children:["Now you are ready to configure the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd TinyORM-builds-cmake/build-debug\n"})}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:y.b,label:y.ux,children:(0,s.jsx)(c.A,{className:"language-powershell",children:`cmake.exe \`\n-S "${(0,x.OZ)(y.b)}/TinyORM/TinyORM" \`\n-B "${(0,x.OZ)(y.b)}/TinyORM/TinyORM-builds-cmake/build-debug" \`\n-G 'Ninja' \`\n-D CMAKE_BUILD_TYPE:STRING='Debug' \`\n-D CMAKE_TOOLCHAIN_FILE:FILEPATH="${(0,x.Sn)(y.b)}/vcpkg/scripts/buildsystems/vcpkg.cmake" \`\n-D CMAKE_CXX_SCAN_FOR_MODULES:BOOL=OFF \`\n-D CMAKE_INSTALL_PREFIX:PATH="${(0,x.Sn)(y.b)}/tmp/TinyORM" \`\n-D BUILD_TESTS:BOOL=OFF \`\n-D MATCH_EQUAL_EXPORTED_BUILDTREE:BOOL=ON \`\n-D MYSQL_PING:BOOL=OFF \`\n-D TOM:BOOL=ON \`\n-D TOM_EXAMPLE:BOOL=OFF \`\n-D VERBOSE_CONFIGURE:BOOL=ON`})}),(0,s.jsx)(t.A,{value:y.xj,label:y.gg,children:(0,s.jsx)(c.A,{className:"language-bash",children:`cmake \\\n-S "${(0,x.OZ)(y.xj)}/TinyORM/TinyORM" \\\n-B "${(0,x.OZ)(y.xj)}/TinyORM/TinyORM-builds-cmake/build-debug" \\\n-G 'Ninja' \\\n-D CMAKE_BUILD_TYPE:STRING='Debug' \\\n-D CMAKE_TOOLCHAIN_FILE:FILEPATH="${(0,x.Sn)(y.xj)}/vcpkg/scripts/buildsystems/vcpkg.cmake" \\\n-D CMAKE_CXX_SCAN_FOR_MODULES:BOOL=OFF \\\n-D CMAKE_INSTALL_PREFIX:PATH="${(0,x.Sn)(y.xj)}/tmp/TinyORM" \\\n-D VERBOSE_CONFIGURE:BOOL=ON \\\n-D BUILD_TESTS:BOOL=OFF \\\n-D MYSQL_PING:BOOL=OFF \\\n-D TOM:BOOL=ON \\\n-D TOM_EXAMPLE:BOOL=OFF \\\n-D MATCH_EQUAL_EXPORTED_BUILDTREE:BOOL=ON`})})]}),"\n",(0,s.jsxs)(n.h5,{id:"cmake-strict_mode-option",children:["CMake ",(0,s.jsx)(n.code,{children:"STRICT_MODE"})," option"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"STRICT_MODE"})," ",(0,s.jsx)(n.code,{children:"CMake"})," configuration option was added in ",(0,s.jsx)(n.code,{children:"TinyORM"})," ",(0,s.jsx)(n.code,{children:"v0.37.3"}),". This option was added to avoid the propagation of aggressive strict warning compiler/linker options and Qt definitions from the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library to user code through the ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/cmake/CommonModules/TinyCommon.cmake",children:(0,s.jsx)(n.code,{children:"TinyOrm::CommonConfig"})})," interface library."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"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 ",(0,s.jsx)(n.code,{children:"ISOCPP"})," ",(0,s.jsx)(n.a,{href:"https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines",children:"C++ Core Guidelines"})," standards."]}),"\n",(0,s.jsxs)(n.p,{children:["If you want to enable these strict warning options in your code, you can enable the ",(0,s.jsx)(n.code,{children:"STRICT_MODE"})," ",(0,s.jsx)(n.code,{children:"CMake"})," configuration option and they will be propagated to your code. You can also enabled it globally using the ",(0,s.jsx)(n.code,{children:"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 ",(0,s.jsx)(n.code,{children:"STRICT_MODE"})," ",(0,s.jsx)(n.code,{children:"CMake"})," configuration option."]}),"\n",(0,s.jsxs)(n.p,{children:["You can achieve the same result by manually linking against the ",(0,s.jsx)(n.code,{children:"TinyOrm::CommonConfig"})," interface library when the ",(0,s.jsx)(n.code,{children:"STRICT_MODE"})," is set to ",(0,s.jsx)(n.code,{children:"OFF"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-cmake",children:"target_link_libraries( PRIVATE TinyOrm::CommonConfig)\n"})}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["The recommended way is to set the ",(0,s.jsx)(n.code,{children:"TINYORM_STRICT_MODE"})," environment variable to ",(0,s.jsx)(n.code,{children:"1"})," or ",(0,s.jsx)(n.code,{children:"ON"}),"."]})}),"\n",(0,s.jsx)(n.h4,{id:"build-tinyorm",children:"Build TinyORM"}),"\n",(0,s.jsx)(n.p,{children:"And build. You don't have to install it, you can use the build tree directly if you want."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cmake --build . --target all\ncmake --install .\n"})}),"\n",(0,s.jsx)(n.p,{children:"Or build and install in one step."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cmake --build . --target install\n"})}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["CMake multi-config generators like ",(0,s.jsx)(n.code,{children:"Ninja Multi-Config"})," or ",(0,s.jsx)(n.code,{children:"Visual Studio 16 2019"})," are also supported."]})}),"\n",(0,s.jsx)(n.h3,{id:"cmake-build-options",children:"CMake build options"}),"\n",(0,s.jsx)("div",{className:"apitable-build-options",children:(0,s.jsx)(l.A,{children:(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Option Name"}),(0,s.jsx)(n.th,{children:"Default"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"BUILD_DRIVERS"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Build ",(0,s.jsx)(n.a,{href:"/tinydrivers/getting-started",children:"TinyDrivers"})," SQL database drivers (core/common code; replaces QtSql module)."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"BUILD_MYSQL_DRIVER"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Build ",(0,s.jsx)(n.code,{children:"TinyDrivers"})," MySQL database driver.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Available when: ",(0,s.jsx)(n.code,{children:"BUILD_DRIVERS"})]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"BUILD_SHARED_LIBS"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ON"})}),(0,s.jsx)(n.td,{children:"Build as a shared/static library."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"BUILD_TESTS"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsx)(n.td,{children:"Build TinyORM unit tests."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"BUILD_TREE_DEPLOY"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ON"})}),(0,s.jsxs)(n.td,{children:["Copy ",(0,s.jsx)(n.code,{children:"TinyDrivers"})," and ",(0,s.jsx)(n.code,{children:"TinyMySql"})," libraries to the root of the build tree."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"DRIVERS_TYPE"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Shared"})}),(0,s.jsxs)(n.td,{children:["How to build and link against ",(0,s.jsx)(n.code,{children:"TinyDrivers"})," SQL database drivers.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["The ",(0,s.jsx)(n.code,{children:"Static"})," value will be select by default when the ",(0,s.jsx)(n.code,{children:"BUILD_SHARED_LIBS"})," is ",(0,s.jsx)(n.code,{children:"OFF"}),".",(0,s.jsx)("br",{}),"Supported values: ",(0,s.jsx)(n.a,{href:"/tinydrivers/getting-started#the-shared-library-build",children:(0,s.jsx)(n.code,{children:"Shared"})}),", ",(0,s.jsx)(n.a,{href:"/tinydrivers/getting-started#the-loadable-sql-drivers-build",children:(0,s.jsx)(n.code,{children:"Loadable"})}),", and ",(0,s.jsx)(n.a,{href:"/tinydrivers/getting-started#the-static-build",children:(0,s.jsx)(n.code,{children:"Static"})}),(0,s.jsx)("br",{}),"Available when: ",(0,s.jsx)(n.code,{children:"BUILD_DRIVERS AND BUILD_SHARED_LIBS"})]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"INLINE_CONSTANTS"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Use inline constants instead of extern constants in the ",(0,s.jsx)(n.code,{children:"shared build"}),".",(0,s.jsx)("br",{}),(0,s.jsx)(n.code,{children:"OFF"})," is highly recommended for the ",(0,s.jsx)(n.code,{children:"shared build"}),";",(0,s.jsx)("br",{}),"is always ",(0,s.jsx)(n.code,{children:"ON"})," for the ",(0,s.jsx)(n.code,{children:"static build"}),".",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Available when: ",(0,s.jsx)(n.code,{children:"BUILD_SHARED_LIBS"})]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"MSVC_RUNTIME_DYNAMIC"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ON"})}),(0,s.jsxs)(n.td,{children:["Use MSVC dynamic runtime library (",(0,s.jsx)(n.code,{children:"-MD"}),") instead of static (",(0,s.jsx)(n.code,{children:"-MT"}),"), also considers a Debug configuration (",(0,s.jsx)(n.code,{children:"-MTd"}),", ",(0,s.jsx)(n.code,{children:"-MDd"}),").",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Available when: ",(0,s.jsx)(n.code,{children:"MSVC AND NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY"})]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"MYSQL_PING"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Enable ",(0,s.jsx)(n.code,{children:"Orm::MySqlConnection::pingDatabase()"})," method."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ORM"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ON"})}),(0,s.jsxs)(n.td,{children:["Controls the compilation of all ",(0,s.jsx)(n.code,{children:"ORM-related"})," source code, when this option is ",(0,s.jsx)(n.code,{children:"disabled"}),", then only the ",(0,s.jsx)(n.code,{children:"query builder"})," without ",(0,s.jsx)(n.code,{children:"ORM"})," is compiled. Also excludes ",(0,s.jsx)(n.code,{children:"ORM-related"})," unit tests."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"STRICT_MODE"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Controls propagation of strict compiler/linker options and Qt definitions using the ",(0,s.jsx)(n.code,{children:"TinyOrm::CommonConfig"})," interface library to the user code.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["(highly recommended; can also be set with the ",(0,s.jsx)(n.code,{children:"TINYORM_STRICT_MODE"})," environment variable; described ",(0,s.jsx)(n.a,{href:"#cmake-strict_mode-option",children:"here"}),")"]}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TOM"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ON"})}),(0,s.jsxs)(n.td,{children:["Controls the compilation of all ",(0,s.jsx)(n.code,{children:"Tom-related"})," source code, when this option is ",(0,s.jsx)(n.code,{children:"disabled"}),", then it also excludes ",(0,s.jsx)(n.code,{children:"Tom-related"})," unit tests."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TOM_EXAMPLE"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Build the ",(0,s.jsx)("abbr",{title:"TinyORM Migrations",children:(0,s.jsx)(n.code,{children:"tom"})})," console application example."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TOM_MIGRATIONS_DIR"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"-"})}),(0,s.jsxs)(n.td,{children:["Default migrations path for the ",(0,s.jsx)(n.code,{children:"make:migration"})," command, can be an absolute or relative path (to the ",(0,s.jsx)("abbr",{title:"Current working directory",children:"pwd"}),").",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Default value: ",(0,s.jsx)(n.code,{children:"database/migrations"})," ",(0,s.jsx)("small",{children:"(relative to the pwd)"})]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TOM_MODELS_DIR"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"-"})}),(0,s.jsxs)(n.td,{children:["Default models path for the ",(0,s.jsx)(n.code,{children:"make:model"})," command, can be an absolute or relative path (to the ",(0,s.jsx)("abbr",{title:"Current working directory",children:"pwd"}),").",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Default value: ",(0,s.jsx)(n.code,{children:"database/models"})," ",(0,s.jsx)("small",{children:"(relative to the pwd)"})]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TOM_SEEDERS_DIR"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"-"})}),(0,s.jsxs)(n.td,{children:["Default seeders path for the ",(0,s.jsx)(n.code,{children:"make:seeder"})," command, can be an absolute or relative path (to the ",(0,s.jsx)("abbr",{title:"Current working directory",children:"pwd"}),").",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Default value: ",(0,s.jsx)(n.code,{children:"database/seeders"})," ",(0,s.jsx)("small",{children:"(relative to the pwd)"})]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"VERBOSE_CONFIGURE"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Show information about ",(0,s.jsx)(n.code,{children:"PACKAGES_FOUND"})," / ",(0,s.jsx)(n.code,{children:"PACKAGES_NOT_FOUND"})," in the CMake configure output."]})]})]})]})})}),"\n",(0,s.jsxs)(n.p,{children:["Advanced ",(0,s.jsx)(n.code,{children:"TinyORM"})," options."]}),"\n",(0,s.jsx)("div",{className:"apitable-build-options",children:(0,s.jsx)(l.A,{children:(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Option Name"}),(0,s.jsx)(n.th,{children:"Default"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"DISABLE_THREAD_LOCAL"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Remove all ",(0,s.jsx)(n.a,{href:"https://en.cppreference.com/w/c/language/storage_duration",children:(0,s.jsx)(n.code,{children:"thread_local"})})," storage duration specifiers, it disables multi-threading support."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)("small",{children:(0,s.jsx)(n.code,{children:"MATCH_EQUAL_EXPORTED_BUILDTREE"})})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Exported package configuration from the build tree is considered to match only when ",(0,s.jsx)(n.code,{children:"the build type"})," of application/library that is linking against the TinyORM library ",(0,s.jsx)(n.strong,{children:"is equal"}),".",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Available when:",(0,s.jsx)("br",{}),(0,s.jsx)(n.code,{children:"CMAKE_EXPORT_PACKAGE_REGISTRY AND NOT TINY_IS_MULTI_CONFIG"})]})]})]})]})]})})}),"\n",(0,s.jsxs)(n.p,{children:["Important ",(0,s.jsx)(n.code,{children:"CMake"})," options."]}),"\n",(0,s.jsx)("div",{className:"apitable-build-options",children:(0,s.jsx)(l.A,{children:(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Option Name"}),(0,s.jsx)(n.th,{children:"Default"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"CMAKE_DISABLE_PRECOMPILE_HEADERS"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsx)(n.td,{children:"Disable precompiled headers."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"CMAKE_CXX_COMPILER"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"auto"})}),(0,s.jsxs)(n.td,{children:["The full path to the ",(0,s.jsx)(n.code,{children:"C++"})," compiler."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"CMAKE_CXX_COMPILER_LAUNCHER"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"-"})}),(0,s.jsxs)(n.td,{children:["Default compiler launcher to use for the ",(0,s.jsx)(n.code,{children:"C++"})," compiler.",(0,s.jsx)("br",{}),"Can be used to enable ",(0,s.jsx)(n.code,{children:"ccache"}),", eg. ",(0,s.jsx)(n.code,{children:"ccache.exe"})," on ",(0,s.jsx)(n.code,{children:"MinGW"})," or ",(0,s.jsx)(n.code,{children:"/usr/bin/ccache"})," on ",(0,s.jsx)(n.code,{children:"Linux"}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"CMAKE_EXPORT_PACKAGE_REGISTRY"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Enable the ",(0,s.jsx)(n.code,{children:"export(TinyOrm)"})," command.",(0,s.jsx)("br",{}),(0,s.jsx)(n.code,{children:"TinyORM"})," doesn't set this variable by default. Its initial value is taken from the ",(0,s.jsx)(n.code,{children:"TINYORM_EXPORT_PACKAGE_REGISTRY"})," environment variable if not already defined."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"CMAKE_VERBOSE_MAKEFILE"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsx)(n.td,{children:"Enable verbose output from Makefile builds."})]})]})]})})}),"\n",(0,s.jsxs)(n.h3,{id:"consume-tinyorm-library-cmake",children:["Consume TinyOrm library ",(0,s.jsx)("small",{children:"(cmake)"})]}),"\n",(0,s.jsxs)(n.p,{children:["In your application or library ",(0,s.jsx)(n.code,{children:"CMakeLists.txt"})," file add following ",(0,s.jsx)(n.code,{children:"find_package()"})," call."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-cmake",metastring:"title='CMakeLists.txt'",children:"find_package(TinyOrm 0.37.3 CONFIG REQUIRED)\n"})}),"\n",(0,s.jsxs)(n.p,{children:["If the ",(0,s.jsx)(n.code,{children:"TinyORM"})," build tree is not exported to the CMake's ",(0,s.jsx)(n.a,{href:"https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html#user-package-registry",children:(0,s.jsx)(n.code,{children:"User Package Registry"})})," then also add the ",(0,s.jsx)(n.code,{children:"TinyORM"})," build tree or ",(0,s.jsx)(n.code,{children:"CMAKE_INSTALL_PREFIX"})," folder to the ",(0,s.jsx)(n.code,{children:"CMAKE_PREFIX_PATH"}),", so CMake can find TinyORM's package configuration file during ",(0,s.jsx)(n.code,{children:"find_package(TinyOrm)"})," call."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:y.b,label:`cmake (${y.b})`,children:(0,s.jsx)(c.A,{className:"language-cmake",children:`# build tree\nlist(APPEND CMAKE_PREFIX_PATH "${(0,x.nC)(y.b,(0,x.OZ)(y.b))}/TinyORM/TinyORM-builds-cmake/build-debug")\n\n# installation folder - CMAKE_INSTALL_PREFIX\nlist(APPEND CMAKE_PREFIX_PATH "${(0,x.nC)(y.b,(0,x.Sn)(y.b))}/tmp/TinyORM")`})}),(0,s.jsx)(t.A,{value:y.xj,label:`cmake (${y.xj})`,children:(0,s.jsx)(c.A,{className:"language-cmake",children:`# build tree\nlist(APPEND CMAKE_PREFIX_PATH "${(0,x.nC)(y.xj,(0,x.OZ)(y.xj))}/TinyORM/TinyORM-builds-cmake/build-debug")\n\n# installation folder - CMAKE_INSTALL_PREFIX\nlist(APPEND CMAKE_PREFIX_PATH "${(0,x.nC)(y.xj,(0,x.Sn)(y.xj))}/tmp/TinyORM")`})})]}),"\n",(0,s.jsxs)(n.p,{children:["Or as an alternative, you can set ",(0,s.jsx)(n.code,{children:"CMAKE_PREFIX_PATH"})," environment variable."]}),"\n",(0,s.jsx)(r.A,{id:"tinyorm-on-path-cmake"}),"\n",(0,s.jsxs)(n.p,{children:["As the last thing, do not forget to add ",(0,s.jsx)(n.code,{children:"TinyOrm0d.dll"})," on the path on Windows and on the ",(0,s.jsx)(n.code,{children:"LD_LIBRARY_PATH"})," on Linux, so your application can find it during execution."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,name:"tinyorm-on-path",children:[(0,s.jsx)(t.A,{value:y.b,label:y.ux,children:(0,s.jsx)(c.A,{className:"language-powershell",children:`$env:Path = "${(0,x.OZ)(y.b,!1)}\\TinyORM\\TinyORM-builds-cmake\\build-debug;" + $env:Path`})}),(0,s.jsx)(t.A,{value:y.xj,label:y.gg,children:(0,s.jsx)(c.A,{className:"language-bash",children:`export LD_LIBRARY_PATH=${(0,x.OZ)(y.xj)}/TinyORM/TinyORM-builds-cmake/build-debug\${PATH:+:}$PATH`})})]}),"\n",(0,s.jsxs)(n.p,{children:["Now you can try the ",(0,s.jsx)(n.a,{href:"/building/hello-world#hello-world-with-cmake",children:(0,s.jsx)(n.code,{children:"HelloWorld CMake"})})," example."]}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["You can also try the ",(0,s.jsx)(n.a,{href:"/building/hello-world#fetchcontent",children:(0,s.jsx)(n.code,{children:"FetchContent"})})," method to fastly link against the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library."]})}),"\n",(0,s.jsx)(n.h2,{id:"building-with-qmake",children:"Building with qmake"}),"\n",(0,s.jsxs)(n.p,{children:["First, create a basic folder structure and then clone the ",(0,s.jsx)(n.code,{children:"TinyORM"})," project."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:y.b,label:y.ux,children:(0,s.jsx)(c.A,{className:"language-powershell",children:`cd ${(0,x.Sn)(y.b)}\nmkdir ${(0,x.np)()}/TinyORM/TinyORM-builds-qmake\n\ncd ${(0,x.np)()}/TinyORM\ngit clone git@github.com:silverqx/TinyORM.git`})}),(0,s.jsx)(t.A,{value:y.xj,label:y.gg,children:(0,s.jsx)(c.A,{className:"language-bash",children:`cd ${(0,x.Sn)(y.xj)}\nmkdir -p ${(0,x.np)()}/TinyORM/TinyORM-builds-qmake\n\ncd ${(0,x.np)()}/TinyORM\ngit clone git@github.com:silverqx/TinyORM.git`})})]}),"\n",(0,s.jsx)(n.h3,{id:"install-dependencies",children:"Install dependencies"}),"\n",(0,s.jsxs)(n.p,{children:["With the ",(0,s.jsx)(n.code,{children:"qmake"})," build system, you have to install ",(0,s.jsx)(n.code,{children:"TinyORM"})," dependencies manually. We will use the ",(0,s.jsx)(n.code,{children:"vcpkg"})," package manager."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd ../../vcpkg\n\nvcpkg search range-v3\nvcpkg search tabulate\nvcpkg install range-v3 tabulate\nvcpkg list\n"})}),"\n",(0,s.jsxs)(n.p,{children:["On ",(0,s.jsx)(n.code,{children:"Linux"}),", you can install the ",(0,s.jsx)(n.code,{children:"range-v3"})," library and some other ",(0,s.jsx)(n.a,{href:"/dependencies#install-dependencies",children:"dependencies"})," with the package manager."]}),"\n",(0,s.jsxs)(n.h3,{id:"configure-and-build-qmake",children:["Configure & Build ",(0,s.jsx)("small",{children:"(qmake)"})]}),"\n",(0,s.jsx)(n.h4,{id:"open-qtcreator-ide",children:"Open QtCreator IDE"}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["I recommend creating a new ",(0,s.jsx)(n.a,{href:"https://doc.qt.io/qtcreator/creator-project-managing-sessions.html",children:(0,s.jsx)(n.code,{children:"Session"})})," in the ",(0,s.jsx)(n.code,{children:"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 ",(0,s.jsx)(n.code,{children:"QtCreator IDE"}),". You can name it ",(0,s.jsx)(n.code,{children:"tinyorm.org"})," or ",(0,s.jsx)(n.code,{children:"TinyORM examples"}),", it is up to you."]})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["If you are using sessions, you can use a single ",(0,s.jsx)(n.code,{children:"clangd"})," instance for all projects in this session in the ",(0,s.jsx)(n.code,{children:"QtCreator IDE"}),". One significant advantage of this method is that the ",(0,s.jsx)(n.code,{children:".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 ",(0,s.jsx)(n.code,{children:"Settings"})," - ",(0,s.jsx)(n.code,{children:"C++"})," - ",(0,s.jsx)(n.code,{children:"Clangd"})," - ",(0,s.jsx)(n.code,{children:"Sessions with a single clangd instance"}),"."]})}),"\n",(0,s.jsx)(n.h4,{id:"configure-tinyorm",children:"Configure TinyORM"}),"\n",(0,s.jsxs)(n.p,{children:["Now you are ready to configure the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library. There are two ways how to configure the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library and it's the new ",(0,s.jsx)(n.code,{children:"Auto-configure"})," feature added in ",(0,s.jsx)(n.code,{children:"TinyORM"})," ",(0,s.jsx)(n.code,{children:"v0.34.0"})," using the ",(0,s.jsx)(n.code,{children:".env"})," files and the old way using the ",(0,s.jsx)(n.code,{children:"conf.pri"})," files."]}),"\n",(0,s.jsx)(n.h5,{id:"auto-configuration-and-tiny_dotenv",children:"Auto-configuration and tiny_dotenv"}),"\n",(0,s.jsxs)(n.p,{children:["This is the new recommended method to auto-configure TinyORM's ",(0,s.jsx)(n.code,{children:"qmake"})," build system and also the dependencies, it was added in ",(0,s.jsx)(n.code,{children:"TinyORM"})," ",(0,s.jsx)(n.code,{children:"v0.34.0"}),". You need to copy the prepared ",(0,s.jsx)(n.code,{children:".env.(win32|unix|mingw).example"})," file to the ",(0,s.jsx)(n.code,{children:".env.(win32|unix|mingw)"}),". One ",(0,s.jsx)(n.code,{children:".env"})," example file is prepared for each supported platform."]}),"\n",(0,s.jsxs)(n.p,{children:["All prepared ",(0,s.jsx)(n.code,{children:".env.(win32|unix|mingw).example"})," files are simple and clear. You can also create a common ",(0,s.jsx)(n.code,{children:".env"})," file that is included before the platform-specific ",(0,s.jsx)(n.code,{children:".env.(win32|unix|mingw)"})," files."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:y.b,label:y.ux,children:(0,s.jsx)(c.A,{className:"language-powershell",children:`cd ${(0,x.OZ)(y.b)}/TinyORM/TinyORM\n\ncp .env.win32.example .env.win32`})}),(0,s.jsx)(t.A,{value:y.xj,label:y.gg,children:(0,s.jsx)(c.A,{className:"language-bash",children:`cd ${(0,x.OZ)(y.xj)}/TinyORM/TinyORM\n\ncp .env.unix.example .env.unix`})})]}),"\n",(0,s.jsxs)(n.p,{children:["And that is all, if you have correctly set all ",(0,s.jsx)(n.code,{children:"qmake"})," variables in this ",(0,s.jsx)(n.code,{children:".env.(win32|unix|mingw)"})," file or you have correctly set environment variables, then the ",(0,s.jsx)(n.code,{children:"qmake"})," build system should be able to ",(0,s.jsx)(n.code,{children:"auto-detect"})," all dependencies . \ud83d\udd25"]}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"#auto-configuration-internals",children:(0,s.jsx)(n.code,{children:"Auto-configuration"})})," and ",(0,s.jsx)(n.a,{href:"#environment-files",children:(0,s.jsx)(n.code,{children:"Environment files"})})," internals are described at the end to make this section more clear."]})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"Auto-configuration"})," feature can be turned off using the ",(0,s.jsx)(n.a,{href:"#disable_autoconf",children:(0,s.jsx)(n.code,{children:"disable_autoconf"})})," ",(0,s.jsx)(n.code,{children:"qmake"})," configuration option (eg. ",(0,s.jsx)(n.code,{children:"CONFIG*=disable_autoconf"}),")."]})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"tiny_dotenv"})," feature can be turned off using the ",(0,s.jsx)(n.a,{href:"#disable_dotenv",children:(0,s.jsx)(n.code,{children:"disable_dotenv"})})," ",(0,s.jsx)(n.code,{children:"qmake"})," configuration option (eg. ",(0,s.jsx)(n.code,{children:"CONFIG*=disable_dotenv"}),")."]})}),"\n",(0,s.jsx)(n.h5,{id:"manual-configuration-confpri",children:"Manual configuration (conf.pri)"}),"\n",(0,s.jsxs)(n.p,{children:["This is the old method used before ",(0,s.jsx)(n.code,{children:"TinyORM"})," ",(0,s.jsx)(n.code,{children:"v0.34.0"}),". You need to copy the ",(0,s.jsx)(n.code,{children:"conf.pri.example"})," files to ",(0,s.jsx)(n.code,{children:"conf.pri"})," (there are four, one for every project or sub-project) and manually update the ",(0,s.jsx)(n.code,{children:"INCLUDEPATH"})," and ",(0,s.jsx)(n.code,{children:"LIBS"})," to configure TinyORM's ",(0,s.jsx)(n.code,{children:"qmake"})," build dependencies. This way you can override any ",(0,s.jsx)(n.code,{children:"qmake"})," build options or variables."]}),"\n",(0,s.jsxs)(n.p,{children:["To disable the ",(0,s.jsx)(n.a,{href:"#auto-configuration-internals",children:(0,s.jsx)(n.code,{children:"Auto-configuration"})})," feature you must define the ",(0,s.jsx)(n.a,{href:"#disable_autoconf",children:(0,s.jsx)(n.code,{children:"disable_autoconf"})})," ",(0,s.jsx)(n.code,{children:"qmake"})," configuration option (eg. ",(0,s.jsx)(n.code,{children:"CONFIG*=disable_autoconf"}),") because from ",(0,s.jsx)(n.code,{children:"TinyORM"})," ",(0,s.jsx)(n.code,{children:"v0.34.0"})," is the ",(0,s.jsx)(n.code,{children:"Auto-configuration"})," feature enabled by default."]}),"\n",(0,s.jsxs)(n.p,{children:["You can also remove all ",(0,s.jsx)(n.code,{children:".env"})," files or turn off the ",(0,s.jsx)(n.code,{children:"tiny_dotenv"})," feature using ",(0,s.jsx)(n.code,{children:"CONFIG*=disable_dotenv"}),". You can use them all at once if you want, ",(0,s.jsx)(n.code,{children:".env"})," and also ",(0,s.jsx)(n.code,{children:"conf.pri"})," files."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"conf.pri"})," files are nicely commented on, so you can see what needs to be modified."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:y.b,label:y.ux,children:(0,s.jsx)(c.A,{className:"language-powershell",children:`cd ${(0,x.OZ)(y.b)}/TinyORM/TinyORM\n\ncp conf.pri.example conf.pri\ncp tests/conf.pri.example tests/conf.pri\ncp tests/testdata_tom/conf.pri.example tests/testdata_tom/conf.pri\ncp examples/tom/conf.pri.example examples/tom/conf.pri`})}),(0,s.jsx)(t.A,{value:y.xj,label:y.gg,children:(0,s.jsx)(c.A,{className:"language-bash",children:`cd ${(0,x.OZ)(y.xj)}/TinyORM/TinyORM\n\ncp conf.pri.example conf.pri\ncp tests/conf.pri.example tests/conf.pri\ncp tests/testdata_tom/conf.pri.example tests/testdata_tom/conf.pri\ncp examples/tom/conf.pri.example examples/tom/conf.pri`})})]}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"#manual-configuration-internals",children:(0,s.jsx)(n.code,{children:"Manual configuration"})})," internals are described at the end to make this section more clear."]})}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"Manual configuration"})," is still relevant if you have any non-standard installation of the ",(0,s.jsx)(n.code,{children:"vcpkg"})," or ",(0,s.jsx)(n.code,{children:"MySQL"})," and the ",(0,s.jsx)(n.code,{children:"Auto-configuration"})," feature fails."]})}),"\n",(0,s.jsx)(n.h5,{id:"opening-tinyormpro-main-project-file",children:"Opening TinyORM.pro (main project file)"}),"\n",(0,s.jsxs)(n.p,{children:["Now you can open the ",(0,s.jsx)(n.code,{children:"TinyORM.pro"})," project in the ",(0,s.jsx)(n.code,{children:"QtCreator IDE"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["This will open the ",(0,s.jsx)(n.code,{children:"Configure Project"})," tab, select some kit and update build folder paths to meet our ",(0,s.jsx)(n.a,{href:"#folders-structure",children:"folders structure"})," or like you want."]}),"\n",(0,s.jsx)("img",{src:i(885).A,alt:"TinyORM - QtCreator - Configure Project",width:"760"}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["You can force the ",(0,s.jsx)(n.code,{children:"QtCreator"})," to generate a build folders structure as is described ",(0,s.jsx)(n.a,{href:"#qtcreator-default-build-directory",children:"above"}),"."]})}),"\n",(0,s.jsxs)(n.p,{children:["You are ready to configure build options, hit ",(0,s.jsx)("kbd",{children:"Ctrl"}),"+",(0,s.jsx)("kbd",{children:"5"})," to open ",(0,s.jsx)(n.code,{children:"Project Settings"})," tab and select ",(0,s.jsx)(n.code,{children:"Build"})," in the left sidebar to open the ",(0,s.jsx)(n.code,{children:"Build Settings"}),", it should look similar to the following picture."]}),"\n",(0,s.jsxs)(n.p,{children:["Disable ",(0,s.jsx)(n.code,{children:"QML debugging and profiling"})," and ",(0,s.jsx)(n.code,{children:"Qt Quick Compiler"}),", they are not used."]}),"\n",(0,s.jsx)("img",{src:i(7619).A,alt:"TinyORM - QtCreator - Build Settings",width:"760"}),"\n",(0,s.jsxs)(n.p,{children:["If you want to change some ",(0,s.jsx)(n.code,{children:"TinyORM"})," build options, you can pass them to the ",(0,s.jsx)(n.code,{children:"Build Steps"})," - ",(0,s.jsx)(n.code,{children:"qmake TinyORM.pro"})," - ",(0,s.jsx)(n.code,{children:"Additional arguments"})," input field. It can look like this."]}),"\n",(0,s.jsx)("img",{src:i(2721).A,alt:"TinyORM - QtCreator - Build Settings - Additional arguments",width:"660"}),"\n",(0,s.jsx)(n.h4,{id:"build-tinyorm-1",children:"Build TinyORM"}),"\n",(0,s.jsxs)(n.p,{children:["Everything is ready for build, you can press ",(0,s.jsx)("kbd",{children:"Ctrl"}),"+",(0,s.jsx)("kbd",{children:"b"})," to build the project."]}),"\n",(0,s.jsx)(n.h3,{id:"qmake-build-options",children:"qmake build options"}),"\n",(0,s.jsx)("div",{className:"apitable-build-options",children:(0,s.jsx)(l.A,{children:(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsxs)(n.th,{children:[(0,s.jsx)(n.code,{children:"CONFIG"})," ",(0,s.jsx)("small",{children:"Option Name"})]}),(0,s.jsx)(n.th,{children:"Default"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"build_loadable_drivers"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Build ",(0,s.jsx)(n.a,{href:"/tinydrivers/getting-started",children:(0,s.jsx)(n.code,{children:"TinyDrivers"})})," as a shared library and SQL database drivers (eg. ",(0,s.jsx)(n.code,{children:"TinyMySql"}),") as shared libraries (",(0,s.jsx)(n.a,{href:"/tinydrivers/getting-started#the-loadable-sql-drivers-build",children:(0,s.jsx)(n.code,{children:"Loadable"})})," modules) that are loaded at runtime using ",(0,s.jsx)(n.code,{children:"LoadLibrary()"})," on Windows or ",(0,s.jsx)(n.code,{children:"dlopen()"})," on Linux."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"build_mysql_driver"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Build ",(0,s.jsx)(n.code,{children:"TinyDrivers"})," MySQL database driver.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["It's enabled by default when ",(0,s.jsx)(n.code,{children:"build_shared_drivers"}),", ",(0,s.jsx)(n.code,{children:"build_loadable_drivers"}),", or ",(0,s.jsx)(n.code,{children:"build_static_drivers"})," is enabled.",(0,s.jsx)("br",{}),"Available when: ",(0,s.jsx)(n.code,{children:"build_shared_drivers"})," OR ",(0,s.jsx)(n.code,{children:"build_loadable_drivers"})," OR ",(0,s.jsx)(n.code,{children:"build_static_drivers"})]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"build_shared_drivers"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Build ",(0,s.jsx)(n.code,{children:"TinyDrivers"})," as a ",(0,s.jsx)(n.a,{href:"/tinydrivers/getting-started#the-shared-library-build",children:(0,s.jsx)(n.code,{children:"Shared"})})," library."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"build_static_drivers"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Build ",(0,s.jsx)(n.code,{children:"TinyDrivers"})," as a ",(0,s.jsx)(n.a,{href:"/tinydrivers/getting-started#the-static-build",children:(0,s.jsx)(n.code,{children:"Static"})})," library archive.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["The ",(0,s.jsx)(n.code,{children:"build_static_drivers"})," ",(0,s.jsx)(n.code,{children:"qmake"})," configuration option will be select by default when the ",(0,s.jsx)(n.a,{href:"#qmake-static",children:(0,s.jsx)(n.code,{children:"CONFIG*=static"})})," is enabled."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"build_tests"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsx)(n.td,{children:"Build TinyORM unit tests."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ccache"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ON"})}),(0,s.jsxs)(n.td,{children:["Enable compiler cache. ",(0,s.jsx)(n.a,{href:"https://ccache.dev/",children:"Homepage"}),(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["It works on Windows and Unix systems. This option overrides qmake's ",(0,s.jsx)(n.code,{children:"ccache"})," option. It internally calls qmake's ",(0,s.jsx)(n.a,{href:"#qmake-ccache",children:(0,s.jsx)(n.code,{children:"ccache"})})," option on Unix and ",(0,s.jsx)(n.a,{href:"#tiny_ccache_win32",children:(0,s.jsx)(n.code,{children:"tiny_ccache_win32"})})," on Windows.",(0,s.jsx)("br",{}),"Reason: It allows using the same option on both OS-es."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"disable_autoconf"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Disable the ",(0,s.jsx)(n.a,{href:"#auto-configuration-internals",children:(0,s.jsx)(n.code,{children:"Auto-configuration"})})," feature ",(0,s.jsxs)("small",{children:["(auto-configuration is enabled by default from ",(0,s.jsx)(n.code,{children:"TinyORM"})," ",(0,s.jsx)(n.code,{children:"v0.34.0"}),")"]}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"disable_dotenv"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Disable the ",(0,s.jsx)(n.a,{href:"#environment-files",children:(0,s.jsx)(n.code,{children:"tiny_dotenv"})})," feature ",(0,s.jsxs)("small",{children:["(environment files are enabled by default from ",(0,s.jsx)(n.code,{children:"TinyORM"})," ",(0,s.jsx)(n.code,{children:"v0.34.0"}),")"]}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"disable_thread_local"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Remove all ",(0,s.jsx)(n.a,{href:"https://en.cppreference.com/w/c/language/storage_duration",children:(0,s.jsx)(n.code,{children:"thread_local"})})," storage duration specifiers, it disables multi-threading support."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"disable_orm"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Controls the compilation of all ",(0,s.jsx)(n.code,{children:"ORM-related"})," source code, when this option is ",(0,s.jsx)(n.code,{children:"enabled"}),", then only the ",(0,s.jsx)(n.code,{children:"query builder"})," without ",(0,s.jsx)(n.code,{children:"ORM"})," is compiled. Also excludes ",(0,s.jsx)(n.code,{children:"ORM-related"})," unit tests."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"disable_tom"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Controls the compilation of all ",(0,s.jsx)(n.code,{children:"Tom-related"})," source code, when this option is ",(0,s.jsx)(n.code,{children:"disabled"}),", then it also excludes ",(0,s.jsx)(n.code,{children:"Tom-related"})," unit tests."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"extern_constants"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ON"})}),(0,s.jsxs)(n.td,{children:["Use ",(0,s.jsx)(n.code,{children:"extern"})," constants instead of ",(0,s.jsx)(n.code,{children:"inline"})," constants in the ",(0,s.jsx)(n.code,{children:"shared build"}),".",(0,s.jsx)("br",{}),(0,s.jsx)(n.code,{children:"ON"})," is highly recommended for the ",(0,s.jsx)(n.code,{children:"shared build"})," ",(0,s.jsx)("small",{children:"(by default)"}),";",(0,s.jsx)("br",{}),"is always ",(0,s.jsx)(n.code,{children:"OFF"})," for the ",(0,s.jsx)(n.code,{children:"static build"}),".",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Available when: ",(0,s.jsx)("code",{children:"CONFIG(shared|dll):!inline_constants"})]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"inline_constants"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Use ",(0,s.jsx)(n.code,{children:"inline"})," constants instead of ",(0,s.jsx)(n.code,{children:"extern"})," constants in the ",(0,s.jsx)(n.code,{children:"shared build"}),".",(0,s.jsx)("br",{}),(0,s.jsx)(n.code,{children:"OFF"})," is highly recommended for the ",(0,s.jsx)(n.code,{children:"shared build"}),";",(0,s.jsx)("br",{}),"is always ",(0,s.jsx)(n.code,{children:"ON"})," for the ",(0,s.jsx)(n.code,{children:"static build"}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"link_pkgconfig_off"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Link against ",(0,s.jsx)(n.code,{children:"mysqlclient"})," or ",(0,s.jsx)(n.code,{children:"libmariadb"})," with ",(0,s.jsx)(n.code,{children:"PKGCONFIG"}),".",(0,s.jsx)("br",{}),"Used only in the ",(0,s.jsx)(n.code,{children:"Unix"})," and ",(0,s.jsx)(n.code,{children:"MinGW"})," ",(0,s.jsx)(n.strong,{children:"shared"})," build ",(0,s.jsxs)("small",{children:["(exactly ",(0,s.jsx)("code",{children:"win32-g++|win32-clang-g++"}),")"]})," and when ",(0,s.jsx)(n.code,{children:"mysql_ping"})," is also defined to link against ",(0,s.jsx)(n.code,{children:"mysqlclient"})," or ",(0,s.jsx)(n.code,{children:"libmariadb"}),", ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/conf.pri.example#L132",children:"source code"}),".",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Available when: ",(0,s.jsx)(n.code,{children:"unix:mysql_ping"})," or ",(0,s.jsx)("code",{children:"(win32-g++|win32-clang-g++):mysql_ping:!static:!staticlib"})]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"mysql_ping"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Enable ",(0,s.jsx)(n.code,{children:"Orm::MySqlConnection::pingDatabase()"})," method."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"tiny_ccache_win32"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ON"})}),(0,s.jsxs)(n.td,{children:["Enable compiler cache. ",(0,s.jsx)(n.a,{href:"https://ccache.dev/",children:"Homepage"}),(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["It works only on Windows systems. It works well with the MSYS2 ",(0,s.jsx)(n.code,{children:"g++"}),", ",(0,s.jsx)(n.code,{children:"clang++"}),", ",(0,s.jsx)(n.code,{children:"msvc"}),", and ",(0,s.jsx)(n.code,{children:"clang-cl"})," with ",(0,s.jsx)(n.code,{children:"msvc"}),". It disables ",(0,s.jsx)(n.code,{children:"precompile_header"})," as they are not supported on Windows and changes the ",(0,s.jsx)(n.code,{children:"-Zi"})," compiler option to the ",(0,s.jsx)(n.code,{children:"-Z7"})," for debug builds as the ",(0,s.jsx)(n.code,{children:"-Zi"})," compiler option is not supported (",(0,s.jsx)(n.a,{href:"https://github.com/ccache/ccache/issues/1040",children:"link"})," to the issue)."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"tom_example"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Build the ",(0,s.jsx)("abbr",{title:"TinyORM Migrations",children:(0,s.jsx)(n.code,{children:"tom"})})," console application example."]})]})]})]})})}),"\n",(0,s.jsxs)(n.p,{children:["Advanced ",(0,s.jsx)(n.code,{children:"TinyORM"})," options."]}),"\n",(0,s.jsx)("div",{className:"apitable-build-options",children:(0,s.jsx)(l.A,{children:(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Option Name"}),(0,s.jsx)(n.th,{children:"Default"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsx)(n.tbody,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ubsan"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Allows to enable ",(0,s.jsx)(n.a,{href:"https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html",children:"UBSan"})," sanitizer (Clang only)."]})]})})]})})}),"\n",(0,s.jsxs)(n.p,{children:["Important ",(0,s.jsx)(n.code,{children:"qmake"})," options."]}),"\n",(0,s.jsx)("div",{className:"apitable-build-options",children:(0,s.jsx)(l.A,{name:"qmake",children:(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsxs)(n.th,{children:[(0,s.jsx)(n.code,{children:"CONFIG"})," ",(0,s.jsx)("small",{children:"Option Name"})]}),(0,s.jsx)(n.th,{children:"Default"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ccache"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Enable compiler cache. ",(0,s.jsx)(n.a,{href:"https://ccache.dev/",children:"Homepage"}),(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["It works only on the Unix systems. It works well with ",(0,s.jsx)(n.code,{children:"g++"})," and ",(0,s.jsx)(n.code,{children:"clang++"})," and also supports precompiled headers."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"precompile_header"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"-"})}),(0,s.jsxs)(n.td,{children:["Enable precompiled headers, you can disable them with:",(0,s.jsx)("br",{})," ",(0,s.jsx)(n.code,{children:"CONFIG-=precompile_header"}),".",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["The ",(0,s.jsx)(n.code,{children:"precompile_header"})," is enabled by default on ",(0,s.jsx)(n.code,{children:"msvc"}),", ",(0,s.jsx)(n.code,{children:"g++"}),", ",(0,s.jsx)(n.code,{children:"clang++"}),", ",(0,s.jsx)(n.code,{children:"clang-cl"})," on ",(0,s.jsx)(n.code,{children:"Windows"})," and disabled by default on ",(0,s.jsx)(n.code,{children:"linux"}),"."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"static"}),(0,s.jsx)("br",{}),(0,s.jsx)(n.code,{children:"staticlib"})]}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Build as a ",(0,s.jsx)(n.code,{children:"static"})," library (lib only).",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["If you want to build all libraries in the ",(0,s.jsx)(n.code,{children:"TinyORM"})," project as static library archives and link against static libraries use the ",(0,s.jsx)(n.a,{href:"https://doc.qt.io/qt/qmake-variable-reference.html#config",children:(0,s.jsx)(n.code,{children:"CONFIG += static"})}),". Don't use the ",(0,s.jsx)(n.code,{children:"CONFIG += staticlib"}),".",(0,s.jsx)("br",{}),"See ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/NOTES.txt",children:"NOTES.txt"})," for more information (search ",(0,s.jsx)(n.code,{children:"static vs staticlib"}),")."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"static_runtime"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Link against the ",(0,s.jsx)(n.code,{children:"shared"})," (dynamic) or ",(0,s.jsx)(n.code,{children:"static"})," run-time library.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["The ",(0,s.jsx)(n.code,{children:"-MD"})," becomes ",(0,s.jsx)(n.code,{children:"-MT"})," and ",(0,s.jsx)(n.code,{children:"-MDd"})," becomes ",(0,s.jsx)(n.code,{children:"-MTd"}),". It works only on ",(0,s.jsx)(n.code,{children:"MSVC"})," and ",(0,s.jsx)(n.code,{children:"MinGW"})," or ",(0,s.jsx)(n.code,{children:"MSYS2"}),".",(0,s.jsx)("br",{}),"Please ",(0,s.jsx)("u",{children:"don't use"})," this option.",(0,s.jsx)("br",{}),"Available when: ",(0,s.jsx)(n.code,{children:"msvc"})," or ",(0,s.jsx)(n.code,{children:"mingw"})]})]})]})]})]})})}),"\n",(0,s.jsxs)(n.h3,{id:"consume-tinyorm-library-qmake",children:["Consume TinyOrm library ",(0,s.jsx)("small",{children:"(qmake)"})]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/qmake/TinyOrm.pri",children:(0,s.jsx)(n.code,{children:"TinyOrm.pri"})})," file is available to simplify the integration of the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library into your application. It sets up and configures the ",(0,s.jsx)(n.code,{children:"CONFIG"})," and ",(0,s.jsx)(n.code,{children:"DEFINES"})," qmake variables, adds the ",(0,s.jsx)(n.code,{children:"TinyORM"}),", ",(0,s.jsx)("abbr",{title:"TinyORM Migrations",children:(0,s.jsx)(n.code,{children:"tom"})}),", and ",(0,s.jsx)(n.code,{children:"vcpkg"})," header files on the system ",(0,s.jsx)(n.code,{children:"INCLUDEPATH"})," (cross-platform using the ",(0,s.jsx)(n.code,{children:"-isystem"})," or ",(0,s.jsx)(n.code,{children:"-imsvc"}),"), links against the TinyORM ",(0,s.jsx)(n.code,{children:"shared"})," or ",(0,s.jsx)(n.code,{children:"static"})," library using the ",(0,s.jsx)(n.code,{children:"LIBS"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["You can use it to configure the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library when you are linking against it. It does a very similar thing like the CMake's ",(0,s.jsx)(n.code,{children:"Find Modules"})," feature."]}),"\n",(0,s.jsx)(n.h4,{id:"requirements",children:"Requirements"}),"\n",(0,s.jsx)(n.p,{children:"It has a few requirements, you need to:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["specify path to the ",(0,s.jsx)(n.code,{children:"TinyORM"})," qmake features (",(0,s.jsx)(n.code,{children:".prf"})," files) using the ",(0,s.jsx)(n.code,{children:"QMAKEFEATURES"})," variable that can only be set in the ",(0,s.jsx)(n.code,{children:".qmake.conf"})," file"]}),"\n",(0,s.jsxs)(n.li,{children:["specify ",(0,s.jsx)(n.code,{children:"qmake"})," or ",(0,s.jsx)(n.code,{children:"environment"})," variables to find the ",(0,s.jsx)(n.code,{children:"vcpkg"})," installation ",(0,s.jsxs)("small",{children:["(",(0,s.jsx)(n.code,{children:"TINY_VCPKG_ROOT"})," and ",(0,s.jsx)(n.code,{children:"TINY_VCPKG_TRIPLET"}),")"]})]}),"\n",(0,s.jsxs)(n.li,{children:["specify path to the ",(0,s.jsx)(n.code,{children:"TinyORM"})," build folder ",(0,s.jsxs)("small",{children:["(",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"}),")"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["you can specify it ",(0,s.jsx)(n.strong,{children:"manually"})]}),"\n",(0,s.jsxs)(n.li,{children:["or you can use ",(0,s.jsxs)(n.a,{href:"#partial-guessing-of-the-tinyorm_build_tree",children:["Partial guessing of the ",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})]})]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["build your application with the same ",(0,s.jsx)(n.code,{children:"CONFIG"})," ",(0,s.jsx)(n.code,{children:"qmake"})," variables that were used when building the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Let's explain one by one."}),"\n",(0,s.jsx)(n.h5,{id:"qmakefeatures",children:(0,s.jsx)(n.code,{children:"QMAKEFEATURES"})}),"\n",(0,s.jsxs)(n.p,{children:["Create the ",(0,s.jsx)(n.code,{children:".qmake.conf"})," file in your application root folder with the following content."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",metastring:"title='.qmake.conf'",children:"# Path to the PARENT folder of the TinyORM source folder\nTINY_MAIN_DIR = $$clean_path()\n# To find .env and .env.$$QMAKE_PLATFORM files in YOUR project\nTINY_DOTENV_ROOT = $$PWD\n\n# Path to the TinyORM build folder (specified manually)\nTINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_0_MSVC2019_64bit-Debug/)\n# vcpkg - range-v3 and tabulate\nTINY_VCPKG_ROOT = $$quote(/vcpkg/)\n#TINY_VCPKG_TRIPLET = x64-windows\n\n# To find .prf files, needed by eg. CONFIG += tiny_system_headers inline/extern_constants\nQMAKEFEATURES *= $$quote($$TINY_MAIN_DIR/TinyORM/qmake/features)\n"})}),"\n",(0,s.jsxs)(n.p,{children:["You can move all ",(0,s.jsx)(n.code,{children:"qmake"})," variables that are part of the ",(0,s.jsx)(n.code,{children:"qmake"})," configuration process to the ",(0,s.jsx)(n.code,{children:".env"})," file if you want (recommended), this is possible because the ",(0,s.jsx)(n.code,{children:"TinyOrm.pri"})," enables the ",(0,s.jsx)(n.a,{href:"#environment-files",children:(0,s.jsx)(n.code,{children:"Environment files"})})," feature by default."]}),"\n",(0,s.jsxs)(n.p,{children:["You can look at the ",(0,s.jsx)(n.a,{href:"/building/hello-world#auto-configure-using-qmake_conf-and-env",children:"Auto-configure using .qmake.conf and .env"})," example for ",(0,s.jsx)(n.code,{children:"Hello world"})," project of what must stay in the ",(0,s.jsx)(n.code,{children:"qmake.conf"})," file and what can be moved to the ",(0,s.jsx)(n.code,{children:".env"})," files."]}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["You can use the ",(0,s.jsxs)(n.a,{href:"#partial-guessing-of-the-tinyorm_build_tree",children:["Partial guessing of the ",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})]})," if you don't like to specify it manually."]})}),"\n",(0,s.jsxs)(n.h5,{id:"variables-affecting-tinyormpri",children:["Variables affecting ",(0,s.jsx)(n.code,{children:"TinyOrm.pri"})]}),"\n",(0,s.jsxs)(n.p,{children:["You must define the following variables before the ",(0,s.jsx)(n.code,{children:"TinyOrm.pri"})," is included:"]}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Variable Name"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})}),(0,s.jsxs)(n.td,{children:["Path to the ",(0,s.jsx)(n.code,{children:"TinyORM"})," build folder."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINY_VCPKG_ROOT"})}),(0,s.jsxs)(n.td,{children:["Path to the ",(0,s.jsx)(n.code,{children:"vcpkg"})," installation folder.",(0,s.jsx)("br",{}),"If not defined, then it tries to use the ",(0,s.jsx)(n.code,{children:"VCPKG_ROOT"})," environment variable."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINY_VCPKG_TRIPLET"})}),(0,s.jsxs)(n.td,{children:["The ",(0,s.jsx)(n.code,{children:"vcpkg"})," ",(0,s.jsx)(n.code,{children:"triplet"})," to use ",(0,s.jsx)("small",{children:"(vcpkg/installed/$$TINY_VCPKG_TRIPLET/)"}),".",(0,s.jsx)("br",{}),"If not defined, then it tries to guess the ",(0,s.jsx)(n.code,{children:"vcpkg"})," ",(0,s.jsx)(n.code,{children:"triplet"})," based on the current compiler and OS (based on the ",(0,s.jsx)(n.code,{children:"QMAKESPEC"}),"), and as the last thing, it tries to use the ",(0,s.jsx)(n.code,{children:"VCPKG_DEFAULT_TRIPLET"})," environment variable."]})]})]})]}),"\n",(0,s.jsx)(n.p,{children:"These variables will be set after the configuration is done:"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Variable Name"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINY_BUILD_SUBFOLDER"})}),(0,s.jsxs)(n.td,{children:["Folder by release type if ",(0,s.jsx)(n.code,{children:"CONFIG+=debug_and_release"})," is defined ",(0,s.jsx)("small",{children:"(/debug, /release, or an empty string)"}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINY_CCACHE_BUILD"})}),(0,s.jsxs)(n.td,{children:["To correctly link ",(0,s.jsx)(n.code,{children:"ccache"})," build against a ",(0,s.jsx)(n.code,{children:"ccache"})," build ",(0,s.jsx)("small",{children:"(_ccache or an empty string)"}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINY_MSVC_VERSION"})}),(0,s.jsxs)(n.td,{children:["The ",(0,s.jsx)(n.code,{children:"msvc"})," compiler string ",(0,s.jsx)("small",{children:"(MSVC2022 or MSVC2019)"}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINY_QT_VERSION_UNDERSCORED"})}),(0,s.jsxs)(n.td,{children:["Underscored ",(0,s.jsx)(n.code,{children:"Qt"})," version ",(0,s.jsx)("small",{children:"(eg. 6_7_0)"}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINY_RELEASE_TYPE_CAMEL"})}),(0,s.jsxs)(n.td,{children:["Build type string ",(0,s.jsx)("small",{children:"(Debug, Profile, or Release)"}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINY_VCPKG_INCLUDE"})}),(0,s.jsxs)(n.td,{children:["Path to the ",(0,s.jsx)(n.code,{children:"vcpkg"})," ",(0,s.jsx)(n.code,{children:"include"})," folder ",(0,s.jsx)("small",{children:"(vcpkg/installed//include/)"}),"."]})]})]})]}),"\n",(0,s.jsxs)(n.p,{children:["Then you simply include the ",(0,s.jsx)(n.code,{children:"TinyOrm.pri"})," in your project file."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",metastring:"title='AnyProject.pro'",children:"include($$TINY_MAIN_DIR/TinyORM/qmake/TinyOrm.pri)\n"})}),"\n",(0,s.jsxs)(n.p,{children:["And that is all, now you should be able to link against the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library. \ud83d\udc4c"]}),"\n",(0,s.jsx)(n.h5,{id:"manual-configuration-examples",children:"Manual configuration examples"}),"\n",(0,s.jsxs)(n.p,{children:["Frankly, there is no reason to use the Manual configuration (define the variables described below before the ",(0,s.jsx)(n.code,{children:"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."]}),"\n",(0,s.jsxs)(n.p,{children:["You will have to link against the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library manually if you don't set the ",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})," ",(0,s.jsx)(n.code,{children:"qmake"})," variable before the inclusion of the ",(0,s.jsx)(n.code,{children:"TinyOrm.pri"})," file. The ",(0,s.jsx)(n.code,{children:"INCLUDEPATH"})," is auto-detected every time."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:y.b,label:y.ux,children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",metastring:"{9}",children:"# Link against TinyORM library\n# ---\nTINY_MAIN_DIR = $$clean_path()\n\n# Configure TinyORM library\ninclude($$TINY_MAIN_DIR/TinyORM/qmake/TinyOrm.pri)\n\n# TinyORM library path\nTINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake)\nLIBS += $$quote(-L$$TINYORM_BUILD_TREE/build-TinyORM-Desktop_Qt_6_7_0_MSVC2019_64bit-Debug/src$${TINY_BUILD_SUBFOLDER}/)\nLIBS += -lTinyOrm\n"})})}),(0,s.jsx)(t.A,{value:y.xj,label:y.gg,children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",metastring:"{9}",children:"# Link against TinyORM library\n# ---\nTINY_MAIN_DIR = $$clean_path()\n\n# Configure TinyORM library\ninclude($$TINY_MAIN_DIR/TinyORM/qmake/TinyOrm.pri)\n\n# TinyORM library path\nTINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake)\nLIBS += $$quote(-L$$TINYORM_BUILD_TREE/build-TinyORM-Desktop_Qt_6_7_0_GCC_64bit-Debug/src$${TINY_BUILD_SUBFOLDER}/)\nLIBS += -lTinyOrm\n"})})})]}),"\n",(0,s.jsxs)(n.p,{children:["The same is true for the ",(0,s.jsx)(n.code,{children:"vcpkg"})," include path. If you don't set the ",(0,s.jsx)(n.code,{children:"TINY_VCPKG_ROOT"})," or have not defined the ",(0,s.jsx)(n.code,{children:"VCPKG_ROOT"})," environment variable, then you need to set up the ",(0,s.jsx)(n.code,{children:"INCLUDEPATH"})," for the ",(0,s.jsx)(n.code,{children:"vcpkg"})," that provides the ",(0,s.jsx)(n.code,{children:"range-v3"})," and ",(0,s.jsx)(n.code,{children:"tabulate"})," header files."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:y.b,label:y.ux,children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",children:"# vcpkg - range-v3 and tabulate\n# ---\nINCLUDEPATH += $$quote(/vcpkg/installed/x64-windows/include/)\n"})})}),(0,s.jsx)(t.A,{value:y.xj,label:y.gg,children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",children:"# vcpkg - range-v3 and tabulate\n# ---\nQMAKE_CXXFLAGS += -isystem $$shell_quote(/vcpkg/installed/x64-linux/include/)\n"})})})]}),"\n",(0,s.jsxs)(n.p,{children:["You can also use TinyORM's ",(0,s.jsx)(n.code,{children:"qmake"})," function ",(0,s.jsx)(n.code,{children:"tiny_add_system_includepath()"})," which handles ",(0,s.jsx)(n.code,{children:"INCLUDEPATH"})," in a cross-platform way."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",children:"# vcpkg - range-v3 and tabulate\n# ---\nload(tiny_system_includepath)\ntiny_add_system_includepath(/vcpkg/installed/x64-linux/include/)\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Do not forget to add ",(0,s.jsx)(n.code,{children:"TinyOrm0.dll"})," on the path on Windows and on the ",(0,s.jsx)(n.code,{children:"LD_LIBRARY_PATH"})," on Linux, so your application can find it during execution."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,name:"tinyorm-on-path",children:[(0,s.jsx)(t.A,{value:y.b,label:y.ux,children:(0,s.jsx)(c.A,{className:"language-powershell",children:`$env:Path = "${(0,x.OZ)(y.b,!1)}\\TinyORM\\TinyORM-builds-qmake\\build-debug;" + $env:Path`})}),(0,s.jsx)(t.A,{value:y.xj,label:y.gg,children:(0,s.jsx)(c.A,{className:"language-bash",children:`export LD_LIBRARY_PATH=${(0,x.OZ)(y.xj)}/TinyORM/TinyORM-builds-qmake/build-debug\${PATH:+:}$PATH`})})]}),"\n",(0,s.jsxs)(n.admonition,{type:"tip",children:[(0,s.jsxs)(n.p,{children:["On Linux ",(0,s.jsx)(n.code,{children:"-isystem"})," marks the directory as a system directory, it prevents warnings."]}),(0,s.jsxs)(n.p,{children:["On Windows you can use ",(0,s.jsx)(n.code,{children:"QMAKE_CXXFLAGS_WARN_ON = -external:anglebrackets -external:W0"}),", it applies a warning level 0 to the angel bracket includes; ",(0,s.jsx)(n.code,{children:"#include "}),"."]}),(0,s.jsxs)(n.p,{children:["With the ",(0,s.jsx)(n.code,{children:"clang-cl"})," with ",(0,s.jsx)(n.code,{children:"MSVC"})," you can use ",(0,s.jsx)(n.code,{children:"-imsvc"}),"."]})]}),"\n",(0,s.jsx)(n.h3,{id:"auto-configuration-internals",children:"Auto-configuration internals"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"qmake"})," build system does not support ",(0,s.jsx)(n.code,{children:"auto-configuration"})," of dependencies out of the box but ",(0,s.jsx)(n.code,{children:"TinyORM"})," from ",(0,s.jsx)(n.code,{children:"v0.34.0"})," added its own ",(0,s.jsx)(n.code,{children:"Auto-configuration"})," feature along with the ",(0,s.jsx)(n.code,{children:"tiny_dotenv"})," qmake feature. These new features allow us to ",(0,s.jsx)(n.code,{children:"auto-configure"})," ",(0,s.jsx)(n.code,{children:"TinyORM"})," project, and with their help, the ",(0,s.jsx)(n.code,{children:"conf.pri"})," files can be ",(0,s.jsx)("u",{children:"skipped entirely"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["While it adds additional complexity to the ",(0,s.jsx)(n.code,{children:"qmake"})," configuration process, the benefits are significant."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"Auto-configuration"})," feature is designed to find the ",(0,s.jsx)(n.code,{children:"vcpkg"})," and ",(0,s.jsx)(n.code,{children:"MySQL"})," installations, and ",(0,s.jsx)(n.code,{children:"tiny_dotenv"})," to include the ",(0,s.jsx)(n.code,{children:".env"})," and ",(0,s.jsx)(n.code,{children:".env.(win32|unix|mingw)"})," files in the project's root folder. These new features can be configured using ",(0,s.jsx)(n.code,{children:"qmake"})," and ",(0,s.jsx)(n.code,{children:"environment"})," variables, and they also contain some guessing logic if these variables are not defined."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"Auto-configuration"})," feature can be turned off using the ",(0,s.jsx)(n.a,{href:"#disable_autoconf",children:(0,s.jsx)(n.code,{children:"disable_autoconf"})})," ",(0,s.jsx)(n.code,{children:"qmake"})," configuration option (eg. ",(0,s.jsx)(n.code,{children:"CONFIG*=disable_autoconf"}),")."]}),"\n",(0,s.jsxs)(n.p,{children:["These are ",(0,s.jsx)("u",{children:(0,s.jsx)(n.code,{children:"qmake"})})," and ",(0,s.jsx)("u",{children:(0,s.jsx)(n.code,{children:"environment"})})," variables that affect the ",(0,s.jsx)(n.code,{children:"Auto-configuration"})," feature:"]}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Variable Name"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINY_VCPKG_ROOT"})}),(0,s.jsxs)(n.td,{children:["Path to the ",(0,s.jsx)(n.code,{children:"vcpkg"})," installation folder.",(0,s.jsx)("br",{}),"If not defined, then it tries to use the ",(0,s.jsx)(n.code,{children:"VCPKG_ROOT"})," environment variable."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINY_VCPKG_TRIPLET"})}),(0,s.jsxs)(n.td,{children:["The ",(0,s.jsx)(n.code,{children:"vcpkg"})," ",(0,s.jsx)(n.code,{children:"triplet"})," to use ",(0,s.jsx)("small",{children:"(vcpkg/installed/$$TINY_VCPKG_TRIPLET/)"}),".",(0,s.jsx)("br",{}),"If not defined, then it tries to guess the ",(0,s.jsx)(n.code,{children:"vcpkg"})," ",(0,s.jsx)(n.code,{children:"triplet"})," based on the current compiler and OS (based on the ",(0,s.jsx)(n.code,{children:"QMAKESPEC"}),"), and as the last thing, it tries to use the ",(0,s.jsx)(n.code,{children:"VCPKG_DEFAULT_TRIPLET"})," environment variable."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINY_MYSQL_ROOT"})}),(0,s.jsxs)(n.td,{children:["Path to the ",(0,s.jsx)(n.code,{children:"MySQL"})," installation folder.",(0,s.jsx)("br",{}),"If not defined, then it tries to guess the ",(0,s.jsx)(n.code,{children:"MySQL"})," installation folder (",(0,s.jsx)(n.code,{children:"win32"})," only): ",(0,s.jsx)("code",{children:"$$(ProgramFiles)/MySQL/MySQL Server (8.4|8.3|8.2|8.1|8.0|5.7)/"})]})]})]})]}),"\n",(0,s.jsxs)(n.p,{children:["You can set these variables in the ",(0,s.jsx)(n.code,{children:".env"})," (recommended) or ",(0,s.jsx)(n.code,{children:"conf.pri"})," files, in the ",(0,s.jsx)(n.code,{children:".qmake.conf"})," file (or wherever you want), or as environment variables."]}),"\n",(0,s.jsxs)(n.p,{children:["These variables will be set after ",(0,s.jsx)(n.code,{children:"auto-configuration"})," is done:"]}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Variable Name"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINY_VCPKG_INCLUDE"})}),(0,s.jsxs)(n.td,{children:["Path to the ",(0,s.jsx)(n.code,{children:"vcpkg"})," ",(0,s.jsx)(n.code,{children:"include"})," folder ",(0,s.jsx)("small",{children:"(vcpkg/installed//include/)"}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINY_MYSQL_INCLUDE"})}),(0,s.jsxs)(n.td,{children:["Path to the ",(0,s.jsx)(n.code,{children:"MySQL"})," ",(0,s.jsx)(n.code,{children:"include"})," folder ",(0,s.jsx)("small",{children:"(MySQL Server 8.4/include/)"}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINY_MYSQL_LIB"})}),(0,s.jsxs)(n.td,{children:["Path to the ",(0,s.jsx)(n.code,{children:"MySQL"})," ",(0,s.jsx)(n.code,{children:"lib"})," folder ",(0,s.jsx)("small",{children:"(MySQL Server 8.4/lib/)"}),"."]})]})]})]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"TINY_MYSQL_INCLUDE"})," and ",(0,s.jsx)(n.code,{children:"TINY_MYSQL_LIB"})," are only set on ",(0,s.jsx)(n.code,{children:"win32"})," platform except ",(0,s.jsx)(n.code,{children:"mingw"}),"."]}),"\n",(0,s.jsx)(n.h4,{id:"environment-files",children:"Environment files"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"tiny_dotenv"})," feature allows us to define the ",(0,s.jsx)(n.code,{children:".env"})," and ",(0,s.jsx)(n.code,{children:".env.$$TINY_DOTENV_PLATFORM"})," files in the project's root folder. These files are loaded as early as possible so you can affect the ",(0,s.jsx)(n.code,{children:"qmake"})," configuration process. On the other hand, the ",(0,s.jsx)(n.code,{children:"conf.pri"})," files are loaded as late as possible, and they can be used to override the ",(0,s.jsx)(n.code,{children:"qmake"})," configuration."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:".env"})," file is included ",(0,s.jsx)("u",{children:"first"})," and is included on all platforms."]}),"\n",(0,s.jsxs)(n.p,{children:["There is only one requirement for this feature to work correctly, and that is to set the ",(0,s.jsx)(n.code,{children:"TINY_DOTENV_ROOT"})," ",(0,s.jsx)(n.code,{children:"qmake"})," variable to the project's root folder. This variable is ",(0,s.jsx)(n.strong,{children:"already"})," set in the ",(0,s.jsx)(n.code,{children:".qmake.conf"})," file for the ",(0,s.jsx)(n.code,{children:"TinyORM"})," project."]}),"\n",(0,s.jsx)(n.p,{children:"Then the following names are taken into account: .env, .env.win32, .env.unix, .env.mingw"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",metastring:"title='.qmake.conf'",children:"# To find .env and .env.$$QMAKE_PLATFORM files\nTINY_DOTENV_ROOT = $$PWD\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"tiny_dotenv"})," feature can be turned off using the ",(0,s.jsx)(n.a,{href:"#disable_dotenv",children:(0,s.jsx)(n.code,{children:"disable_dotenv"})})," ",(0,s.jsx)(n.code,{children:"qmake"})," configuration option (eg. ",(0,s.jsx)(n.code,{children:"CONFIG*=disable_dotenv"}),")."]}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Environment files"})," don't work in the ",(0,s.jsx)(n.code,{children:"CMake"})," builds."]})}),"\n",(0,s.jsxs)(n.h4,{id:"partial-guessing-of-the-tinyorm_build_tree",children:["Partial guessing of the ",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})]}),"\n",(0,s.jsxs)(n.p,{children:["You don't have to manually define the ",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})," in ",(0,s.jsx)(n.code,{children:".env"})," or ",(0,s.jsx)(n.code,{children:".qmake.conf"})," files. The ",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})," absolute path can be put together for you (this is happening inside the ",(0,s.jsx)(n.code,{children:"variables.pri"})," file) and ",(0,s.jsx)(n.code,{children:"TinyORM"})," build folder name can be guessed for you too."]}),"\n",(0,s.jsxs)(n.p,{children:["You must define the following variables before the ",(0,s.jsx)(n.code,{children:"TinyOrm.pri"})," will be included to make this real (set them in the ",(0,s.jsx)(n.code,{children:".qmake.conf"}),"):"]}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Variable Name"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINY_MAIN_DIR"})}),(0,s.jsxs)(n.td,{children:["Path to the ",(0,s.jsx)(n.strong,{children:"PARENT"})," folder of the ",(0,s.jsx)(n.code,{children:"TinyORM"})," source folder."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINY_BUILD_TREE"})}),(0,s.jsxs)(n.td,{children:["Path to the ",(0,s.jsx)(n.strong,{children:"current"})," build tree - ",(0,s.jsx)(n.code,{children:"TINY_BUILD_TREE = $$shadowed($$PWD)"}),"."]})]})]})]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"TINY_MAIN_DIR"})," is required for another features anyway (so it should already be set) and all that's left is to set the ",(0,s.jsx)(n.code,{children:"TINY_BUILD_TREE"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",metastring:"title='.qmake.conf'",children:"# Path to the current build tree (used to guess the TinyORM build tree)\nTINY_BUILD_TREE = $$shadowed($$PWD)\n"})}),"\n",(0,s.jsxs)(n.p,{children:["If you will follow this pattern or logic then you can switch ",(0,s.jsx)(n.code,{children:"QtCreator Kits"})," and the ",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})," will be ",(0,s.jsx)(n.strong,{children:"auto-generated"})," correctly and will always point to the correct ",(0,s.jsx)(n.code,{children:"TinyORM"})," build tree."]}),"\n",(0,s.jsxs)(n.p,{children:["It works this way, all is happening inside the ",(0,s.jsx)(n.code,{children:"variables.pri"}),", it takes a build folder name for the ",(0,s.jsx)(n.strong,{children:"current"})," project eg. ",(0,s.jsx)(n.code,{children:"build-HelloWorld-Desktop_Qt_6_7_0_MSVC2022_64bit-Debug"}),", replaces the ",(0,s.jsx)(n.code,{children:"HelloWorld"})," with the ",(0,s.jsx)(n.code,{children:"TinyORM"})," and as we already know the ",(0,s.jsx)(n.code,{children:"TinyORM"})," build folder location we can simply concatenate these paths like ",(0,s.jsx)(n.code,{children:"$$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_0_MSVC2022_64bit-Debug"}),"."]}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsxs)(n.p,{children:["This will only work if you follow the recommended ",(0,s.jsx)(n.a,{href:"#folders-structure",children:(0,s.jsx)(n.code,{children:"Folders structure"})}),"."]})}),"\n",(0,s.jsx)(n.h3,{id:"manual-configuration-internals",children:"Manual configuration internals"}),"\n",(0,s.jsxs)(n.p,{children:["There is not much to say about the ",(0,s.jsx)(n.code,{children:"Manual configuration"})," feature. It uses ",(0,s.jsx)(n.code,{children:"conf.pri"})," files (there are four, one for every project or sub-project), and every project has prepared its own ",(0,s.jsx)(n.code,{children:"conf.pri.example"})," file for faster initial configuration."]}),"\n",(0,s.jsxs)(n.p,{children:["These ",(0,s.jsx)(n.code,{children:"conf.pri.example"})," files are nicely commented on, so you can see what needs to be modified. The ",(0,s.jsx)(n.code,{children:"conf.pri"})," files are loaded as late as possible, and they can be used to override the ",(0,s.jsx)(n.code,{children:"qmake"})," configuration."]}),"\n",(0,s.jsxs)(n.p,{children:["If the ",(0,s.jsx)(n.code,{children:"Auto-configuration"})," feature is disabled and there are no ",(0,s.jsx)(n.code,{children:"conf.pri"})," files, then the ",(0,s.jsx)(n.code,{children:"TinyORM"})," ",(0,s.jsx)(n.code,{children:"qmake"})," configuration or build will fail at 100%."]}),"\n",(0,s.jsxs)(n.p,{children:["These ",(0,s.jsx)(n.code,{children:"conf.pri"})," files are intended for configuring qmake's ",(0,s.jsx)(n.code,{children:"INCLUDEPATH"})," and ",(0,s.jsx)(n.code,{children:"LIBS"}),", ",(0,s.jsx)(n.code,{children:"CONFIG"})," or eg. ",(0,s.jsx)(n.code,{children:"QMAKE_LFLAGS"}),", or any other ",(0,s.jsx)(n.code,{children:"qmake"})," options or variables."]}),"\n",(0,s.jsx)(n.h2,{id:"ccache-support",children:"Ccache support"}),"\n",(0,s.jsxs)(n.p,{children:["The TinyORM supports the ",(0,s.jsx)(n.a,{href:"https://ccache.dev/",children:(0,s.jsx)(n.code,{children:"ccache"})})," out of the box for all ",(0,s.jsx)(n.a,{href:"/supported-compilers",children:"supported compilers"}),". For ",(0,s.jsx)(n.code,{children:"qmake"})," you can enable it using the ",(0,s.jsx)(n.a,{href:"#ccache",children:(0,s.jsx)(n.code,{children:"CONFIG+=ccache"})})," and for ",(0,s.jsx)(n.code,{children:"CMake"})," you can set the ",(0,s.jsx)(n.a,{href:"#CMAKE_CXX_COMPILER_LAUNCHER",children:(0,s.jsx)(n.code,{children:"CMAKE_CXX_COMPILER_LAUNCHER=ccache"})}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["On ",(0,s.jsx)(n.code,{children:"Linux"})," it's clear, the ",(0,s.jsx)(n.code,{children:"ccache"})," is fully supported and works also with the ",(0,s.jsx)(n.code,{children:"precompiled headers"}),". But was necessary to add some workarounds to the ",(0,s.jsx)(n.code,{children:"qmake"}),"/",(0,s.jsx)(n.code,{children:"CMake"})," build systems to make out of the box support on ",(0,s.jsx)(n.code,{children:"Windows"}),". When you enable the ",(0,s.jsx)(n.code,{children:"ccache"})," on ",(0,s.jsx)(n.code,{children:"Windows"})," then the build system disables ",(0,s.jsx)(n.code,{children:"precompiled headers"})," and replaces the ",(0,s.jsx)(n.code,{children:"-Zi"})," compiler option with the ",(0,s.jsx)(n.code,{children:"-Z7"})," (link to the ",(0,s.jsx)(n.a,{href:"https://github.com/ccache/ccache/issues/1040",children:"issue"}),")."]}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["You can install the ",(0,s.jsx)(n.code,{children:"ccache"})," using the ",(0,s.jsx)(n.code,{children:"scoop install ccache"})," command on Windows. See the ",(0,s.jsx)(n.a,{href:"/dependencies#linux-installation-ccache",children:"Dependencies"})," page for how to install ",(0,s.jsx)(n.code,{children:"ccache"})," on Linux."]})})]})}function I(e={}){const{wrapper:n}={...(0,d.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(M,{...e})}):M(e)}},9365:(e,n,i)=>{i.d(n,{A:()=>l});i(6540);var s=i(4164);const d={tabItem:"tabItem_Ymn6"};var r=i(4848);function l(e){let{children:n,hidden:i,className:l}=e;return(0,r.jsx)("div",{role:"tabpanel",className:(0,s.A)(d.tabItem,l),hidden:i,children:n})}},1470:(e,n,i)=>{i.d(n,{A:()=>_});var s=i(6540),d=i(4164),r=i(3104),l=i(6347),c=i(205),t=i(7485),o=i(1682),a=i(9466);function h(e){return s.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,s.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function x(e){const{values:n,children:i}=e;return(0,s.useMemo)((()=>{const e=n??function(e){return h(e).map((e=>{let{props:{value:n,label:i,attributes:s,default:d}}=e;return{value:n,label:i,attributes:s,default:d}}))}(i);return function(e){const n=(0,o.X)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[n,i])}function j(e){let{value:n,tabValues:i}=e;return i.some((e=>e.value===n))}function u(e){let{queryString:n=!1,groupId:i}=e;const d=(0,l.W6)(),r=function(e){let{queryString:n=!1,groupId:i}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!i)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return i??null}({queryString:n,groupId:i});return[(0,t.aZ)(r),(0,s.useCallback)((e=>{if(!r)return;const n=new URLSearchParams(d.location.search);n.set(r,e),d.replace({...d.location,search:n.toString()})}),[r,d])]}function p(e){const{defaultValue:n,queryString:i=!1,groupId:d}=e,r=x(e),[l,t]=(0,s.useState)((()=>function(e){let{defaultValue:n,tabValues:i}=e;if(0===i.length)throw new Error("Docusaurus error: the component requires at least one children component");if(n){if(!j({value:n,tabValues:i}))throw new Error(`Docusaurus error: The has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${i.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const s=i.find((e=>e.default))??i[0];if(!s)throw new Error("Unexpected error: 0 tabValues");return s.value}({defaultValue:n,tabValues:r}))),[o,h]=u({queryString:i,groupId:d}),[p,m]=function(e){let{groupId:n}=e;const i=function(e){return e?`docusaurus.tab.${e}`:null}(n),[d,r]=(0,a.Dv)(i);return[d,(0,s.useCallback)((e=>{i&&r.set(e)}),[i,r])]}({groupId:d}),b=(()=>{const e=o??p;return j({value:e,tabValues:r})?e:null})();(0,c.A)((()=>{b&&t(b)}),[b]);return{selectedValue:l,selectValue:(0,s.useCallback)((e=>{if(!j({value:e,tabValues:r}))throw new Error(`Can't select invalid tab value=${e}`);t(e),h(e),m(e)}),[h,m,r]),tabValues:r}}var m=i(2303);const b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var f=i(4848);function g(e){let{className:n,block:i,selectedValue:s,selectValue:l,tabValues:c}=e;const t=[],{blockElementScrollPositionUntilNextRender:o}=(0,r.a_)(),a=e=>{const n=e.currentTarget,i=t.indexOf(n),d=c[i].value;d!==s&&(o(n),l(d))},h=e=>{let n=null;switch(e.key){case"Enter":a(e);break;case"ArrowRight":{const i=t.indexOf(e.currentTarget)+1;n=t[i]??t[0];break}case"ArrowLeft":{const i=t.indexOf(e.currentTarget)-1;n=t[i]??t[t.length-1];break}}n?.focus()};return(0,f.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,d.A)("tabs",{"tabs--block":i},n),children:c.map((e=>{let{value:n,label:i,attributes:r}=e;return(0,f.jsx)("li",{role:"tab",tabIndex:s===n?0:-1,"aria-selected":s===n,ref:e=>t.push(e),onKeyDown:h,onClick:a,...r,className:(0,d.A)("tabs__item",b.tabItem,r?.className,{"tabs__item--active":s===n}),children:i??n},n)}))})}function y(e){let{lazy:n,children:i,selectedValue:d}=e;const r=(Array.isArray(i)?i:[i]).filter(Boolean);if(n){const e=r.find((e=>e.props.value===d));return e?(0,s.cloneElement)(e,{className:"margin-top--md"}):null}return(0,f.jsx)("div",{className:"margin-top--md",children:r.map(((e,n)=>(0,s.cloneElement)(e,{key:n,hidden:e.props.value!==d})))})}function T(e){const n=p(e);return(0,f.jsxs)("div",{className:(0,d.A)("tabs-container",b.tabList),children:[(0,f.jsx)(g,{...n,...e}),(0,f.jsx)(y,{...n,...e})]})}function _(e){const n=(0,m.A)();return(0,f.jsx)(T,{...e,children:h(e.children)},String(n))}},6684:(e,n,i)=>{i.d(n,{A:()=>a});var s=i(6540),d=i(3427),r=i(6347);const l={apiTable:"apiTable_flxF"};var c=i(4848);function t(e,n){let{name:i,children:l}=e;const t=function(e){let n=e;for(;(0,s.isValidElement)(n);)[n]=s.Children.toArray(n.props.children);if("string"!=typeof n)throw new Error(`Could not extract APITable row name from JSX tree:\n${JSON.stringify(e,null,2)}`);return n}(l),o=i?`${i}-${t}`:t,a=`#${o}`,h=(0,r.W6)();return(0,d.A)().collectAnchor(o),(0,c.jsx)("tr",{id:o,tabIndex:0,ref:h.location.hash===a?n:void 0,onClick:e=>{const n=e.target;[n,n.parentElement].some((e=>"A"===e?.tagName.toUpperCase()))||h.push(a)},onKeyDown:e=>{"Enter"===e.key&&h.push(a)},children:l.props.children})}const o=s.forwardRef(t);function a(e){let{children:n,name:i}=e;if("table"!==n.type)throw new Error("Bad usage of APITable component.\nIt is probably that your Markdown table is malformed.\nMake sure to double-check you have the appropriate number of columns for each table row.");const[d,r]=s.Children.toArray(n.props.children),t=(0,s.useRef)(null);(0,s.useEffect)((()=>{t.current?.focus()}),[t]);const a=s.Children.map(r.props.children,(e=>(0,c.jsx)(o,{name:i,ref:t,children:e})));return(0,c.jsxs)("table",{className:l.apiTable,children:[d,(0,c.jsx)("tbody",{children:a})]})}},7324:(e,n,i)=>{i.d(n,{$E:()=>m,A3:()=>f,CW:()=>b,Dx:()=>a,F4:()=>x,Fi:()=>o,J_:()=>_,LQ:()=>g,Lf:()=>v,OO:()=>d,Q7:()=>y,b:()=>c,cy:()=>t,gg:()=>u,kl:()=>j,os:()=>h,pW:()=>r,ux:()=>p,vf:()=>s,xj:()=>l,xt:()=>T});const s="shell",d="database",r="application",l="bash",c="pwsh",t="zsh",o="maria",a="mysql",h="postgres",x="sqlite",j="application",u="bash",p="pwsh",m="zsh",b="MariaDB",f="MySQL",g="PostgreSQL",y="SQLite",T="tinyorm.org",_="$HOME/Code/c/",v="$env:USERPROFILE\\Code\\c\\"},6362:(e,n,i)=>{i.d(n,{A:()=>r});var s=i(6540),d=i(1838);function r(){const e=(0,s.useContext)(d.A);if(null!=e)return e;throw new Error("useRootFolderContext is used outside of Layout component.")}},6694:(e,n,i)=>{i.d(n,{OZ:()=>t,Sn:()=>l,T3:()=>a,bw:()=>o,nC:()=>h,np:()=>c});var s=i(6362),d=i(2303),r=i(7324);const l=function(e,n){return void 0===n&&(n=!0),x((0,s.A)().rootFolder[e]??o(e),e,n)},c=()=>(0,s.A)().rootFolder[r.pW]??o(r.pW),t=function(e,n){if(void 0===n&&(n=!0),null==e)throw new Error("The groupId in the applicationFolderPath() can not be empty.");const i=n||e!==r.b?"/":"\\";return x(l(e)+i+c(),e,n)};function o(e){if(null==e)throw new Error("The groupId in the folderDefaultValue() can not be empty.");if(!(0,d.A)())return"";switch(e){case r.b:return r.Lf;case r.xj:return r.J_;case r.pW:return r.xt;default:throw new Error(`No default value for '${e}' groupId in the folderDefaultValue().`)}}function a(e){return e===r.pW}function h(e,n){if(null==n||""===n)return n;const i="$ENV{$1}$2";switch(e){case r.b:return u(n).replace(/\$env:(.+?)(\/.*)/,i);case r.xj:return n.replace(/\$(.+?)(\/.*)/,i);default:throw new Error(`Unsupported shell type '${e}' in the convertToCmakeEnvVariable().`)}}function x(e,n,i){if(void 0===i&&(i=!0),null==e||""===e)return e;if(n!==r.b)return j(e);const s=j(e);return i?u(s):function(e){return null==e||""===e?e:e.replaceAll(/\/+/g,"\\")}(s)}function j(e){return null==e||""===e?e:e.replace(/[/\\]+$/,"")}function u(e){return null==e||""===e?e:e.replaceAll(/\\+(?! )/g,"/")}},2721:(e,n,i)=>{i.d(n,{A:()=>s});const s=i.p+"assets/images/qmake-additional_arguments-14d3b6b82ad6d28db5b999a462500a6a.png"},7619:(e,n,i)=>{i.d(n,{A:()=>s});const s=i.p+"assets/images/qmake-build_settings-7caa6d7c86232484b82acb24b5a3a6a7.png"},885:(e,n,i)=>{i.d(n,{A:()=>s});const s=i.p+"assets/images/qmake-configure_project-0b6821ea0523567dab9f21b3215055a3.png"}}]); \ No newline at end of file +"use strict";(self.webpackChunktinyorm_org=self.webpackChunktinyorm_org||[]).push([[395],{993:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>O,contentTitle:()=>_,default:()=>I,frontMatter:()=>T,metadata:()=>v,toc:()=>R});var s=i(4848),d=i(8453),r=i(8774),l=i(6684),c=i(2364),t=i(9365),o=i(1470),a=i(5556),h=i.n(a),x=i(6694);function j(e){let{groupId:n}=e;return(0,s.jsx)("span",{children:(0,x.OZ)(n)})}j.propTypes={groupId:h().string.isRequired};const u=j;var p=i(4164),m=i(6362);const b={rootFolderInput:"rootFolderInput_ottS",input:"input_OR7e",application:"application_fjej"};function f(e){let{groupId:n,label:i}=e;const{rootFolder:d,setRootFolder:r}=(0,m.A)(),l=(0,x.T3)(n),c=l?"application":"root",t=l?"\nThis folder name is common for all shells (eg. pwsh, bash, ...)":"";return(0,s.jsx)("form",{name:"tinyorm-root-folder-form",className:(0,p.A)(b.rootFolderInput,b[n],n),onSubmit:e=>{e.preventDefault(),e.stopPropagation()},children:(0,s.jsx)("input",{name:"tinyorm-root-folder-input",className:(0,p.A)(b.input,b[n],n),placeholder:`Enter ${c} folder...`,title:`This ${c} folder will be used in all ${i} examples at tinyorm.org${t}`,onChange:e=>{r(n,e.target.value)},value:d[n]??(0,x.bw)(n)})})}f.propTypes={groupId:h().string.isRequired,label:h().string.isRequired};const g=f;var y=i(7324);const T={sidebar_position:0,sidebar_label:"TinyORM",hide_table_of_contents:!0,description:"How to compile the TinyORM C++ library on Windows and Linux.",keywords:["c++ orm","building","tinyorm"]},_="Building: TinyORM",v={id:"building/tinyorm",title:"Building: TinyORM",description:"How to compile the TinyORM C++ library on Windows and Linux.",source:"@site/docs/building/tinyorm.mdx",sourceDirName:"building",slug:"/building/tinyorm",permalink:"/building/tinyorm",draft:!1,unlisted:!1,tags:[],version:"current",sidebarPosition:0,frontMatter:{sidebar_position:0,sidebar_label:"TinyORM",hide_table_of_contents:!0,description:"How to compile the TinyORM C++ library on Windows and Linux.",keywords:["c++ orm","building","tinyorm"]},sidebar:"tinyormSidebar",previous:{title:"Getting Started",permalink:"/tinydrivers/getting-started"},next:{title:"Hello world",permalink:"/building/hello-world"}},O={},R=[{value:"Introduction",id:"introduction",level:2},{value:"Common Prerequisites",id:"common-prerequisites",level:4},{value:"Windows Prerequisites",id:"windows-prerequisites",level:4},{value:"Build environment scripts",id:"build-environment-scripts",level:5},{value:"Allow symbolic links unprivileged",id:"allow-symbolic-links-unprivileged",level:5},{value:"Folders structure",id:"folders-structure",level:2},{value:"Getting started",id:"getting-started",level:2},{value:"vcpkg",id:"vcpkg",level:2},{value:"Set up vcpkg environment",id:"set-up-vcpkg-environment",level:4},{value:"C preprocessor macros",id:"c-preprocessor-macros",level:2},{value:"Building with CMake",id:"building-with-cmake",level:2},{value:"Configure & Build (cmake)",id:"configure-and-build-cmake",level:3},{value:"CMake STRICT_MODE option",id:"cmake-strict_mode-option",level:5},{value:"Build TinyORM",id:"build-tinyorm",level:4},{value:"CMake build options",id:"cmake-build-options",level:3},{value:"Consume TinyOrm library (cmake)",id:"consume-tinyorm-library-cmake",level:3},{value:"Building with qmake",id:"building-with-qmake",level:2},{value:"Install dependencies",id:"install-dependencies",level:3},{value:"Configure & Build (qmake)",id:"configure-and-build-qmake",level:3},{value:"Open QtCreator IDE",id:"open-qtcreator-ide",level:4},{value:"Configure TinyORM",id:"configure-tinyorm",level:4},{value:"Auto-configuration and tiny_dotenv",id:"auto-configuration-and-tiny_dotenv",level:5},{value:"Manual configuration (conf.pri)",id:"manual-configuration-confpri",level:5},{value:"Opening TinyORM.pro (main project file)",id:"opening-tinyormpro-main-project-file",level:5},{value:"Build TinyORM",id:"build-tinyorm-1",level:4},{value:"qmake build options",id:"qmake-build-options",level:3},{value:"Consume TinyOrm library (qmake)",id:"consume-tinyorm-library-qmake",level:3},{value:"Requirements",id:"requirements",level:4},{value:"QMAKEFEATURES",id:"qmakefeatures",level:5},{value:"Variables affecting TinyOrm.pri",id:"variables-affecting-tinyormpri",level:5},{value:"Manual configuration examples",id:"manual-configuration-examples",level:5},{value:"Auto-configuration internals",id:"auto-configuration-internals",level:3},{value:"Environment files",id:"environment-files",level:4},{value:"Partial guessing of the TINYORM_BUILD_TREE",id:"partial-guessing-of-the-tinyorm_build_tree",level:4},{value:"Manual configuration internals",id:"manual-configuration-internals",level:3},{value:"Ccache support",id:"ccache-support",level:2}];function M(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",h5:"h5",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,d.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"building-tinyorm",children:"Building: TinyORM"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#introduction",children:"Introduction"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#common-prerequisites",children:"Common Prerequisites"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#windows-prerequisites",children:"Windows Prerequisites"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#folders-structure",children:"Folders structure"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#getting-started",children:"Getting started"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#vcpkg",children:"vcpkg"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#c-preprocessor-macros",children:"C preprocessor macros"})}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#building-with-cmake",children:"Building with CMake"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#configure-and-build-cmake",children:"Configure & Build"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#cmake-build-options",children:"CMake build options"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#consume-tinyorm-library-cmake",children:"Consume TinyOrm library"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#building-with-qmake",children:"Building with qmake"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#install-dependencies",children:"Install dependencies"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#configure-and-build-qmake",children:"Configure & Build"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#qmake-build-options",children:"qmake build options"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#consume-tinyorm-library-qmake",children:"Consume TinyOrm library"})}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#auto-configuration-internals",children:"Auto-configuration internals"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#environment-files",children:"Environment files"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#manual-configuration-internals",children:"Manual configuration internals"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#ccache-support",children:"Ccache support"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsxs)(n.p,{children:["The build systems supported out of the box are ",(0,s.jsx)(n.code,{children:"CMake"})," and ",(0,s.jsx)(n.code,{children:"qmake"}),"."]}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["All examples below assume that ",(0,s.jsx)(n.code,{children:"pwsh"})," runs on ",(0,s.jsx)(n.code,{children:"Windows"})," and ",(0,s.jsx)(n.code,{children:"bash"})," runs on ",(0,s.jsx)(n.code,{children:"Linux"}),"."]})}),"\n",(0,s.jsx)(n.h4,{id:"common-prerequisites",children:"Common Prerequisites"}),"\n",(0,s.jsxs)(n.p,{children:["Install the required ",(0,s.jsx)(n.a,{href:"/dependencies",children:"dependencies"})," before starting."]}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"QSqlDatabase"})," depends on ",(0,s.jsx)(n.code,{children:"QCoreApplication"})," from ",(0,s.jsx)(n.code,{children:"Qt v6.5.3"})," so you must create the ",(0,s.jsx)(n.code,{children:"QCoreApplication"})," instance before you will call anything from the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library. \ud83e\udee4 The change was made ",(0,s.jsx)(n.a,{href:"https://github.com/qt/qtbase/commit/8d2bdc9cd5482eace12ba7e45304857bd24db0e6#diff-1d355c25c0b0eddec2be48253407780c4dc510d986739aec61e1ec892ccaf86e",children:"here"}),"."]})}),"\n",(0,s.jsx)(n.h4,{id:"windows-prerequisites",children:"Windows Prerequisites"}),"\n",(0,s.jsx)(n.h5,{id:"build-environment-scripts",children:"Build environment scripts"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"Visual Studio"})," does not provide ",(0,s.jsx)(n.code,{children:"vcvars"})," scripts for ",(0,s.jsx)(n.code,{children:"pwsh"}),", you can use ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/tree/main/tools/vcvars64.ps1",children:(0,s.jsx)(n.code,{children:"vcvars64.ps1"})})," provided by ",(0,s.jsx)(n.code,{children:"TinyORM"})," in the ",(0,s.jsx)(n.code,{children:"tools/"})," folder. Place them on the ",(0,s.jsx)(n.code,{children:"$env:Path"})," user/system path and they will be available system-wide."]}),"\n",(0,s.jsxs)(n.p,{children:["The same is true for the ",(0,s.jsx)(n.code,{children:"Qt Framework"}),", it doesn't provide ",(0,s.jsx)(n.code,{children:"qtenv"})," scripts for ",(0,s.jsx)(n.code,{children:"pwsh"})," too. You can create your own script, place it on the ",(0,s.jsx)(n.code,{children:"$env:Path"})," user/system path and it will be available system-wide."]}),"\n",(0,s.jsxs)(n.p,{children:["Here is one simple example for ",(0,s.jsx)(n.code,{children:"pwsh"}),"."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:"qtenv6.ps1",label:"qtenv6.ps1",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-powershell",children:"#!/usr/bin/env pwsh\n\nSet-StrictMode -Version 3.0\n\nWrite-Host 'Setting up environment for Qt 6.7.1 usage...' -ForegroundColor Magenta\nWrite-Host\n\n$Script:QtRoot = $env:TINY_QT_ROOT ?? 'C:\\Qt'\n\n$env:Path = \"$Script:QtRoot\\6.7.1\\msvc2019_64\\bin;\" + $env:Path\n\n. vcvars64.ps1\n"})})}),(0,s.jsx)(t.A,{value:"qtenv5.ps1",label:"qtenv5.ps1",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-powershell",children:"#!/usr/bin/env pwsh\n\nSet-StrictMode -Version 3.0\n\nWrite-Host 'Setting up environment for Qt 5.15.2 usage...' -ForegroundColor Magenta\nWrite-Host\n\n$Script:QtRoot = $env:TINY_QT_ROOT ?? 'C:\\Qt'\n\n$env:Path = \"$Script:QtRoot\\5.15.2\\msvc2019_64\\bin;\" + $env:Path\n\n. vcvars64.ps1\n"})})})]}),"\n",(0,s.jsxs)(n.p,{children:["And here for ",(0,s.jsx)(n.code,{children:"Linux"}),"."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:"qtenv6",label:"qtenv6",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'#!/usr/bin/env sh\n\necho \'Setting up environment for Qt 6.7.1 usage...\'\n\nQtRoot="${TINY_QT_ROOT:-/opt/Qt}"\n\nexport PATH="$QtRoot/6.7.1/gcc_64/bin"${PATH:+:}$PATH\nexport LD_LIBRARY_PATH="$QtRoot/6.7.1/gcc_64/lib"${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH\n'})})}),(0,s.jsx)(t.A,{value:"qtenv5",label:"qtenv5",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'#!/usr/bin/env sh\n\necho \'Setting up environment for Qt 5.15.2 usage...\'\n\nQtRoot="${TINY_QT_ROOT:-/opt/Qt}"\n\nexport PATH="$QtRoot/5.15.2/gcc_64/bin"${PATH:+:}$PATH\nexport LD_LIBRARY_PATH="$QtRoot/5.15.2/gcc_64/lib"${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH\n'})})})]}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["These scripts consider the ",(0,s.jsx)(n.code,{children:"TINY_QT_ROOT"})," environment variable that should point to the ",(0,s.jsx)(n.code,{children:"Qt"})," installation folder, you can define this environment variable globally in your OS."]})}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["You can't execute these ",(0,s.jsx)(n.code,{children:"qtenvX"})," scripts, they have to be sourced like ",(0,s.jsx)(n.code,{children:"source qtenvX"})," or ",(0,s.jsx)(n.code,{children:". qtenvX"}),"."]})}),"\n",(0,s.jsx)(n.h5,{id:"allow-symbolic-links-unprivileged",children:"Allow symbolic links unprivileged"}),"\n",(0,s.jsxs)(n.p,{children:["Open ",(0,s.jsx)(n.code,{children:"Local Security Policy"}),", go to ",(0,s.jsx)(n.code,{children:"Local Policies - User Rights Assignment"}),", open ",(0,s.jsx)(n.code,{children:"Create symbolic links"})," and add your user account or user group, restart when it doesn't apply immediately."]}),"\n",(0,s.jsx)(n.h2,{id:"folders-structure",children:"Folders structure"}),"\n",(0,s.jsxs)(n.p,{children:["All ",(0,s.jsx)(n.code,{children:"tinyorm.org"})," examples are based on the following folders structure. The ",(0,s.jsx)(n.code,{children:"tom"})," folder will contain a ",(0,s.jsx)(n.a,{href:"/building/migrations",children:"migrations console application"}),"."]}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["You can set the root and application folder paths in the form below and they will be used across the whole ",(0,s.jsx)(n.a,{href:"http://www.tinyorm.org",children:"www.tinyorm.org"})," website. \ud83e\udd73 The pwsh shell is supposed to use on Windows and the bash shell on Linux, but it is not a requirement."]})}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsxs)(t.A,{value:y.b,label:y.ux,className:"tiny-tree",children:[(0,s.jsx)("div",{className:"tiny-root-folder-info-wrapper",children:(0,s.jsxs)(n.p,{children:[(0,s.jsx)("span",{className:"tiny-root-folder-info-prefix",children:"Current pwsh path"}),"\xa0",(0,s.jsx)(u,{groupId:y.b})]})}),(0,s.jsx)(g,{groupId:y.b,label:y.ux}),(0,s.jsx)(g,{groupId:y.pW,label:y.kl}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-text",children:"\n\n\n\u251c\u2500\u2500\n\u2502 \u251c\u2500\u2500 HelloWorld/\n\u2502 | \u251c\u2500\u2500 HelloWorld/\n\u2502 | \u251c\u2500\u2500 HelloWorld-builds-cmake/\n\u2502 | | \u2514\u2500\u2500 build-debug/\n\u2502 | \u2514\u2500\u2500 HelloWorld-builds-qmake/\n\u2502 | \u2514\u2500\u2500 build-debug/\n\u2502 \u251c\u2500\u2500 TinyORM/\n\u2502 | \u251c\u2500\u2500 TinyORM/\n\u2502 | \u251c\u2500\u2500 TinyORM-builds-cmake/\n\u2502 | \u2502 \u251c\u2500\u2500 build-gcc-debug/\n\u2502 | \u2502 \u251c\u2500\u2500 build-gcc-release/\n\u2502 | \u2502 \u2514\u2500\u2500 build-clang-debug/\n\u2502 | \u2514\u2500\u2500 TinyORM-builds-qmake/\n\u2502 | \u251c\u2500\u2500 build-debug/\n\u2502 | \u251c\u2500\u2500 build-TinyORM-Desktop_Qt_5_15_2_MSVC2019_64bit-Debug/\n\u2502 | \u2514\u2500\u2500 build-TinyORM-Desktop_Qt_5_15_2_MSYS2_UCRT64_64bit-Release/\n\u2502 \u2514\u2500\u2500 tom/\n\u2502 \u251c\u2500\u2500 tom/\n\u2502 \u2502 \u2514\u2500\u2500 database/\n\u2502 \u2502 \u251c\u2500\u2500 migrations/\n\u2502 \u2502 \u251c\u2500\u2500 seeders/\n\u2502 \u2502 \u251c\u2500\u2500 migrations.pri\n\u2502 \u2502 \u2514\u2500\u2500 seeders.pri\n\u2502 \u251c\u2500\u2500 tom-builds-cmake/\n\u2502 \u2502 \u2514\u2500\u2500 build-TinyORM-Desktop_Qt_6_7_1_MSVC2019_64bit-Debug/\n\u2502 \u2514\u2500\u2500 tom-builds-qmake/\n\u2502 \u251c\u2500\u2500 build-TinyORM-Desktop_Qt_5_15_3_MSYS2_UCRT64_64bit-Release/\n\u2502 \u2514\u2500\u2500 build-TinyORM-Desktop_Qt_6_7_1_MSVC2019_64bit-Debug/\n\u251c\u2500\u2500 tmp/\n\u2514\u2500\u2500 vcpkg/\n"})})]}),(0,s.jsxs)(t.A,{value:y.xj,label:y.gg,className:"tiny-tree",children:[(0,s.jsx)("div",{className:"tiny-root-folder-info-wrapper",children:(0,s.jsxs)(n.p,{children:[(0,s.jsx)("span",{className:"tiny-root-folder-info-prefix",children:"Current bash path"}),"\xa0",(0,s.jsx)(u,{groupId:y.xj})]})}),(0,s.jsx)(g,{groupId:y.xj,label:y.gg}),(0,s.jsx)(g,{groupId:y.pW,label:y.pW}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-text",children:"\n\n\n\u251c\u2500\u2500\n\u2502 \u251c\u2500\u2500 HelloWorld/\n\u2502 | \u251c\u2500\u2500 HelloWorld/\n\u2502 | \u251c\u2500\u2500 HelloWorld-builds-cmake/\n\u2502 | | \u2514\u2500\u2500 build-debug/\n\u2502 | \u2514\u2500\u2500 HelloWorld-builds-qmake/\n\u2502 | \u2514\u2500\u2500 build-debug/\n\u2502 \u251c\u2500\u2500 TinyORM/\n\u2502 | \u251c\u2500\u2500 TinyORM/\n\u2502 | \u251c\u2500\u2500 TinyORM-builds-cmake/\n\u2502 | \u2502 \u251c\u2500\u2500 build-gcc-debug/\n\u2502 | \u2502 \u251c\u2500\u2500 build-gcc-release/\n\u2502 | \u2502 \u2514\u2500\u2500 build-clang-debug/\n\u2502 | \u2514\u2500\u2500 TinyORM-builds-qmake/\n\u2502 | \u251c\u2500\u2500 build-debug/\n\u2502 | \u251c\u2500\u2500 build-TinyORM-Desktop_Qt_5_15_2_GCC_64bit-Debug/\n\u2502 | \u2514\u2500\u2500 build-TinyORM-Desktop_Qt_5_15_2_clang13_64bit_ccache-Release/\n\u2502 \u2514\u2500\u2500 tom/\n\u2502 \u251c\u2500\u2500 tom/\n\u2502 \u2502 \u2514\u2500\u2500 database/\n\u2502 \u2502 \u251c\u2500\u2500 migrations/\n\u2502 \u2502 \u251c\u2500\u2500 seeders/\n\u2502 \u2502 \u251c\u2500\u2500 migrations.pri\n\u2502 \u2502 \u2514\u2500\u2500 seeders.pri\n\u2502 \u251c\u2500\u2500 tom-builds-cmake/\n\u2502 \u2502 \u2514\u2500\u2500 build-TinyORM-Desktop_Qt_6_7_1_clang14_64bit_ccache-Debug/\n\u2502 \u2514\u2500\u2500 tom-builds-qmake/\n\u2502 \u251c\u2500\u2500 build-TinyORM-Desktop_Qt_6_7_1_GCC_64bit-Debug/\n\u2502 \u2514\u2500\u2500 build-TinyORM-Desktop_Qt_6_7_1_clang14_64bit_ccache-Release/\n\u251c\u2500\u2500 tmp/\n\u2514\u2500\u2500 vcpkg/\n"})})]})]}),"\n",(0,s.jsx)(n.admonition,{type:"danger",children:(0,s.jsxs)(n.p,{children:["Avoid paths with spaces with the ",(0,s.jsx)(n.code,{children:"qmake"})," build system, it will not compile."]})}),"\n",(0,s.jsx)(r.A,{id:"qtcreator-default-build-directory"}),"\n",(0,s.jsxs)(n.admonition,{type:"tip",children:[(0,s.jsxs)(n.p,{children:["You can force the ",(0,s.jsx)(n.code,{children:"QtCreator"})," to generate a build folders structure as is described above."]}),(0,s.jsxs)(n.p,{children:["To generate the required folders structure set the ",(0,s.jsx)(n.code,{children:"Settings"})," - ",(0,s.jsx)(n.code,{children:"Build & Run"})," - ",(0,s.jsx)(n.code,{children:"Default Build Properties"})," - ",(0,s.jsx)(n.code,{children:"Default build directory"})," to:",(0,s.jsx)("br",{}),"\n",(0,s.jsx)(n.code,{children:'../%{Project:Name}-builds-%{BuildSystem:Name}/%{JS: Util.asciify("build-%{Project:Name}-%{Kit:FileSystemName}-%{BuildConfig:Name}")}'})]})]}),"\n",(0,s.jsx)(n.h2,{id:"getting-started",children:"Getting started"}),"\n",(0,s.jsxs)(n.p,{children:["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 ",(0,s.jsx)(n.code,{children:"PATH"})," and ",(0,s.jsx)(n.code,{children:"LD_LIBRARY_PATH"})," for Qt Framework, or use our ",(0,s.jsx)(n.code,{children:"qtenvX"})," scripts described above."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:y.b,label:y.ux,children:(0,s.jsx)(c.A,{className:"language-powershell",children:`mkdir ${(0,x.Sn)(y.b)}\ncd ${(0,x.Sn)(y.b)}\n$env:Path = 'C:\\Qt\\6.7.1\\msvc2019_64\\bin;' + $env:Path\nvcvars64.ps1`})}),(0,s.jsx)(t.A,{value:y.xj,label:y.gg,children:(0,s.jsx)(c.A,{className:"language-bash",children:`mkdir -p ${(0,x.Sn)(y.xj)}\ncd ${(0,x.Sn)(y.xj)}\nexport PATH=/opt/Qt/6.7.1/gcc_64/bin\${PATH:+:}$PATH\nexport LD_LIBRARY_PATH=/opt/Qt/6.7.1/gcc_64/lib\${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH`})})]}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["You can also use the ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/tools/Add-FolderOnPath.ps1",children:(0,s.jsx)(n.code,{children:"tools/Add-FolderOnPath.ps1"})})," pwsh script to fastly prepend a path or ",(0,s.jsx)("abbr",{title:"Current working directory",children:"pwd"})," on the system ",(0,s.jsx)(n.code,{children:"PATH"}),"."]})}),"\n",(0,s.jsx)(n.h2,{id:"vcpkg",children:"vcpkg"}),"\n",(0,s.jsxs)(n.p,{children:["Installing the ",(0,s.jsx)(n.code,{children:"vcpkg"})," is highly recommended, it simplifies installation of the ",(0,s.jsx)(n.code,{children:"range-v3"})," and ",(0,s.jsx)(n.code,{children:"tabulate"})," dependencies."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:y.b,label:y.ux,children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-powershell",children:"git clone git@github.com:microsoft/vcpkg.git\ncd vcpkg\n.\\bootstrap-vcpkg.bat\n"})})}),(0,s.jsx)(t.A,{value:y.xj,label:y.gg,children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"git clone git@github.com:microsoft/vcpkg.git\ncd vcpkg\n./bootstrap-vcpkg.sh\n"})})})]}),"\n",(0,s.jsxs)(n.p,{children:["Add ",(0,s.jsx)(n.code,{children:"vcpkg"})," on the system path, add the following to the ",(0,s.jsx)(n.code,{children:".bashrc"})," or ",(0,s.jsx)(n.code,{children:".zshrc"})," on Linux."]}),"\n",(0,s.jsx)(c.A,{className:"language-bash",children:`export PATH=${(0,x.Sn)(y.xj)}/vcpkg\${PATH:+:}$PATH`}),"\n",(0,s.jsxs)(n.p,{children:["On Windows, open the ",(0,s.jsx)(n.code,{children:"Environment variables"})," dialog and add ",(0,s.jsx)(n.code,{children:"vcpkg"})," on the user ",(0,s.jsx)(n.code,{children:"PATH"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Or you can export it for the current session only."}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:y.b,label:y.ux,children:(0,s.jsx)(c.A,{className:"language-powershell",children:`$env:Path = "${(0,x.Sn)(y.b,!1)}\\vcpkg;" + $env:Path`})}),(0,s.jsx)(t.A,{value:y.xj,label:y.gg,children:(0,s.jsx)(c.A,{className:"language-bash",children:`export PATH=${(0,x.Sn)(y.xj)}/vcpkg\${PATH:+:}$PATH`})})]}),"\n",(0,s.jsxs)(n.h4,{id:"set-up-vcpkg-environment",children:["Set up ",(0,s.jsx)(n.code,{children:"vcpkg"})," environment"]}),"\n",(0,s.jsxs)(n.p,{children:["To export ",(0,s.jsx)(n.code,{children:"vcpkg"})," environment variables globally, add it to the ",(0,s.jsx)(n.code,{children:".bashrc"})," or ",(0,s.jsx)(n.code,{children:".zshrc"})," on Linux, and you can use the ",(0,s.jsx)(n.code,{children:"Environment variables"})," dialog on Windows."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:"title='Linux'",children:'export VCPKG_DEFAULT_TRIPLET=x64-linux\n#export VCPKG_DEFAULT_HOST_TRIPLET=x64-linux\nexport VCPKG_MAX_CONCURRENCY=11\nexport VCPKG_OVERLAY_PORTS="$HOME/.local/share/vcpkg/ports"\nexport VCPKG_OVERLAY_TRIPLETS="$HOME/.local/share/vcpkg/triplets"\nexport VCPKG_ROOT="$HOME/Code/c/vcpkg"\n'})}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["It is recommended to define these variables globally because the ",(0,s.jsx)(n.code,{children:"CMake"})," and ",(0,s.jsx)(n.code,{children:"qmake"})," build system are able to detect the ",(0,s.jsx)(n.code,{children:"vcpkg"})," installation from them so you don't have to configure them manually to detect the ",(0,s.jsx)(n.code,{children:"vcpkg"})," installation."]})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["On Windows, it's always better to create these types of variables as user variables instead of system variables in the ",(0,s.jsx)(n.code,{children:"Environment variables"})," dialog."]})}),"\n",(0,s.jsx)(n.h2,{id:"c-preprocessor-macros",children:"C preprocessor macros"}),"\n",(0,s.jsxs)(n.p,{children:["The following table summarizes all the C preprocessor macros defined in the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library. These C macros are configured by ",(0,s.jsx)(n.code,{children:"CMake"})," or ",(0,s.jsx)(n.code,{children:"qmake"})," build systems. They are not sorted alphabetically, but they are sorted by how significant they are."]}),"\n",(0,s.jsxs)(n.p,{children:["In the ",(0,s.jsx)(n.code,{children:"CMake"})," build system, all the C macros are auto-detected / auto-configured or controlled by ",(0,s.jsx)(n.a,{href:"#cmake-build-options",children:(0,s.jsx)(n.code,{children:"CMake build options"})}),", so you don't have to care too much about them."]}),"\n",(0,s.jsxs)(n.p,{children:["In the ",(0,s.jsx)(n.code,{children:"qmake"})," build is important whether you are building ",(0,s.jsx)(n.code,{children:"TinyORM"})," library or you are building your application and linking against ",(0,s.jsx)(n.code,{children:"TinyORM"})," library. When you are building the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library, all the C macros are auto-detected / auto-configured or controlled by ",(0,s.jsx)(n.a,{href:"#qmake-build-options",children:(0,s.jsx)(n.code,{children:"qmake build options"})}),", so you don't have to care too much about them."]}),"\n",(0,s.jsxs)(n.p,{children:["But a special situation is when you are building your application / library and you are linking against ",(0,s.jsx)(n.code,{children:"TinyORM"})," library. In this particular case, you must configure all these C macros manually! For this reason, the ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/qmake/TinyOrm.pri",children:(0,s.jsx)(n.code,{children:"TinyOrm.pri"})})," has been created, so that's not a big deal either. Little more info ",(0,s.jsx)(n.a,{href:"#consume-tinyorm-library-qmake",children:"here"}),"."]}),"\n",(0,s.jsx)("div",{id:"apitable-c-macros",children:(0,s.jsx)(l.A,{children:(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"C Macro Name"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_LINKING_SHARED"})}),(0,s.jsxs)(n.td,{children:[(0,s.jsx)("u",{children:(0,s.jsx)(n.strong,{children:"Must"})})," be defined when you are linking against ",(0,s.jsx)(n.code,{children:"TinyORM"})," shared build (",(0,s.jsx)(n.code,{children:"dll"})," library), exported classes and functions will be tagged with ",(0,s.jsx)(n.code,{children:"__declspec(dllimport)"})," on ",(0,s.jsx)(n.code,{children:"msvc"})," and ",(0,s.jsx)(n.code,{children:'visibility("default")'})," on ",(0,s.jsx)(n.code,{children:"GCC >= 4"}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_BUILDING_SHARED"})}),(0,s.jsxs)(n.td,{children:["Defined when ",(0,s.jsx)(n.code,{children:"TinyORM"})," is built as a ",(0,s.jsx)(n.code,{children:"dll"})," library (shared build)."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_DEBUG"})}),(0,s.jsx)(n.td,{children:"Defined in the debug build."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_NO_DEBUG"})}),(0,s.jsx)(n.td,{children:"Defined in the release build."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_DEBUG_SQL"})}),(0,s.jsx)(n.td,{children:"Defined in the debug build."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_NO_DEBUG_SQL"})}),(0,s.jsx)(n.td,{children:"Defined in the release build."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_MYSQL_PING"})}),(0,s.jsxs)(n.td,{children:["Enable ",(0,s.jsx)(n.code,{children:"Orm::MySqlConnection::pingDatabase()"})," method.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Defined when ",(0,s.jsx)(n.a,{href:"#mysql_ping",children:(0,s.jsx)(n.code,{children:"mysql_ping"})})," ",(0,s.jsx)("small",{children:"(qmake)"})," / ",(0,s.jsx)(n.a,{href:"#MYSQL_PING",children:(0,s.jsx)(n.code,{children:"MYSQL_PING"})})," ",(0,s.jsx)("small",{children:"(cmake)"})," configuration ",(0,s.jsx)(n.code,{children:"build option"})," is enabled."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_DISABLE_ORM"})}),(0,s.jsxs)(n.td,{children:["Controls the compilation of all ",(0,s.jsx)(n.code,{children:"ORM-related"})," source code, when this macro is ",(0,s.jsx)(n.code,{children:"defined"}),", then only the ",(0,s.jsx)(n.code,{children:"query builder"})," without ",(0,s.jsx)(n.code,{children:"ORM"})," is compiled. Also excludes ",(0,s.jsx)(n.code,{children:"ORM-related"})," unit tests.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Defined when ",(0,s.jsx)(n.a,{href:"#disable_orm",children:(0,s.jsx)(n.code,{children:"disable_orm"})})," ",(0,s.jsx)("small",{children:"(qmake)"})," / ",(0,s.jsx)(n.a,{href:"#ORM",children:(0,s.jsx)(n.code,{children:"ORM"})})," ",(0,s.jsx)("small",{children:"(cmake)"})," configuration ",(0,s.jsx)(n.code,{children:"build option"})," is enabled ",(0,s.jsx)("small",{children:"(qmake)"})," / disabled ",(0,s.jsx)("small",{children:"(cmake)"}),"."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_EXTERN_CONSTANTS"})}),(0,s.jsxs)(n.td,{children:["Defined when extern constants are used. Extern constants are enabled by default for shared builds and disabled for static builds.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Described at ",(0,s.jsx)(n.a,{href:"#extern_constants",children:(0,s.jsx)(n.code,{children:"qmake"})})," / ",(0,s.jsx)(n.a,{href:"#INLINE_CONSTANTS",children:(0,s.jsx)(n.code,{children:"CMake"})})," how it works."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_INLINE_CONSTANTS"})}),(0,s.jsxs)(n.td,{children:["Defined when global inline constants are used.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Defined when ",(0,s.jsx)(n.a,{href:"#inline_constants",children:(0,s.jsx)(n.code,{children:"inline_constants"})})," ",(0,s.jsx)("small",{children:"(qmake)"})," / ",(0,s.jsx)(n.a,{href:"#INLINE_CONSTANTS",children:(0,s.jsx)(n.code,{children:"INLINE_CONSTANTS"})})," ",(0,s.jsx)("small",{children:"(cmake)"})," configuration ",(0,s.jsx)(n.code,{children:"build option"})," is enabled."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_TESTS_CODE"})}),(0,s.jsxs)(n.td,{children:["Enable code needed by unit tests, eg. connection overriding in the ",(0,s.jsx)(n.code,{children:"Orm::Tiny::Model"}),".",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Defined when ",(0,s.jsx)(n.a,{href:"#build_tests",children:(0,s.jsx)(n.code,{children:"build_tests"})})," ",(0,s.jsx)("small",{children:"(qmake)"})," / ",(0,s.jsx)(n.a,{href:"#BUILD_TESTS",children:(0,s.jsx)(n.code,{children:"BUILD_TESTS"})})," ",(0,s.jsx)("small",{children:"(cmake)"})," configuration ",(0,s.jsx)(n.code,{children:"build option"})," is enabled."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_DISABLE_THREAD_LOCAL"})}),(0,s.jsxs)(n.td,{children:["Remove all ",(0,s.jsx)(n.a,{href:"https://en.cppreference.com/w/c/language/storage_duration",children:(0,s.jsx)(n.code,{children:"thread_local"})})," storage duration specifiers, it disables multi-threading support.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Defined when ",(0,s.jsx)(n.a,{href:"#disable_thread_local",children:(0,s.jsx)(n.code,{children:"disable_thread_local"})})," ",(0,s.jsx)("small",{children:"(qmake)"})," / ",(0,s.jsx)(n.a,{href:"#DISABLE_THREAD_LOCAL",children:(0,s.jsx)(n.code,{children:"DISABLE_THREAD_LOCAL"})})," ",(0,s.jsx)("small",{children:"(cmake)"})," configuration ",(0,s.jsx)(n.code,{children:"build option"})," is enabled."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYTOM_MIGRATIONS_DIR"})}),(0,s.jsxs)(n.td,{children:["Default migrations path for the ",(0,s.jsx)(n.code,{children:"make:migration"})," command, can be an absolute or relative path (to the ",(0,s.jsx)("abbr",{title:"Current working directory",children:"pwd"}),").",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Default value: ",(0,s.jsx)(n.code,{children:"database/migrations"})," ",(0,s.jsx)("small",{children:"(relative to the pwd)"})]}),(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Defined by ",(0,s.jsx)(n.a,{href:"#TOM_MIGRATIONS_DIR",children:(0,s.jsx)(n.code,{children:"TOM_MIGRATIONS_DIR"})})," ",(0,s.jsx)("small",{children:"(cmake)"})," configuration build option.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["(qmake note) You can use ",(0,s.jsx)(n.code,{children:'DEFINES += TINYTOM_MIGRATIONS_DIR="\\"database/migrations\\""'})," on the command-line or set it in the ",(0,s.jsx)(n.strong,{children:"main"})," ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/conf.pri.example#L65-L70",children:(0,s.jsx)(n.code,{children:"conf.pri"})})," file."]})]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYTOM_MODELS_DIR"})}),(0,s.jsxs)(n.td,{children:["Default models path for the ",(0,s.jsx)(n.code,{children:"make:model"})," command, can be an absolute or relative path (to the ",(0,s.jsx)("abbr",{title:"Current working directory",children:"pwd"}),").",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Default value: ",(0,s.jsx)(n.code,{children:"database/models"})," ",(0,s.jsx)("small",{children:"(relative to the pwd)"})]}),(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Defined by ",(0,s.jsx)(n.a,{href:"#TOM_MODELS_DIR",children:(0,s.jsx)(n.code,{children:"TOM_MODELS_DIR"})})," ",(0,s.jsx)("small",{children:"(cmake)"})," configuration build option.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["(qmake note) You can use ",(0,s.jsx)(n.code,{children:'DEFINES += TINYTOM_MODELS_DIR="\\"database/models\\""'})," on the command-line or set it in the ",(0,s.jsx)(n.strong,{children:"main"})," ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/conf.pri.example#L72-L73",children:(0,s.jsx)(n.code,{children:"conf.pri"})})," file."]})]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYTOM_SEEDERS_DIR"})}),(0,s.jsxs)(n.td,{children:["Default seeders path for the ",(0,s.jsx)(n.code,{children:"make:seeder"})," command, can be an absolute or relative path (to the ",(0,s.jsx)("abbr",{title:"Current working directory",children:"pwd"}),").",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Default value: ",(0,s.jsx)(n.code,{children:"database/seeders"})," ",(0,s.jsx)("small",{children:"(relative to the pwd)"})]}),(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Defined by ",(0,s.jsx)(n.a,{href:"#TOM_SEEDERS_DIR",children:(0,s.jsx)(n.code,{children:"TOM_SEEDERS_DIR"})})," ",(0,s.jsx)("small",{children:"(cmake)"})," configuration build option.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["(qmake note) You can use ",(0,s.jsx)(n.code,{children:'DEFINES += TINYTOM_SEEDERS_DIR="\\"database/seeders\\""'})," on the command-line or set it in the ",(0,s.jsx)(n.strong,{children:"main"})," ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/conf.pri.example#L75-L76",children:(0,s.jsx)(n.code,{children:"conf.pri"})})," file."]})]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_USING_PCH"})}),(0,s.jsxs)(n.td,{children:["Defined if building with precompiled headers.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Controlled by ",(0,s.jsx)(n.a,{href:"#qmake-precompile_header",children:(0,s.jsx)(n.code,{children:"qmake"})})," / ",(0,s.jsx)(n.a,{href:"#CMAKE_DISABLE_PRECOMPILE_HEADERS",children:(0,s.jsx)(n.code,{children:"CMake"})}),"."]})]})]})]})]})})}),"\n",(0,s.jsx)(n.h2,{id:"building-with-cmake",children:"Building with CMake"}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["If something is not clear, you can still look at GitHub Action ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/tree/main/.github/workflows",children:(0,s.jsx)(n.code,{children:"workflows"})})," how a building is done."]})}),"\n",(0,s.jsxs)(n.p,{children:["First, create a basic folder structure and then clone the ",(0,s.jsx)(n.code,{children:"TinyORM"})," project."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:y.b,label:y.ux,children:(0,s.jsx)(c.A,{className:"language-powershell",children:`cd ${(0,x.Sn)(y.b)}\nmkdir ${(0,x.np)()}/TinyORM/TinyORM-builds-cmake/build-debug\n\ncd ${(0,x.np)()}/TinyORM\ngit clone git@github.com:silverqx/TinyORM.git`})}),(0,s.jsx)(t.A,{value:y.xj,label:y.gg,children:(0,s.jsx)(c.A,{className:"language-bash",children:`cd ${(0,x.Sn)(y.xj)}\nmkdir -p ${(0,x.np)()}/TinyORM/TinyORM-builds-cmake/build-debug\n\ncd ${(0,x.np)()}/TinyORM\ngit clone git@github.com:silverqx/TinyORM.git`})})]}),"\n",(0,s.jsxs)(n.h3,{id:"configure-and-build-cmake",children:["Configure & Build ",(0,s.jsx)("small",{children:"(cmake)"})]}),"\n",(0,s.jsxs)(n.p,{children:["Now you are ready to configure the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd TinyORM-builds-cmake/build-debug\n"})}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:y.b,label:y.ux,children:(0,s.jsx)(c.A,{className:"language-powershell",children:`cmake.exe \`\n-S "${(0,x.OZ)(y.b)}/TinyORM/TinyORM" \`\n-B "${(0,x.OZ)(y.b)}/TinyORM/TinyORM-builds-cmake/build-debug" \`\n-G 'Ninja' \`\n-D CMAKE_BUILD_TYPE:STRING='Debug' \`\n-D CMAKE_TOOLCHAIN_FILE:FILEPATH="${(0,x.Sn)(y.b)}/vcpkg/scripts/buildsystems/vcpkg.cmake" \`\n-D CMAKE_CXX_SCAN_FOR_MODULES:BOOL=OFF \`\n-D CMAKE_INSTALL_PREFIX:PATH="${(0,x.Sn)(y.b)}/tmp/TinyORM" \`\n-D BUILD_TESTS:BOOL=OFF \`\n-D MATCH_EQUAL_EXPORTED_BUILDTREE:BOOL=ON \`\n-D MYSQL_PING:BOOL=OFF \`\n-D TOM:BOOL=ON \`\n-D TOM_EXAMPLE:BOOL=OFF \`\n-D VERBOSE_CONFIGURE:BOOL=ON`})}),(0,s.jsx)(t.A,{value:y.xj,label:y.gg,children:(0,s.jsx)(c.A,{className:"language-bash",children:`cmake \\\n-S "${(0,x.OZ)(y.xj)}/TinyORM/TinyORM" \\\n-B "${(0,x.OZ)(y.xj)}/TinyORM/TinyORM-builds-cmake/build-debug" \\\n-G 'Ninja' \\\n-D CMAKE_BUILD_TYPE:STRING='Debug' \\\n-D CMAKE_TOOLCHAIN_FILE:FILEPATH="${(0,x.Sn)(y.xj)}/vcpkg/scripts/buildsystems/vcpkg.cmake" \\\n-D CMAKE_CXX_SCAN_FOR_MODULES:BOOL=OFF \\\n-D CMAKE_INSTALL_PREFIX:PATH="${(0,x.Sn)(y.xj)}/tmp/TinyORM" \\\n-D VERBOSE_CONFIGURE:BOOL=ON \\\n-D BUILD_TESTS:BOOL=OFF \\\n-D MYSQL_PING:BOOL=OFF \\\n-D TOM:BOOL=ON \\\n-D TOM_EXAMPLE:BOOL=OFF \\\n-D MATCH_EQUAL_EXPORTED_BUILDTREE:BOOL=ON`})})]}),"\n",(0,s.jsxs)(n.h5,{id:"cmake-strict_mode-option",children:["CMake ",(0,s.jsx)(n.code,{children:"STRICT_MODE"})," option"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"STRICT_MODE"})," ",(0,s.jsx)(n.code,{children:"CMake"})," configuration option was added in ",(0,s.jsx)(n.code,{children:"TinyORM"})," ",(0,s.jsx)(n.code,{children:"v0.37.3"}),". This option was added to avoid the propagation of aggressive strict warning compiler/linker options and Qt definitions from the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library to user code through the ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/cmake/CommonModules/TinyCommon.cmake",children:(0,s.jsx)(n.code,{children:"TinyOrm::CommonConfig"})})," interface library."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"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 ",(0,s.jsx)(n.code,{children:"ISOCPP"})," ",(0,s.jsx)(n.a,{href:"https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines",children:"C++ Core Guidelines"})," standards."]}),"\n",(0,s.jsxs)(n.p,{children:["If you want to enable these strict warning options in your code, you can enable the ",(0,s.jsx)(n.code,{children:"STRICT_MODE"})," ",(0,s.jsx)(n.code,{children:"CMake"})," configuration option and they will be propagated to your code. You can also enabled it globally using the ",(0,s.jsx)(n.code,{children:"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 ",(0,s.jsx)(n.code,{children:"STRICT_MODE"})," ",(0,s.jsx)(n.code,{children:"CMake"})," configuration option."]}),"\n",(0,s.jsxs)(n.p,{children:["You can achieve the same result by manually linking against the ",(0,s.jsx)(n.code,{children:"TinyOrm::CommonConfig"})," interface library when the ",(0,s.jsx)(n.code,{children:"STRICT_MODE"})," is set to ",(0,s.jsx)(n.code,{children:"OFF"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-cmake",children:"target_link_libraries( PRIVATE TinyOrm::CommonConfig)\n"})}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["The recommended way is to set the ",(0,s.jsx)(n.code,{children:"TINYORM_STRICT_MODE"})," environment variable to ",(0,s.jsx)(n.code,{children:"1"})," or ",(0,s.jsx)(n.code,{children:"ON"}),"."]})}),"\n",(0,s.jsx)(n.h4,{id:"build-tinyorm",children:"Build TinyORM"}),"\n",(0,s.jsx)(n.p,{children:"And build. You don't have to install it, you can use the build tree directly if you want."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cmake --build . --target all\ncmake --install .\n"})}),"\n",(0,s.jsx)(n.p,{children:"Or build and install in one step."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cmake --build . --target install\n"})}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["CMake multi-config generators like ",(0,s.jsx)(n.code,{children:"Ninja Multi-Config"})," or ",(0,s.jsx)(n.code,{children:"Visual Studio 16 2019"})," are also supported."]})}),"\n",(0,s.jsx)(n.h3,{id:"cmake-build-options",children:"CMake build options"}),"\n",(0,s.jsx)("div",{className:"apitable-build-options",children:(0,s.jsx)(l.A,{children:(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Option Name"}),(0,s.jsx)(n.th,{children:"Default"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"BUILD_DRIVERS"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Build ",(0,s.jsx)(n.a,{href:"/tinydrivers/getting-started",children:"TinyDrivers"})," SQL database drivers (core/common code; replaces QtSql module)."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"BUILD_MYSQL_DRIVER"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Build ",(0,s.jsx)(n.code,{children:"TinyDrivers"})," MySQL database driver.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Available when: ",(0,s.jsx)(n.code,{children:"BUILD_DRIVERS"})]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"BUILD_SHARED_LIBS"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ON"})}),(0,s.jsx)(n.td,{children:"Build as a shared/static library."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"BUILD_TESTS"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsx)(n.td,{children:"Build TinyORM unit tests."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"BUILD_TREE_DEPLOY"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ON"})}),(0,s.jsxs)(n.td,{children:["Copy ",(0,s.jsx)(n.code,{children:"TinyDrivers"})," and ",(0,s.jsx)(n.code,{children:"TinyMySql"})," libraries to the root of the build tree."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"DRIVERS_TYPE"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Shared"})}),(0,s.jsxs)(n.td,{children:["How to build and link against ",(0,s.jsx)(n.code,{children:"TinyDrivers"})," SQL database drivers.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["The ",(0,s.jsx)(n.code,{children:"Static"})," value will be select by default when the ",(0,s.jsx)(n.code,{children:"BUILD_SHARED_LIBS"})," is ",(0,s.jsx)(n.code,{children:"OFF"}),".",(0,s.jsx)("br",{}),"Supported values: ",(0,s.jsx)(n.a,{href:"/tinydrivers/getting-started#the-shared-library-build",children:(0,s.jsx)(n.code,{children:"Shared"})}),", ",(0,s.jsx)(n.a,{href:"/tinydrivers/getting-started#the-loadable-sql-drivers-build",children:(0,s.jsx)(n.code,{children:"Loadable"})}),", and ",(0,s.jsx)(n.a,{href:"/tinydrivers/getting-started#the-static-build",children:(0,s.jsx)(n.code,{children:"Static"})}),(0,s.jsx)("br",{}),"Available when: ",(0,s.jsx)(n.code,{children:"BUILD_DRIVERS AND BUILD_SHARED_LIBS"})]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"INLINE_CONSTANTS"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Use inline constants instead of extern constants in the ",(0,s.jsx)(n.code,{children:"shared build"}),".",(0,s.jsx)("br",{}),(0,s.jsx)(n.code,{children:"OFF"})," is highly recommended for the ",(0,s.jsx)(n.code,{children:"shared build"}),";",(0,s.jsx)("br",{}),"is always ",(0,s.jsx)(n.code,{children:"ON"})," for the ",(0,s.jsx)(n.code,{children:"static build"}),".",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Available when: ",(0,s.jsx)(n.code,{children:"BUILD_SHARED_LIBS"})]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"MSVC_RUNTIME_DYNAMIC"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ON"})}),(0,s.jsxs)(n.td,{children:["Use MSVC dynamic runtime library (",(0,s.jsx)(n.code,{children:"-MD"}),") instead of static (",(0,s.jsx)(n.code,{children:"-MT"}),"), also considers a Debug configuration (",(0,s.jsx)(n.code,{children:"-MTd"}),", ",(0,s.jsx)(n.code,{children:"-MDd"}),").",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Available when: ",(0,s.jsx)(n.code,{children:"MSVC AND NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY"})]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"MYSQL_PING"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Enable ",(0,s.jsx)(n.code,{children:"Orm::MySqlConnection::pingDatabase()"})," method."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ORM"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ON"})}),(0,s.jsxs)(n.td,{children:["Controls the compilation of all ",(0,s.jsx)(n.code,{children:"ORM-related"})," source code, when this option is ",(0,s.jsx)(n.code,{children:"disabled"}),", then only the ",(0,s.jsx)(n.code,{children:"query builder"})," without ",(0,s.jsx)(n.code,{children:"ORM"})," is compiled. Also excludes ",(0,s.jsx)(n.code,{children:"ORM-related"})," unit tests."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"STRICT_MODE"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Controls propagation of strict compiler/linker options and Qt definitions using the ",(0,s.jsx)(n.code,{children:"TinyOrm::CommonConfig"})," interface library to the user code.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["(highly recommended; can also be set with the ",(0,s.jsx)(n.code,{children:"TINYORM_STRICT_MODE"})," environment variable; described ",(0,s.jsx)(n.a,{href:"#cmake-strict_mode-option",children:"here"}),")"]}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TOM"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ON"})}),(0,s.jsxs)(n.td,{children:["Controls the compilation of all ",(0,s.jsx)(n.code,{children:"Tom-related"})," source code, when this option is ",(0,s.jsx)(n.code,{children:"disabled"}),", then it also excludes ",(0,s.jsx)(n.code,{children:"Tom-related"})," unit tests."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TOM_EXAMPLE"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Build the ",(0,s.jsx)("abbr",{title:"TinyORM Migrations",children:(0,s.jsx)(n.code,{children:"tom"})})," console application example."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TOM_MIGRATIONS_DIR"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"-"})}),(0,s.jsxs)(n.td,{children:["Default migrations path for the ",(0,s.jsx)(n.code,{children:"make:migration"})," command, can be an absolute or relative path (to the ",(0,s.jsx)("abbr",{title:"Current working directory",children:"pwd"}),").",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Default value: ",(0,s.jsx)(n.code,{children:"database/migrations"})," ",(0,s.jsx)("small",{children:"(relative to the pwd)"})]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TOM_MODELS_DIR"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"-"})}),(0,s.jsxs)(n.td,{children:["Default models path for the ",(0,s.jsx)(n.code,{children:"make:model"})," command, can be an absolute or relative path (to the ",(0,s.jsx)("abbr",{title:"Current working directory",children:"pwd"}),").",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Default value: ",(0,s.jsx)(n.code,{children:"database/models"})," ",(0,s.jsx)("small",{children:"(relative to the pwd)"})]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TOM_SEEDERS_DIR"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"-"})}),(0,s.jsxs)(n.td,{children:["Default seeders path for the ",(0,s.jsx)(n.code,{children:"make:seeder"})," command, can be an absolute or relative path (to the ",(0,s.jsx)("abbr",{title:"Current working directory",children:"pwd"}),").",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Default value: ",(0,s.jsx)(n.code,{children:"database/seeders"})," ",(0,s.jsx)("small",{children:"(relative to the pwd)"})]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"VERBOSE_CONFIGURE"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Show information about ",(0,s.jsx)(n.code,{children:"PACKAGES_FOUND"})," / ",(0,s.jsx)(n.code,{children:"PACKAGES_NOT_FOUND"})," in the CMake configure output."]})]})]})]})})}),"\n",(0,s.jsxs)(n.p,{children:["Advanced ",(0,s.jsx)(n.code,{children:"TinyORM"})," options."]}),"\n",(0,s.jsx)("div",{className:"apitable-build-options",children:(0,s.jsx)(l.A,{children:(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Option Name"}),(0,s.jsx)(n.th,{children:"Default"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"DISABLE_THREAD_LOCAL"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Remove all ",(0,s.jsx)(n.a,{href:"https://en.cppreference.com/w/c/language/storage_duration",children:(0,s.jsx)(n.code,{children:"thread_local"})})," storage duration specifiers, it disables multi-threading support."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)("small",{children:(0,s.jsx)(n.code,{children:"MATCH_EQUAL_EXPORTED_BUILDTREE"})})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Exported package configuration from the build tree is considered to match only when ",(0,s.jsx)(n.code,{children:"the build type"})," of application/library that is linking against the TinyORM library ",(0,s.jsx)(n.strong,{children:"is equal"}),".",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Available when:",(0,s.jsx)("br",{}),(0,s.jsx)(n.code,{children:"CMAKE_EXPORT_PACKAGE_REGISTRY AND NOT TINY_IS_MULTI_CONFIG"})]})]})]})]})]})})}),"\n",(0,s.jsxs)(n.p,{children:["Important ",(0,s.jsx)(n.code,{children:"CMake"})," options."]}),"\n",(0,s.jsx)("div",{className:"apitable-build-options",children:(0,s.jsx)(l.A,{children:(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Option Name"}),(0,s.jsx)(n.th,{children:"Default"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"CMAKE_DISABLE_PRECOMPILE_HEADERS"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsx)(n.td,{children:"Disable precompiled headers."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"CMAKE_CXX_COMPILER"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"auto"})}),(0,s.jsxs)(n.td,{children:["The full path to the ",(0,s.jsx)(n.code,{children:"C++"})," compiler."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"CMAKE_CXX_COMPILER_LAUNCHER"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"-"})}),(0,s.jsxs)(n.td,{children:["Default compiler launcher to use for the ",(0,s.jsx)(n.code,{children:"C++"})," compiler.",(0,s.jsx)("br",{}),"Can be used to enable ",(0,s.jsx)(n.code,{children:"ccache"}),", eg. ",(0,s.jsx)(n.code,{children:"ccache.exe"})," on ",(0,s.jsx)(n.code,{children:"MinGW"})," or ",(0,s.jsx)(n.code,{children:"/usr/bin/ccache"})," on ",(0,s.jsx)(n.code,{children:"Linux"}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"CMAKE_EXPORT_PACKAGE_REGISTRY"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Enable the ",(0,s.jsx)(n.code,{children:"export(TinyOrm)"})," command.",(0,s.jsx)("br",{}),(0,s.jsx)(n.code,{children:"TinyORM"})," doesn't set this variable by default. Its initial value is taken from the ",(0,s.jsx)(n.code,{children:"TINYORM_EXPORT_PACKAGE_REGISTRY"})," environment variable if not already defined."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"CMAKE_VERBOSE_MAKEFILE"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsx)(n.td,{children:"Enable verbose output from Makefile builds."})]})]})]})})}),"\n",(0,s.jsxs)(n.h3,{id:"consume-tinyorm-library-cmake",children:["Consume TinyOrm library ",(0,s.jsx)("small",{children:"(cmake)"})]}),"\n",(0,s.jsxs)(n.p,{children:["In your application or library ",(0,s.jsx)(n.code,{children:"CMakeLists.txt"})," file add following ",(0,s.jsx)(n.code,{children:"find_package()"})," call."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-cmake",metastring:"title='CMakeLists.txt'",children:"find_package(TinyOrm 0.37.3 CONFIG REQUIRED)\n"})}),"\n",(0,s.jsxs)(n.p,{children:["If the ",(0,s.jsx)(n.code,{children:"TinyORM"})," build tree is not exported to the CMake's ",(0,s.jsx)(n.a,{href:"https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html#user-package-registry",children:(0,s.jsx)(n.code,{children:"User Package Registry"})})," then also add the ",(0,s.jsx)(n.code,{children:"TinyORM"})," build tree or ",(0,s.jsx)(n.code,{children:"CMAKE_INSTALL_PREFIX"})," folder to the ",(0,s.jsx)(n.code,{children:"CMAKE_PREFIX_PATH"}),", so CMake can find TinyORM's package configuration file during ",(0,s.jsx)(n.code,{children:"find_package(TinyOrm)"})," call."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:y.b,label:`cmake (${y.b})`,children:(0,s.jsx)(c.A,{className:"language-cmake",children:`# build tree\nlist(APPEND CMAKE_PREFIX_PATH "${(0,x.nC)(y.b,(0,x.OZ)(y.b))}/TinyORM/TinyORM-builds-cmake/build-debug")\n\n# installation folder - CMAKE_INSTALL_PREFIX\nlist(APPEND CMAKE_PREFIX_PATH "${(0,x.nC)(y.b,(0,x.Sn)(y.b))}/tmp/TinyORM")`})}),(0,s.jsx)(t.A,{value:y.xj,label:`cmake (${y.xj})`,children:(0,s.jsx)(c.A,{className:"language-cmake",children:`# build tree\nlist(APPEND CMAKE_PREFIX_PATH "${(0,x.nC)(y.xj,(0,x.OZ)(y.xj))}/TinyORM/TinyORM-builds-cmake/build-debug")\n\n# installation folder - CMAKE_INSTALL_PREFIX\nlist(APPEND CMAKE_PREFIX_PATH "${(0,x.nC)(y.xj,(0,x.Sn)(y.xj))}/tmp/TinyORM")`})})]}),"\n",(0,s.jsxs)(n.p,{children:["Or as an alternative, you can set ",(0,s.jsx)(n.code,{children:"CMAKE_PREFIX_PATH"})," environment variable."]}),"\n",(0,s.jsx)(r.A,{id:"tinyorm-on-path-cmake"}),"\n",(0,s.jsxs)(n.p,{children:["As the last thing, do not forget to add ",(0,s.jsx)(n.code,{children:"TinyOrm0d.dll"})," on the path on Windows and on the ",(0,s.jsx)(n.code,{children:"LD_LIBRARY_PATH"})," on Linux, so your application can find it during execution."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,name:"tinyorm-on-path",children:[(0,s.jsx)(t.A,{value:y.b,label:y.ux,children:(0,s.jsx)(c.A,{className:"language-powershell",children:`$env:Path = "${(0,x.OZ)(y.b,!1)}\\TinyORM\\TinyORM-builds-cmake\\build-debug;" + $env:Path`})}),(0,s.jsx)(t.A,{value:y.xj,label:y.gg,children:(0,s.jsx)(c.A,{className:"language-bash",children:`export LD_LIBRARY_PATH=${(0,x.OZ)(y.xj)}/TinyORM/TinyORM-builds-cmake/build-debug\${PATH:+:}$PATH`})})]}),"\n",(0,s.jsxs)(n.p,{children:["Now you can try the ",(0,s.jsx)(n.a,{href:"/building/hello-world#hello-world-with-cmake",children:(0,s.jsx)(n.code,{children:"HelloWorld CMake"})})," example."]}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["You can also try the ",(0,s.jsx)(n.a,{href:"/building/hello-world#fetchcontent",children:(0,s.jsx)(n.code,{children:"FetchContent"})})," method to fastly link against the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library."]})}),"\n",(0,s.jsx)(n.h2,{id:"building-with-qmake",children:"Building with qmake"}),"\n",(0,s.jsxs)(n.p,{children:["First, create a basic folder structure and then clone the ",(0,s.jsx)(n.code,{children:"TinyORM"})," project."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:y.b,label:y.ux,children:(0,s.jsx)(c.A,{className:"language-powershell",children:`cd ${(0,x.Sn)(y.b)}\nmkdir ${(0,x.np)()}/TinyORM/TinyORM-builds-qmake\n\ncd ${(0,x.np)()}/TinyORM\ngit clone git@github.com:silverqx/TinyORM.git`})}),(0,s.jsx)(t.A,{value:y.xj,label:y.gg,children:(0,s.jsx)(c.A,{className:"language-bash",children:`cd ${(0,x.Sn)(y.xj)}\nmkdir -p ${(0,x.np)()}/TinyORM/TinyORM-builds-qmake\n\ncd ${(0,x.np)()}/TinyORM\ngit clone git@github.com:silverqx/TinyORM.git`})})]}),"\n",(0,s.jsx)(n.h3,{id:"install-dependencies",children:"Install dependencies"}),"\n",(0,s.jsxs)(n.p,{children:["With the ",(0,s.jsx)(n.code,{children:"qmake"})," build system, you have to install ",(0,s.jsx)(n.code,{children:"TinyORM"})," dependencies manually. We will use the ",(0,s.jsx)(n.code,{children:"vcpkg"})," package manager."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd ../../vcpkg\n\nvcpkg search range-v3\nvcpkg search tabulate\nvcpkg install range-v3 tabulate\nvcpkg list\n"})}),"\n",(0,s.jsxs)(n.p,{children:["On ",(0,s.jsx)(n.code,{children:"Linux"}),", you can install the ",(0,s.jsx)(n.code,{children:"range-v3"})," library and some other ",(0,s.jsx)(n.a,{href:"/dependencies#install-dependencies",children:"dependencies"})," with the package manager."]}),"\n",(0,s.jsxs)(n.h3,{id:"configure-and-build-qmake",children:["Configure & Build ",(0,s.jsx)("small",{children:"(qmake)"})]}),"\n",(0,s.jsx)(n.h4,{id:"open-qtcreator-ide",children:"Open QtCreator IDE"}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["I recommend creating a new ",(0,s.jsx)(n.a,{href:"https://doc.qt.io/qtcreator/creator-project-managing-sessions.html",children:(0,s.jsx)(n.code,{children:"Session"})})," in the ",(0,s.jsx)(n.code,{children:"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 ",(0,s.jsx)(n.code,{children:"QtCreator IDE"}),". You can name it ",(0,s.jsx)(n.code,{children:"tinyorm.org"})," or ",(0,s.jsx)(n.code,{children:"TinyORM examples"}),", it is up to you."]})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["If you are using sessions, you can use a single ",(0,s.jsx)(n.code,{children:"clangd"})," instance for all projects in this session in the ",(0,s.jsx)(n.code,{children:"QtCreator IDE"}),". One significant advantage of this method is that the ",(0,s.jsx)(n.code,{children:".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 ",(0,s.jsx)(n.code,{children:"Settings"})," - ",(0,s.jsx)(n.code,{children:"C++"})," - ",(0,s.jsx)(n.code,{children:"Clangd"})," - ",(0,s.jsx)(n.code,{children:"Sessions with a single clangd instance"}),"."]})}),"\n",(0,s.jsx)(n.h4,{id:"configure-tinyorm",children:"Configure TinyORM"}),"\n",(0,s.jsxs)(n.p,{children:["Now you are ready to configure the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library. There are two ways how to configure the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library and it's the new ",(0,s.jsx)(n.code,{children:"Auto-configure"})," feature added in ",(0,s.jsx)(n.code,{children:"TinyORM"})," ",(0,s.jsx)(n.code,{children:"v0.34.0"})," using the ",(0,s.jsx)(n.code,{children:".env"})," files and the old way using the ",(0,s.jsx)(n.code,{children:"conf.pri"})," files."]}),"\n",(0,s.jsx)(n.h5,{id:"auto-configuration-and-tiny_dotenv",children:"Auto-configuration and tiny_dotenv"}),"\n",(0,s.jsxs)(n.p,{children:["This is the new recommended method to auto-configure TinyORM's ",(0,s.jsx)(n.code,{children:"qmake"})," build system and also the dependencies, it was added in ",(0,s.jsx)(n.code,{children:"TinyORM"})," ",(0,s.jsx)(n.code,{children:"v0.34.0"}),". You need to copy the prepared ",(0,s.jsx)(n.code,{children:".env.(win32|unix|mingw).example"})," file to the ",(0,s.jsx)(n.code,{children:".env.(win32|unix|mingw)"}),". One ",(0,s.jsx)(n.code,{children:".env"})," example file is prepared for each supported platform."]}),"\n",(0,s.jsxs)(n.p,{children:["All prepared ",(0,s.jsx)(n.code,{children:".env.(win32|unix|mingw).example"})," files are simple and clear. You can also create a common ",(0,s.jsx)(n.code,{children:".env"})," file that is included before the platform-specific ",(0,s.jsx)(n.code,{children:".env.(win32|unix|mingw)"})," files."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:y.b,label:y.ux,children:(0,s.jsx)(c.A,{className:"language-powershell",children:`cd ${(0,x.OZ)(y.b)}/TinyORM/TinyORM\n\ncp .env.win32.example .env.win32`})}),(0,s.jsx)(t.A,{value:y.xj,label:y.gg,children:(0,s.jsx)(c.A,{className:"language-bash",children:`cd ${(0,x.OZ)(y.xj)}/TinyORM/TinyORM\n\ncp .env.unix.example .env.unix`})})]}),"\n",(0,s.jsxs)(n.p,{children:["And that is all, if you have correctly set all ",(0,s.jsx)(n.code,{children:"qmake"})," variables in this ",(0,s.jsx)(n.code,{children:".env.(win32|unix|mingw)"})," file or you have correctly set environment variables, then the ",(0,s.jsx)(n.code,{children:"qmake"})," build system should be able to ",(0,s.jsx)(n.code,{children:"auto-detect"})," all dependencies . \ud83d\udd25"]}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"#auto-configuration-internals",children:(0,s.jsx)(n.code,{children:"Auto-configuration"})})," and ",(0,s.jsx)(n.a,{href:"#environment-files",children:(0,s.jsx)(n.code,{children:"Environment files"})})," internals are described at the end to make this section more clear."]})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"Auto-configuration"})," feature can be turned off using the ",(0,s.jsx)(n.a,{href:"#disable_autoconf",children:(0,s.jsx)(n.code,{children:"disable_autoconf"})})," ",(0,s.jsx)(n.code,{children:"qmake"})," configuration option (eg. ",(0,s.jsx)(n.code,{children:"CONFIG*=disable_autoconf"}),")."]})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"tiny_dotenv"})," feature can be turned off using the ",(0,s.jsx)(n.a,{href:"#disable_dotenv",children:(0,s.jsx)(n.code,{children:"disable_dotenv"})})," ",(0,s.jsx)(n.code,{children:"qmake"})," configuration option (eg. ",(0,s.jsx)(n.code,{children:"CONFIG*=disable_dotenv"}),")."]})}),"\n",(0,s.jsx)(n.h5,{id:"manual-configuration-confpri",children:"Manual configuration (conf.pri)"}),"\n",(0,s.jsxs)(n.p,{children:["This is the old method used before ",(0,s.jsx)(n.code,{children:"TinyORM"})," ",(0,s.jsx)(n.code,{children:"v0.34.0"}),". You need to copy the ",(0,s.jsx)(n.code,{children:"conf.pri.example"})," files to ",(0,s.jsx)(n.code,{children:"conf.pri"})," (there are four, one for every project or sub-project) and manually update the ",(0,s.jsx)(n.code,{children:"INCLUDEPATH"})," and ",(0,s.jsx)(n.code,{children:"LIBS"})," to configure TinyORM's ",(0,s.jsx)(n.code,{children:"qmake"})," build dependencies. This way you can override any ",(0,s.jsx)(n.code,{children:"qmake"})," build options or variables."]}),"\n",(0,s.jsxs)(n.p,{children:["To disable the ",(0,s.jsx)(n.a,{href:"#auto-configuration-internals",children:(0,s.jsx)(n.code,{children:"Auto-configuration"})})," feature you must define the ",(0,s.jsx)(n.a,{href:"#disable_autoconf",children:(0,s.jsx)(n.code,{children:"disable_autoconf"})})," ",(0,s.jsx)(n.code,{children:"qmake"})," configuration option (eg. ",(0,s.jsx)(n.code,{children:"CONFIG*=disable_autoconf"}),") because from ",(0,s.jsx)(n.code,{children:"TinyORM"})," ",(0,s.jsx)(n.code,{children:"v0.34.0"})," is the ",(0,s.jsx)(n.code,{children:"Auto-configuration"})," feature enabled by default."]}),"\n",(0,s.jsxs)(n.p,{children:["You can also remove all ",(0,s.jsx)(n.code,{children:".env"})," files or turn off the ",(0,s.jsx)(n.code,{children:"tiny_dotenv"})," feature using ",(0,s.jsx)(n.code,{children:"CONFIG*=disable_dotenv"}),". You can use them all at once if you want, ",(0,s.jsx)(n.code,{children:".env"})," and also ",(0,s.jsx)(n.code,{children:"conf.pri"})," files."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"conf.pri"})," files are nicely commented on, so you can see what needs to be modified."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:y.b,label:y.ux,children:(0,s.jsx)(c.A,{className:"language-powershell",children:`cd ${(0,x.OZ)(y.b)}/TinyORM/TinyORM\n\ncp conf.pri.example conf.pri\ncp tests/conf.pri.example tests/conf.pri\ncp tests/testdata_tom/conf.pri.example tests/testdata_tom/conf.pri\ncp examples/tom/conf.pri.example examples/tom/conf.pri`})}),(0,s.jsx)(t.A,{value:y.xj,label:y.gg,children:(0,s.jsx)(c.A,{className:"language-bash",children:`cd ${(0,x.OZ)(y.xj)}/TinyORM/TinyORM\n\ncp conf.pri.example conf.pri\ncp tests/conf.pri.example tests/conf.pri\ncp tests/testdata_tom/conf.pri.example tests/testdata_tom/conf.pri\ncp examples/tom/conf.pri.example examples/tom/conf.pri`})})]}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"#manual-configuration-internals",children:(0,s.jsx)(n.code,{children:"Manual configuration"})})," internals are described at the end to make this section more clear."]})}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"Manual configuration"})," is still relevant if you have any non-standard installation of the ",(0,s.jsx)(n.code,{children:"vcpkg"})," or ",(0,s.jsx)(n.code,{children:"MySQL"})," and the ",(0,s.jsx)(n.code,{children:"Auto-configuration"})," feature fails."]})}),"\n",(0,s.jsx)(n.h5,{id:"opening-tinyormpro-main-project-file",children:"Opening TinyORM.pro (main project file)"}),"\n",(0,s.jsxs)(n.p,{children:["Now you can open the ",(0,s.jsx)(n.code,{children:"TinyORM.pro"})," project in the ",(0,s.jsx)(n.code,{children:"QtCreator IDE"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["This will open the ",(0,s.jsx)(n.code,{children:"Configure Project"})," tab, select some kit and update build folder paths to meet our ",(0,s.jsx)(n.a,{href:"#folders-structure",children:"folders structure"})," or like you want."]}),"\n",(0,s.jsx)("img",{src:i(885).A,alt:"TinyORM - QtCreator - Configure Project",width:"760"}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["You can force the ",(0,s.jsx)(n.code,{children:"QtCreator"})," to generate a build folders structure as is described ",(0,s.jsx)(n.a,{href:"#qtcreator-default-build-directory",children:"above"}),"."]})}),"\n",(0,s.jsxs)(n.p,{children:["You are ready to configure build options, hit ",(0,s.jsx)("kbd",{children:"Ctrl"}),"+",(0,s.jsx)("kbd",{children:"5"})," to open ",(0,s.jsx)(n.code,{children:"Project Settings"})," tab and select ",(0,s.jsx)(n.code,{children:"Build"})," in the left sidebar to open the ",(0,s.jsx)(n.code,{children:"Build Settings"}),", it should look similar to the following picture."]}),"\n",(0,s.jsxs)(n.p,{children:["Disable ",(0,s.jsx)(n.code,{children:"QML debugging and profiling"})," and ",(0,s.jsx)(n.code,{children:"Qt Quick Compiler"}),", they are not used."]}),"\n",(0,s.jsx)("img",{src:i(7619).A,alt:"TinyORM - QtCreator - Build Settings",width:"760"}),"\n",(0,s.jsxs)(n.p,{children:["If you want to change some ",(0,s.jsx)(n.code,{children:"TinyORM"})," build options, you can pass them to the ",(0,s.jsx)(n.code,{children:"Build Steps"})," - ",(0,s.jsx)(n.code,{children:"qmake TinyORM.pro"})," - ",(0,s.jsx)(n.code,{children:"Additional arguments"})," input field. It can look like this."]}),"\n",(0,s.jsx)("img",{src:i(2721).A,alt:"TinyORM - QtCreator - Build Settings - Additional arguments",width:"660"}),"\n",(0,s.jsx)(n.h4,{id:"build-tinyorm-1",children:"Build TinyORM"}),"\n",(0,s.jsxs)(n.p,{children:["Everything is ready for build, you can press ",(0,s.jsx)("kbd",{children:"Ctrl"}),"+",(0,s.jsx)("kbd",{children:"b"})," to build the project."]}),"\n",(0,s.jsx)(n.h3,{id:"qmake-build-options",children:"qmake build options"}),"\n",(0,s.jsx)("div",{className:"apitable-build-options",children:(0,s.jsx)(l.A,{children:(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsxs)(n.th,{children:[(0,s.jsx)(n.code,{children:"CONFIG"})," ",(0,s.jsx)("small",{children:"Option Name"})]}),(0,s.jsx)(n.th,{children:"Default"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"build_loadable_drivers"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Build ",(0,s.jsx)(n.a,{href:"/tinydrivers/getting-started",children:(0,s.jsx)(n.code,{children:"TinyDrivers"})})," as a shared library and SQL database drivers (eg. ",(0,s.jsx)(n.code,{children:"TinyMySql"}),") as shared libraries (",(0,s.jsx)(n.a,{href:"/tinydrivers/getting-started#the-loadable-sql-drivers-build",children:(0,s.jsx)(n.code,{children:"Loadable"})})," modules) that are loaded at runtime using ",(0,s.jsx)(n.code,{children:"LoadLibrary()"})," on Windows or ",(0,s.jsx)(n.code,{children:"dlopen()"})," on Linux."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"build_mysql_driver"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Build ",(0,s.jsx)(n.code,{children:"TinyDrivers"})," MySQL database driver.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["It's enabled by default when ",(0,s.jsx)(n.code,{children:"build_shared_drivers"}),", ",(0,s.jsx)(n.code,{children:"build_loadable_drivers"}),", or ",(0,s.jsx)(n.code,{children:"build_static_drivers"})," is enabled.",(0,s.jsx)("br",{}),"Available when: ",(0,s.jsx)(n.code,{children:"build_shared_drivers"})," OR ",(0,s.jsx)(n.code,{children:"build_loadable_drivers"})," OR ",(0,s.jsx)(n.code,{children:"build_static_drivers"})]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"build_shared_drivers"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Build ",(0,s.jsx)(n.code,{children:"TinyDrivers"})," as a ",(0,s.jsx)(n.a,{href:"/tinydrivers/getting-started#the-shared-library-build",children:(0,s.jsx)(n.code,{children:"Shared"})})," library."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"build_static_drivers"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Build ",(0,s.jsx)(n.code,{children:"TinyDrivers"})," as a ",(0,s.jsx)(n.a,{href:"/tinydrivers/getting-started#the-static-build",children:(0,s.jsx)(n.code,{children:"Static"})})," library archive.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["The ",(0,s.jsx)(n.code,{children:"build_static_drivers"})," ",(0,s.jsx)(n.code,{children:"qmake"})," configuration option will be select by default when the ",(0,s.jsx)(n.a,{href:"#qmake-static",children:(0,s.jsx)(n.code,{children:"CONFIG*=static"})})," is enabled."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"build_tests"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsx)(n.td,{children:"Build TinyORM unit tests."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ccache"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ON"})}),(0,s.jsxs)(n.td,{children:["Enable compiler cache. ",(0,s.jsx)(n.a,{href:"https://ccache.dev/",children:"Homepage"}),(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["It works on Windows and Unix systems. This option overrides qmake's ",(0,s.jsx)(n.code,{children:"ccache"})," option. It internally calls qmake's ",(0,s.jsx)(n.a,{href:"#qmake-ccache",children:(0,s.jsx)(n.code,{children:"ccache"})})," option on Unix and ",(0,s.jsx)(n.a,{href:"#tiny_ccache_win32",children:(0,s.jsx)(n.code,{children:"tiny_ccache_win32"})})," on Windows.",(0,s.jsx)("br",{}),"Reason: It allows using the same option on both OS-es."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"disable_autoconf"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Disable the ",(0,s.jsx)(n.a,{href:"#auto-configuration-internals",children:(0,s.jsx)(n.code,{children:"Auto-configuration"})})," feature ",(0,s.jsxs)("small",{children:["(auto-configuration is enabled by default from ",(0,s.jsx)(n.code,{children:"TinyORM"})," ",(0,s.jsx)(n.code,{children:"v0.34.0"}),")"]}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"disable_dotenv"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Disable the ",(0,s.jsx)(n.a,{href:"#environment-files",children:(0,s.jsx)(n.code,{children:"tiny_dotenv"})})," feature ",(0,s.jsxs)("small",{children:["(environment files are enabled by default from ",(0,s.jsx)(n.code,{children:"TinyORM"})," ",(0,s.jsx)(n.code,{children:"v0.34.0"}),")"]}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"disable_thread_local"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Remove all ",(0,s.jsx)(n.a,{href:"https://en.cppreference.com/w/c/language/storage_duration",children:(0,s.jsx)(n.code,{children:"thread_local"})})," storage duration specifiers, it disables multi-threading support."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"disable_orm"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Controls the compilation of all ",(0,s.jsx)(n.code,{children:"ORM-related"})," source code, when this option is ",(0,s.jsx)(n.code,{children:"enabled"}),", then only the ",(0,s.jsx)(n.code,{children:"query builder"})," without ",(0,s.jsx)(n.code,{children:"ORM"})," is compiled. Also excludes ",(0,s.jsx)(n.code,{children:"ORM-related"})," unit tests."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"disable_tom"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Controls the compilation of all ",(0,s.jsx)(n.code,{children:"Tom-related"})," source code, when this option is ",(0,s.jsx)(n.code,{children:"disabled"}),", then it also excludes ",(0,s.jsx)(n.code,{children:"Tom-related"})," unit tests."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"extern_constants"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ON"})}),(0,s.jsxs)(n.td,{children:["Use ",(0,s.jsx)(n.code,{children:"extern"})," constants instead of ",(0,s.jsx)(n.code,{children:"inline"})," constants in the ",(0,s.jsx)(n.code,{children:"shared build"}),".",(0,s.jsx)("br",{}),(0,s.jsx)(n.code,{children:"ON"})," is highly recommended for the ",(0,s.jsx)(n.code,{children:"shared build"})," ",(0,s.jsx)("small",{children:"(by default)"}),";",(0,s.jsx)("br",{}),"is always ",(0,s.jsx)(n.code,{children:"OFF"})," for the ",(0,s.jsx)(n.code,{children:"static build"}),".",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Available when: ",(0,s.jsx)("code",{children:"CONFIG(shared|dll):!inline_constants"})]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"inline_constants"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Use ",(0,s.jsx)(n.code,{children:"inline"})," constants instead of ",(0,s.jsx)(n.code,{children:"extern"})," constants in the ",(0,s.jsx)(n.code,{children:"shared build"}),".",(0,s.jsx)("br",{}),(0,s.jsx)(n.code,{children:"OFF"})," is highly recommended for the ",(0,s.jsx)(n.code,{children:"shared build"}),";",(0,s.jsx)("br",{}),"is always ",(0,s.jsx)(n.code,{children:"ON"})," for the ",(0,s.jsx)(n.code,{children:"static build"}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"link_pkgconfig_off"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Link against ",(0,s.jsx)(n.code,{children:"mysqlclient"})," or ",(0,s.jsx)(n.code,{children:"libmariadb"})," with ",(0,s.jsx)(n.code,{children:"PKGCONFIG"}),".",(0,s.jsx)("br",{}),"Used only in the ",(0,s.jsx)(n.code,{children:"Unix"})," and ",(0,s.jsx)(n.code,{children:"MinGW"})," ",(0,s.jsx)(n.strong,{children:"shared"})," build ",(0,s.jsxs)("small",{children:["(exactly ",(0,s.jsx)("code",{children:"win32-g++|win32-clang-g++"}),")"]})," and when ",(0,s.jsx)(n.code,{children:"mysql_ping"})," is also defined to link against ",(0,s.jsx)(n.code,{children:"mysqlclient"})," or ",(0,s.jsx)(n.code,{children:"libmariadb"}),", ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/conf.pri.example#L132",children:"source code"}),".",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Available when: ",(0,s.jsx)(n.code,{children:"unix:mysql_ping"})," or ",(0,s.jsx)("code",{children:"(win32-g++|win32-clang-g++):mysql_ping:!static:!staticlib"})]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"mysql_ping"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Enable ",(0,s.jsx)(n.code,{children:"Orm::MySqlConnection::pingDatabase()"})," method."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"tiny_ccache_win32"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ON"})}),(0,s.jsxs)(n.td,{children:["Enable compiler cache. ",(0,s.jsx)(n.a,{href:"https://ccache.dev/",children:"Homepage"}),(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["It works only on Windows systems. It works well with the MSYS2 ",(0,s.jsx)(n.code,{children:"g++"}),", ",(0,s.jsx)(n.code,{children:"clang++"}),", ",(0,s.jsx)(n.code,{children:"msvc"}),", and ",(0,s.jsx)(n.code,{children:"clang-cl"})," with ",(0,s.jsx)(n.code,{children:"msvc"}),". It disables ",(0,s.jsx)(n.code,{children:"precompile_header"})," as they are not supported on Windows and changes the ",(0,s.jsx)(n.code,{children:"-Zi"})," compiler option to the ",(0,s.jsx)(n.code,{children:"-Z7"})," for debug builds as the ",(0,s.jsx)(n.code,{children:"-Zi"})," compiler option is not supported (",(0,s.jsx)(n.a,{href:"https://github.com/ccache/ccache/issues/1040",children:"link"})," to the issue)."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"tom_example"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Build the ",(0,s.jsx)("abbr",{title:"TinyORM Migrations",children:(0,s.jsx)(n.code,{children:"tom"})})," console application example."]})]})]})]})})}),"\n",(0,s.jsxs)(n.p,{children:["Advanced ",(0,s.jsx)(n.code,{children:"TinyORM"})," options."]}),"\n",(0,s.jsx)("div",{className:"apitable-build-options",children:(0,s.jsx)(l.A,{children:(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Option Name"}),(0,s.jsx)(n.th,{children:"Default"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsx)(n.tbody,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ubsan"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Allows to enable ",(0,s.jsx)(n.a,{href:"https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html",children:"UBSan"})," sanitizer (Clang only)."]})]})})]})})}),"\n",(0,s.jsxs)(n.p,{children:["Important ",(0,s.jsx)(n.code,{children:"qmake"})," options."]}),"\n",(0,s.jsx)("div",{className:"apitable-build-options",children:(0,s.jsx)(l.A,{name:"qmake",children:(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsxs)(n.th,{children:[(0,s.jsx)(n.code,{children:"CONFIG"})," ",(0,s.jsx)("small",{children:"Option Name"})]}),(0,s.jsx)(n.th,{children:"Default"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ccache"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Enable compiler cache. ",(0,s.jsx)(n.a,{href:"https://ccache.dev/",children:"Homepage"}),(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["It works only on the Unix systems. It works well with ",(0,s.jsx)(n.code,{children:"g++"})," and ",(0,s.jsx)(n.code,{children:"clang++"})," and also supports precompiled headers."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"precompile_header"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"-"})}),(0,s.jsxs)(n.td,{children:["Enable precompiled headers, you can disable them with:",(0,s.jsx)("br",{})," ",(0,s.jsx)(n.code,{children:"CONFIG-=precompile_header"}),".",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["The ",(0,s.jsx)(n.code,{children:"precompile_header"})," is enabled by default on ",(0,s.jsx)(n.code,{children:"msvc"}),", ",(0,s.jsx)(n.code,{children:"g++"}),", ",(0,s.jsx)(n.code,{children:"clang++"}),", ",(0,s.jsx)(n.code,{children:"clang-cl"})," on ",(0,s.jsx)(n.code,{children:"Windows"})," and disabled by default on ",(0,s.jsx)(n.code,{children:"linux"}),"."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"static"}),(0,s.jsx)("br",{}),(0,s.jsx)(n.code,{children:"staticlib"})]}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Build as a ",(0,s.jsx)(n.code,{children:"static"})," library (lib only).",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["If you want to build all libraries in the ",(0,s.jsx)(n.code,{children:"TinyORM"})," project as static library archives and link against static libraries use the ",(0,s.jsx)(n.a,{href:"https://doc.qt.io/qt/qmake-variable-reference.html#config",children:(0,s.jsx)(n.code,{children:"CONFIG += static"})}),". Don't use the ",(0,s.jsx)(n.code,{children:"CONFIG += staticlib"}),".",(0,s.jsx)("br",{}),"See ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/NOTES.txt",children:"NOTES.txt"})," for more information (search ",(0,s.jsx)(n.code,{children:"static vs staticlib"}),")."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"static_runtime"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"OFF"})}),(0,s.jsxs)(n.td,{children:["Link against the ",(0,s.jsx)(n.code,{children:"shared"})," (dynamic) or ",(0,s.jsx)(n.code,{children:"static"})," run-time library.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["The ",(0,s.jsx)(n.code,{children:"-MD"})," becomes ",(0,s.jsx)(n.code,{children:"-MT"})," and ",(0,s.jsx)(n.code,{children:"-MDd"})," becomes ",(0,s.jsx)(n.code,{children:"-MTd"}),". It works only on ",(0,s.jsx)(n.code,{children:"MSVC"})," and ",(0,s.jsx)(n.code,{children:"MinGW"})," or ",(0,s.jsx)(n.code,{children:"MSYS2"}),".",(0,s.jsx)("br",{}),"Please ",(0,s.jsx)("u",{children:"don't use"})," this option.",(0,s.jsx)("br",{}),"Available when: ",(0,s.jsx)(n.code,{children:"msvc"})," or ",(0,s.jsx)(n.code,{children:"mingw"})]})]})]})]})]})})}),"\n",(0,s.jsxs)(n.h3,{id:"consume-tinyorm-library-qmake",children:["Consume TinyOrm library ",(0,s.jsx)("small",{children:"(qmake)"})]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/qmake/TinyOrm.pri",children:(0,s.jsx)(n.code,{children:"TinyOrm.pri"})})," file is available to simplify the integration of the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library into your application. It sets up and configures the ",(0,s.jsx)(n.code,{children:"CONFIG"})," and ",(0,s.jsx)(n.code,{children:"DEFINES"})," qmake variables, adds the ",(0,s.jsx)(n.code,{children:"TinyORM"}),", ",(0,s.jsx)("abbr",{title:"TinyORM Migrations",children:(0,s.jsx)(n.code,{children:"tom"})}),", and ",(0,s.jsx)(n.code,{children:"vcpkg"})," header files on the system ",(0,s.jsx)(n.code,{children:"INCLUDEPATH"})," (cross-platform using the ",(0,s.jsx)(n.code,{children:"-isystem"})," or ",(0,s.jsx)(n.code,{children:"-imsvc"}),"), links against the TinyORM ",(0,s.jsx)(n.code,{children:"shared"})," or ",(0,s.jsx)(n.code,{children:"static"})," library using the ",(0,s.jsx)(n.code,{children:"LIBS"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["You can use it to configure the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library when you are linking against it. It does a very similar thing like the CMake's ",(0,s.jsx)(n.code,{children:"Find Modules"})," feature."]}),"\n",(0,s.jsx)(n.h4,{id:"requirements",children:"Requirements"}),"\n",(0,s.jsx)(n.p,{children:"It has a few requirements, you need to:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["specify path to the ",(0,s.jsx)(n.code,{children:"TinyORM"})," qmake features (",(0,s.jsx)(n.code,{children:".prf"})," files) using the ",(0,s.jsx)(n.code,{children:"QMAKEFEATURES"})," variable that can only be set in the ",(0,s.jsx)(n.code,{children:".qmake.conf"})," file"]}),"\n",(0,s.jsxs)(n.li,{children:["specify ",(0,s.jsx)(n.code,{children:"qmake"})," or ",(0,s.jsx)(n.code,{children:"environment"})," variables to find the ",(0,s.jsx)(n.code,{children:"vcpkg"})," installation ",(0,s.jsxs)("small",{children:["(",(0,s.jsx)(n.code,{children:"TINY_VCPKG_ROOT"})," and ",(0,s.jsx)(n.code,{children:"TINY_VCPKG_TRIPLET"}),")"]})]}),"\n",(0,s.jsxs)(n.li,{children:["specify path to the ",(0,s.jsx)(n.code,{children:"TinyORM"})," build folder ",(0,s.jsxs)("small",{children:["(",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"}),")"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["you can specify it ",(0,s.jsx)(n.strong,{children:"manually"})]}),"\n",(0,s.jsxs)(n.li,{children:["or you can use ",(0,s.jsxs)(n.a,{href:"#partial-guessing-of-the-tinyorm_build_tree",children:["Partial guessing of the ",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})]})]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["build your application with the same ",(0,s.jsx)(n.code,{children:"CONFIG"})," ",(0,s.jsx)(n.code,{children:"qmake"})," variables that were used when building the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Let's explain one by one."}),"\n",(0,s.jsx)(n.h5,{id:"qmakefeatures",children:(0,s.jsx)(n.code,{children:"QMAKEFEATURES"})}),"\n",(0,s.jsxs)(n.p,{children:["Create the ",(0,s.jsx)(n.code,{children:".qmake.conf"})," file in your application root folder with the following content."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",metastring:"title='.qmake.conf'",children:"# Path to the PARENT folder of the TinyORM source folder\nTINY_MAIN_DIR = $$clean_path()\n# To find .env and .env.$$QMAKE_PLATFORM files in YOUR project\nTINY_DOTENV_ROOT = $$PWD\n\n# Path to the TinyORM build folder (specified manually)\nTINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_1_MSVC2019_64bit-Debug/)\n# vcpkg - range-v3 and tabulate\nTINY_VCPKG_ROOT = $$quote(/vcpkg/)\n#TINY_VCPKG_TRIPLET = x64-windows\n\n# To find .prf files, needed by eg. CONFIG += tiny_system_headers inline/extern_constants\nQMAKEFEATURES *= $$quote($$TINY_MAIN_DIR/TinyORM/qmake/features)\n"})}),"\n",(0,s.jsxs)(n.p,{children:["You can move all ",(0,s.jsx)(n.code,{children:"qmake"})," variables that are part of the ",(0,s.jsx)(n.code,{children:"qmake"})," configuration process to the ",(0,s.jsx)(n.code,{children:".env"})," file if you want (recommended), this is possible because the ",(0,s.jsx)(n.code,{children:"TinyOrm.pri"})," enables the ",(0,s.jsx)(n.a,{href:"#environment-files",children:(0,s.jsx)(n.code,{children:"Environment files"})})," feature by default."]}),"\n",(0,s.jsxs)(n.p,{children:["You can look at the ",(0,s.jsx)(n.a,{href:"/building/hello-world#auto-configure-using-qmake_conf-and-env",children:"Auto-configure using .qmake.conf and .env"})," example for ",(0,s.jsx)(n.code,{children:"Hello world"})," project of what must stay in the ",(0,s.jsx)(n.code,{children:"qmake.conf"})," file and what can be moved to the ",(0,s.jsx)(n.code,{children:".env"})," files."]}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["You can use the ",(0,s.jsxs)(n.a,{href:"#partial-guessing-of-the-tinyorm_build_tree",children:["Partial guessing of the ",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})]})," if you don't like to specify it manually."]})}),"\n",(0,s.jsxs)(n.h5,{id:"variables-affecting-tinyormpri",children:["Variables affecting ",(0,s.jsx)(n.code,{children:"TinyOrm.pri"})]}),"\n",(0,s.jsxs)(n.p,{children:["You must define the following variables before the ",(0,s.jsx)(n.code,{children:"TinyOrm.pri"})," is included:"]}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Variable Name"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})}),(0,s.jsxs)(n.td,{children:["Path to the ",(0,s.jsx)(n.code,{children:"TinyORM"})," build folder."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINY_VCPKG_ROOT"})}),(0,s.jsxs)(n.td,{children:["Path to the ",(0,s.jsx)(n.code,{children:"vcpkg"})," installation folder.",(0,s.jsx)("br",{}),"If not defined, then it tries to use the ",(0,s.jsx)(n.code,{children:"VCPKG_ROOT"})," environment variable."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINY_VCPKG_TRIPLET"})}),(0,s.jsxs)(n.td,{children:["The ",(0,s.jsx)(n.code,{children:"vcpkg"})," ",(0,s.jsx)(n.code,{children:"triplet"})," to use ",(0,s.jsx)("small",{children:"(vcpkg/installed/$$TINY_VCPKG_TRIPLET/)"}),".",(0,s.jsx)("br",{}),"If not defined, then it tries to guess the ",(0,s.jsx)(n.code,{children:"vcpkg"})," ",(0,s.jsx)(n.code,{children:"triplet"})," based on the current compiler and OS (based on the ",(0,s.jsx)(n.code,{children:"QMAKESPEC"}),"), and as the last thing, it tries to use the ",(0,s.jsx)(n.code,{children:"VCPKG_DEFAULT_TRIPLET"})," environment variable."]})]})]})]}),"\n",(0,s.jsx)(n.p,{children:"These variables will be set after the configuration is done:"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Variable Name"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINY_BUILD_SUBFOLDER"})}),(0,s.jsxs)(n.td,{children:["Folder by release type if ",(0,s.jsx)(n.code,{children:"CONFIG+=debug_and_release"})," is defined ",(0,s.jsx)("small",{children:"(/debug, /release, or an empty string)"}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINY_CCACHE_BUILD"})}),(0,s.jsxs)(n.td,{children:["To correctly link ",(0,s.jsx)(n.code,{children:"ccache"})," build against a ",(0,s.jsx)(n.code,{children:"ccache"})," build ",(0,s.jsx)("small",{children:"(_ccache or an empty string)"}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINY_MSVC_VERSION"})}),(0,s.jsxs)(n.td,{children:["The ",(0,s.jsx)(n.code,{children:"msvc"})," compiler string ",(0,s.jsx)("small",{children:"(MSVC2022 or MSVC2019)"}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINY_QT_VERSION_UNDERSCORED"})}),(0,s.jsxs)(n.td,{children:["Underscored ",(0,s.jsx)(n.code,{children:"Qt"})," version ",(0,s.jsx)("small",{children:"(eg. 6_7_1)"}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINY_RELEASE_TYPE_CAMEL"})}),(0,s.jsxs)(n.td,{children:["Build type string ",(0,s.jsx)("small",{children:"(Debug, Profile, or Release)"}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINY_VCPKG_INCLUDE"})}),(0,s.jsxs)(n.td,{children:["Path to the ",(0,s.jsx)(n.code,{children:"vcpkg"})," ",(0,s.jsx)(n.code,{children:"include"})," folder ",(0,s.jsx)("small",{children:"(vcpkg/installed//include/)"}),"."]})]})]})]}),"\n",(0,s.jsxs)(n.p,{children:["Then you simply include the ",(0,s.jsx)(n.code,{children:"TinyOrm.pri"})," in your project file."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",metastring:"title='AnyProject.pro'",children:"include($$TINY_MAIN_DIR/TinyORM/qmake/TinyOrm.pri)\n"})}),"\n",(0,s.jsxs)(n.p,{children:["And that is all, now you should be able to link against the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library. \ud83d\udc4c"]}),"\n",(0,s.jsx)(n.h5,{id:"manual-configuration-examples",children:"Manual configuration examples"}),"\n",(0,s.jsxs)(n.p,{children:["Frankly, there is no reason to use the Manual configuration (define the variables described below before the ",(0,s.jsx)(n.code,{children:"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."]}),"\n",(0,s.jsxs)(n.p,{children:["You will have to link against the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library manually if you don't set the ",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})," ",(0,s.jsx)(n.code,{children:"qmake"})," variable before the inclusion of the ",(0,s.jsx)(n.code,{children:"TinyOrm.pri"})," file. The ",(0,s.jsx)(n.code,{children:"INCLUDEPATH"})," is auto-detected every time."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:y.b,label:y.ux,children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",metastring:"{9}",children:"# Link against TinyORM library\n# ---\nTINY_MAIN_DIR = $$clean_path()\n\n# Configure TinyORM library\ninclude($$TINY_MAIN_DIR/TinyORM/qmake/TinyOrm.pri)\n\n# TinyORM library path\nTINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake)\nLIBS += $$quote(-L$$TINYORM_BUILD_TREE/build-TinyORM-Desktop_Qt_6_7_1_MSVC2019_64bit-Debug/src$${TINY_BUILD_SUBFOLDER}/)\nLIBS += -lTinyOrm\n"})})}),(0,s.jsx)(t.A,{value:y.xj,label:y.gg,children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",metastring:"{9}",children:"# Link against TinyORM library\n# ---\nTINY_MAIN_DIR = $$clean_path()\n\n# Configure TinyORM library\ninclude($$TINY_MAIN_DIR/TinyORM/qmake/TinyOrm.pri)\n\n# TinyORM library path\nTINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake)\nLIBS += $$quote(-L$$TINYORM_BUILD_TREE/build-TinyORM-Desktop_Qt_6_7_1_GCC_64bit-Debug/src$${TINY_BUILD_SUBFOLDER}/)\nLIBS += -lTinyOrm\n"})})})]}),"\n",(0,s.jsxs)(n.p,{children:["The same is true for the ",(0,s.jsx)(n.code,{children:"vcpkg"})," include path. If you don't set the ",(0,s.jsx)(n.code,{children:"TINY_VCPKG_ROOT"})," or have not defined the ",(0,s.jsx)(n.code,{children:"VCPKG_ROOT"})," environment variable, then you need to set up the ",(0,s.jsx)(n.code,{children:"INCLUDEPATH"})," for the ",(0,s.jsx)(n.code,{children:"vcpkg"})," that provides the ",(0,s.jsx)(n.code,{children:"range-v3"})," and ",(0,s.jsx)(n.code,{children:"tabulate"})," header files."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:y.b,label:y.ux,children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",children:"# vcpkg - range-v3 and tabulate\n# ---\nINCLUDEPATH += $$quote(/vcpkg/installed/x64-windows/include/)\n"})})}),(0,s.jsx)(t.A,{value:y.xj,label:y.gg,children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",children:"# vcpkg - range-v3 and tabulate\n# ---\nQMAKE_CXXFLAGS += -isystem $$shell_quote(/vcpkg/installed/x64-linux/include/)\n"})})})]}),"\n",(0,s.jsxs)(n.p,{children:["You can also use TinyORM's ",(0,s.jsx)(n.code,{children:"qmake"})," function ",(0,s.jsx)(n.code,{children:"tiny_add_system_includepath()"})," which handles ",(0,s.jsx)(n.code,{children:"INCLUDEPATH"})," in a cross-platform way."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",children:"# vcpkg - range-v3 and tabulate\n# ---\nload(tiny_system_includepath)\ntiny_add_system_includepath(/vcpkg/installed/x64-linux/include/)\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Do not forget to add ",(0,s.jsx)(n.code,{children:"TinyOrm0.dll"})," on the path on Windows and on the ",(0,s.jsx)(n.code,{children:"LD_LIBRARY_PATH"})," on Linux, so your application can find it during execution."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,name:"tinyorm-on-path",children:[(0,s.jsx)(t.A,{value:y.b,label:y.ux,children:(0,s.jsx)(c.A,{className:"language-powershell",children:`$env:Path = "${(0,x.OZ)(y.b,!1)}\\TinyORM\\TinyORM-builds-qmake\\build-debug;" + $env:Path`})}),(0,s.jsx)(t.A,{value:y.xj,label:y.gg,children:(0,s.jsx)(c.A,{className:"language-bash",children:`export LD_LIBRARY_PATH=${(0,x.OZ)(y.xj)}/TinyORM/TinyORM-builds-qmake/build-debug\${PATH:+:}$PATH`})})]}),"\n",(0,s.jsxs)(n.admonition,{type:"tip",children:[(0,s.jsxs)(n.p,{children:["On Linux ",(0,s.jsx)(n.code,{children:"-isystem"})," marks the directory as a system directory, it prevents warnings."]}),(0,s.jsxs)(n.p,{children:["On Windows you can use ",(0,s.jsx)(n.code,{children:"QMAKE_CXXFLAGS_WARN_ON = -external:anglebrackets -external:W0"}),", it applies a warning level 0 to the angel bracket includes; ",(0,s.jsx)(n.code,{children:"#include "}),"."]}),(0,s.jsxs)(n.p,{children:["With the ",(0,s.jsx)(n.code,{children:"clang-cl"})," with ",(0,s.jsx)(n.code,{children:"MSVC"})," you can use ",(0,s.jsx)(n.code,{children:"-imsvc"}),"."]})]}),"\n",(0,s.jsx)(n.h3,{id:"auto-configuration-internals",children:"Auto-configuration internals"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"qmake"})," build system does not support ",(0,s.jsx)(n.code,{children:"auto-configuration"})," of dependencies out of the box but ",(0,s.jsx)(n.code,{children:"TinyORM"})," from ",(0,s.jsx)(n.code,{children:"v0.34.0"})," added its own ",(0,s.jsx)(n.code,{children:"Auto-configuration"})," feature along with the ",(0,s.jsx)(n.code,{children:"tiny_dotenv"})," qmake feature. These new features allow us to ",(0,s.jsx)(n.code,{children:"auto-configure"})," ",(0,s.jsx)(n.code,{children:"TinyORM"})," project, and with their help, the ",(0,s.jsx)(n.code,{children:"conf.pri"})," files can be ",(0,s.jsx)("u",{children:"skipped entirely"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["While it adds additional complexity to the ",(0,s.jsx)(n.code,{children:"qmake"})," configuration process, the benefits are significant."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"Auto-configuration"})," feature is designed to find the ",(0,s.jsx)(n.code,{children:"vcpkg"})," and ",(0,s.jsx)(n.code,{children:"MySQL"})," installations, and ",(0,s.jsx)(n.code,{children:"tiny_dotenv"})," to include the ",(0,s.jsx)(n.code,{children:".env"})," and ",(0,s.jsx)(n.code,{children:".env.(win32|unix|mingw)"})," files in the project's root folder. These new features can be configured using ",(0,s.jsx)(n.code,{children:"qmake"})," and ",(0,s.jsx)(n.code,{children:"environment"})," variables, and they also contain some guessing logic if these variables are not defined."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"Auto-configuration"})," feature can be turned off using the ",(0,s.jsx)(n.a,{href:"#disable_autoconf",children:(0,s.jsx)(n.code,{children:"disable_autoconf"})})," ",(0,s.jsx)(n.code,{children:"qmake"})," configuration option (eg. ",(0,s.jsx)(n.code,{children:"CONFIG*=disable_autoconf"}),")."]}),"\n",(0,s.jsxs)(n.p,{children:["These are ",(0,s.jsx)("u",{children:(0,s.jsx)(n.code,{children:"qmake"})})," and ",(0,s.jsx)("u",{children:(0,s.jsx)(n.code,{children:"environment"})})," variables that affect the ",(0,s.jsx)(n.code,{children:"Auto-configuration"})," feature:"]}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Variable Name"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINY_VCPKG_ROOT"})}),(0,s.jsxs)(n.td,{children:["Path to the ",(0,s.jsx)(n.code,{children:"vcpkg"})," installation folder.",(0,s.jsx)("br",{}),"If not defined, then it tries to use the ",(0,s.jsx)(n.code,{children:"VCPKG_ROOT"})," environment variable."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINY_VCPKG_TRIPLET"})}),(0,s.jsxs)(n.td,{children:["The ",(0,s.jsx)(n.code,{children:"vcpkg"})," ",(0,s.jsx)(n.code,{children:"triplet"})," to use ",(0,s.jsx)("small",{children:"(vcpkg/installed/$$TINY_VCPKG_TRIPLET/)"}),".",(0,s.jsx)("br",{}),"If not defined, then it tries to guess the ",(0,s.jsx)(n.code,{children:"vcpkg"})," ",(0,s.jsx)(n.code,{children:"triplet"})," based on the current compiler and OS (based on the ",(0,s.jsx)(n.code,{children:"QMAKESPEC"}),"), and as the last thing, it tries to use the ",(0,s.jsx)(n.code,{children:"VCPKG_DEFAULT_TRIPLET"})," environment variable."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINY_MYSQL_ROOT"})}),(0,s.jsxs)(n.td,{children:["Path to the ",(0,s.jsx)(n.code,{children:"MySQL"})," installation folder.",(0,s.jsx)("br",{}),"If not defined, then it tries to guess the ",(0,s.jsx)(n.code,{children:"MySQL"})," installation folder (",(0,s.jsx)(n.code,{children:"win32"})," only): ",(0,s.jsx)("code",{children:"$$(ProgramFiles)/MySQL/MySQL Server (8.4|8.3|8.2|8.1|8.0|5.7)/"})]})]})]})]}),"\n",(0,s.jsxs)(n.p,{children:["You can set these variables in the ",(0,s.jsx)(n.code,{children:".env"})," (recommended) or ",(0,s.jsx)(n.code,{children:"conf.pri"})," files, in the ",(0,s.jsx)(n.code,{children:".qmake.conf"})," file (or wherever you want), or as environment variables."]}),"\n",(0,s.jsxs)(n.p,{children:["These variables will be set after ",(0,s.jsx)(n.code,{children:"auto-configuration"})," is done:"]}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Variable Name"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINY_VCPKG_INCLUDE"})}),(0,s.jsxs)(n.td,{children:["Path to the ",(0,s.jsx)(n.code,{children:"vcpkg"})," ",(0,s.jsx)(n.code,{children:"include"})," folder ",(0,s.jsx)("small",{children:"(vcpkg/installed//include/)"}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINY_MYSQL_INCLUDE"})}),(0,s.jsxs)(n.td,{children:["Path to the ",(0,s.jsx)(n.code,{children:"MySQL"})," ",(0,s.jsx)(n.code,{children:"include"})," folder ",(0,s.jsx)("small",{children:"(MySQL Server 8.4/include/)"}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINY_MYSQL_LIB"})}),(0,s.jsxs)(n.td,{children:["Path to the ",(0,s.jsx)(n.code,{children:"MySQL"})," ",(0,s.jsx)(n.code,{children:"lib"})," folder ",(0,s.jsx)("small",{children:"(MySQL Server 8.4/lib/)"}),"."]})]})]})]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"TINY_MYSQL_INCLUDE"})," and ",(0,s.jsx)(n.code,{children:"TINY_MYSQL_LIB"})," are only set on ",(0,s.jsx)(n.code,{children:"win32"})," platform except ",(0,s.jsx)(n.code,{children:"mingw"}),"."]}),"\n",(0,s.jsx)(n.h4,{id:"environment-files",children:"Environment files"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"tiny_dotenv"})," feature allows us to define the ",(0,s.jsx)(n.code,{children:".env"})," and ",(0,s.jsx)(n.code,{children:".env.$$TINY_DOTENV_PLATFORM"})," files in the project's root folder. These files are loaded as early as possible so you can affect the ",(0,s.jsx)(n.code,{children:"qmake"})," configuration process. On the other hand, the ",(0,s.jsx)(n.code,{children:"conf.pri"})," files are loaded as late as possible, and they can be used to override the ",(0,s.jsx)(n.code,{children:"qmake"})," configuration."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:".env"})," file is included ",(0,s.jsx)("u",{children:"first"})," and is included on all platforms."]}),"\n",(0,s.jsxs)(n.p,{children:["There is only one requirement for this feature to work correctly, and that is to set the ",(0,s.jsx)(n.code,{children:"TINY_DOTENV_ROOT"})," ",(0,s.jsx)(n.code,{children:"qmake"})," variable to the project's root folder. This variable is ",(0,s.jsx)(n.strong,{children:"already"})," set in the ",(0,s.jsx)(n.code,{children:".qmake.conf"})," file for the ",(0,s.jsx)(n.code,{children:"TinyORM"})," project."]}),"\n",(0,s.jsx)(n.p,{children:"Then the following names are taken into account: .env, .env.win32, .env.unix, .env.mingw"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",metastring:"title='.qmake.conf'",children:"# To find .env and .env.$$QMAKE_PLATFORM files\nTINY_DOTENV_ROOT = $$PWD\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"tiny_dotenv"})," feature can be turned off using the ",(0,s.jsx)(n.a,{href:"#disable_dotenv",children:(0,s.jsx)(n.code,{children:"disable_dotenv"})})," ",(0,s.jsx)(n.code,{children:"qmake"})," configuration option (eg. ",(0,s.jsx)(n.code,{children:"CONFIG*=disable_dotenv"}),")."]}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Environment files"})," don't work in the ",(0,s.jsx)(n.code,{children:"CMake"})," builds."]})}),"\n",(0,s.jsxs)(n.h4,{id:"partial-guessing-of-the-tinyorm_build_tree",children:["Partial guessing of the ",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})]}),"\n",(0,s.jsxs)(n.p,{children:["You don't have to manually define the ",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})," in ",(0,s.jsx)(n.code,{children:".env"})," or ",(0,s.jsx)(n.code,{children:".qmake.conf"})," files. The ",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})," absolute path can be put together for you (this is happening inside the ",(0,s.jsx)(n.code,{children:"variables.pri"})," file) and ",(0,s.jsx)(n.code,{children:"TinyORM"})," build folder name can be guessed for you too."]}),"\n",(0,s.jsxs)(n.p,{children:["You must define the following variables before the ",(0,s.jsx)(n.code,{children:"TinyOrm.pri"})," will be included to make this real (set them in the ",(0,s.jsx)(n.code,{children:".qmake.conf"}),"):"]}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Variable Name"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINY_MAIN_DIR"})}),(0,s.jsxs)(n.td,{children:["Path to the ",(0,s.jsx)(n.strong,{children:"PARENT"})," folder of the ",(0,s.jsx)(n.code,{children:"TinyORM"})," source folder."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINY_BUILD_TREE"})}),(0,s.jsxs)(n.td,{children:["Path to the ",(0,s.jsx)(n.strong,{children:"current"})," build tree - ",(0,s.jsx)(n.code,{children:"TINY_BUILD_TREE = $$shadowed($$PWD)"}),"."]})]})]})]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"TINY_MAIN_DIR"})," is required for another features anyway (so it should already be set) and all that's left is to set the ",(0,s.jsx)(n.code,{children:"TINY_BUILD_TREE"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",metastring:"title='.qmake.conf'",children:"# Path to the current build tree (used to guess the TinyORM build tree)\nTINY_BUILD_TREE = $$shadowed($$PWD)\n"})}),"\n",(0,s.jsxs)(n.p,{children:["If you will follow this pattern or logic then you can switch ",(0,s.jsx)(n.code,{children:"QtCreator Kits"})," and the ",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})," will be ",(0,s.jsx)(n.strong,{children:"auto-generated"})," correctly and will always point to the correct ",(0,s.jsx)(n.code,{children:"TinyORM"})," build tree."]}),"\n",(0,s.jsxs)(n.p,{children:["It works this way, all is happening inside the ",(0,s.jsx)(n.code,{children:"variables.pri"}),", it takes a build folder name for the ",(0,s.jsx)(n.strong,{children:"current"})," project eg. ",(0,s.jsx)(n.code,{children:"build-HelloWorld-Desktop_Qt_6_7_1_MSVC2022_64bit-Debug"}),", replaces the ",(0,s.jsx)(n.code,{children:"HelloWorld"})," with the ",(0,s.jsx)(n.code,{children:"TinyORM"})," and as we already know the ",(0,s.jsx)(n.code,{children:"TinyORM"})," build folder location we can simply concatenate these paths like ",(0,s.jsx)(n.code,{children:"$$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_1_MSVC2022_64bit-Debug"}),"."]}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsxs)(n.p,{children:["This will only work if you follow the recommended ",(0,s.jsx)(n.a,{href:"#folders-structure",children:(0,s.jsx)(n.code,{children:"Folders structure"})}),"."]})}),"\n",(0,s.jsx)(n.h3,{id:"manual-configuration-internals",children:"Manual configuration internals"}),"\n",(0,s.jsxs)(n.p,{children:["There is not much to say about the ",(0,s.jsx)(n.code,{children:"Manual configuration"})," feature. It uses ",(0,s.jsx)(n.code,{children:"conf.pri"})," files (there are four, one for every project or sub-project), and every project has prepared its own ",(0,s.jsx)(n.code,{children:"conf.pri.example"})," file for faster initial configuration."]}),"\n",(0,s.jsxs)(n.p,{children:["These ",(0,s.jsx)(n.code,{children:"conf.pri.example"})," files are nicely commented on, so you can see what needs to be modified. The ",(0,s.jsx)(n.code,{children:"conf.pri"})," files are loaded as late as possible, and they can be used to override the ",(0,s.jsx)(n.code,{children:"qmake"})," configuration."]}),"\n",(0,s.jsxs)(n.p,{children:["If the ",(0,s.jsx)(n.code,{children:"Auto-configuration"})," feature is disabled and there are no ",(0,s.jsx)(n.code,{children:"conf.pri"})," files, then the ",(0,s.jsx)(n.code,{children:"TinyORM"})," ",(0,s.jsx)(n.code,{children:"qmake"})," configuration or build will fail at 100%."]}),"\n",(0,s.jsxs)(n.p,{children:["These ",(0,s.jsx)(n.code,{children:"conf.pri"})," files are intended for configuring qmake's ",(0,s.jsx)(n.code,{children:"INCLUDEPATH"})," and ",(0,s.jsx)(n.code,{children:"LIBS"}),", ",(0,s.jsx)(n.code,{children:"CONFIG"})," or eg. ",(0,s.jsx)(n.code,{children:"QMAKE_LFLAGS"}),", or any other ",(0,s.jsx)(n.code,{children:"qmake"})," options or variables."]}),"\n",(0,s.jsx)(n.h2,{id:"ccache-support",children:"Ccache support"}),"\n",(0,s.jsxs)(n.p,{children:["The TinyORM supports the ",(0,s.jsx)(n.a,{href:"https://ccache.dev/",children:(0,s.jsx)(n.code,{children:"ccache"})})," out of the box for all ",(0,s.jsx)(n.a,{href:"/supported-compilers",children:"supported compilers"}),". For ",(0,s.jsx)(n.code,{children:"qmake"})," you can enable it using the ",(0,s.jsx)(n.a,{href:"#ccache",children:(0,s.jsx)(n.code,{children:"CONFIG+=ccache"})})," and for ",(0,s.jsx)(n.code,{children:"CMake"})," you can set the ",(0,s.jsx)(n.a,{href:"#CMAKE_CXX_COMPILER_LAUNCHER",children:(0,s.jsx)(n.code,{children:"CMAKE_CXX_COMPILER_LAUNCHER=ccache"})}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["On ",(0,s.jsx)(n.code,{children:"Linux"})," it's clear, the ",(0,s.jsx)(n.code,{children:"ccache"})," is fully supported and works also with the ",(0,s.jsx)(n.code,{children:"precompiled headers"}),". But was necessary to add some workarounds to the ",(0,s.jsx)(n.code,{children:"qmake"}),"/",(0,s.jsx)(n.code,{children:"CMake"})," build systems to make out of the box support on ",(0,s.jsx)(n.code,{children:"Windows"}),". When you enable the ",(0,s.jsx)(n.code,{children:"ccache"})," on ",(0,s.jsx)(n.code,{children:"Windows"})," then the build system disables ",(0,s.jsx)(n.code,{children:"precompiled headers"})," and replaces the ",(0,s.jsx)(n.code,{children:"-Zi"})," compiler option with the ",(0,s.jsx)(n.code,{children:"-Z7"})," (link to the ",(0,s.jsx)(n.a,{href:"https://github.com/ccache/ccache/issues/1040",children:"issue"}),")."]}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["You can install the ",(0,s.jsx)(n.code,{children:"ccache"})," using the ",(0,s.jsx)(n.code,{children:"scoop install ccache"})," command on Windows. See the ",(0,s.jsx)(n.a,{href:"/dependencies#linux-installation-ccache",children:"Dependencies"})," page for how to install ",(0,s.jsx)(n.code,{children:"ccache"})," on Linux."]})})]})}function I(e={}){const{wrapper:n}={...(0,d.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(M,{...e})}):M(e)}},9365:(e,n,i)=>{i.d(n,{A:()=>l});i(6540);var s=i(4164);const d={tabItem:"tabItem_Ymn6"};var r=i(4848);function l(e){let{children:n,hidden:i,className:l}=e;return(0,r.jsx)("div",{role:"tabpanel",className:(0,s.A)(d.tabItem,l),hidden:i,children:n})}},1470:(e,n,i)=>{i.d(n,{A:()=>_});var s=i(6540),d=i(4164),r=i(3104),l=i(6347),c=i(205),t=i(7485),o=i(1682),a=i(9466);function h(e){return s.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,s.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function x(e){const{values:n,children:i}=e;return(0,s.useMemo)((()=>{const e=n??function(e){return h(e).map((e=>{let{props:{value:n,label:i,attributes:s,default:d}}=e;return{value:n,label:i,attributes:s,default:d}}))}(i);return function(e){const n=(0,o.X)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[n,i])}function j(e){let{value:n,tabValues:i}=e;return i.some((e=>e.value===n))}function u(e){let{queryString:n=!1,groupId:i}=e;const d=(0,l.W6)(),r=function(e){let{queryString:n=!1,groupId:i}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!i)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return i??null}({queryString:n,groupId:i});return[(0,t.aZ)(r),(0,s.useCallback)((e=>{if(!r)return;const n=new URLSearchParams(d.location.search);n.set(r,e),d.replace({...d.location,search:n.toString()})}),[r,d])]}function p(e){const{defaultValue:n,queryString:i=!1,groupId:d}=e,r=x(e),[l,t]=(0,s.useState)((()=>function(e){let{defaultValue:n,tabValues:i}=e;if(0===i.length)throw new Error("Docusaurus error: the component requires at least one children component");if(n){if(!j({value:n,tabValues:i}))throw new Error(`Docusaurus error: The has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${i.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const s=i.find((e=>e.default))??i[0];if(!s)throw new Error("Unexpected error: 0 tabValues");return s.value}({defaultValue:n,tabValues:r}))),[o,h]=u({queryString:i,groupId:d}),[p,m]=function(e){let{groupId:n}=e;const i=function(e){return e?`docusaurus.tab.${e}`:null}(n),[d,r]=(0,a.Dv)(i);return[d,(0,s.useCallback)((e=>{i&&r.set(e)}),[i,r])]}({groupId:d}),b=(()=>{const e=o??p;return j({value:e,tabValues:r})?e:null})();(0,c.A)((()=>{b&&t(b)}),[b]);return{selectedValue:l,selectValue:(0,s.useCallback)((e=>{if(!j({value:e,tabValues:r}))throw new Error(`Can't select invalid tab value=${e}`);t(e),h(e),m(e)}),[h,m,r]),tabValues:r}}var m=i(2303);const b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var f=i(4848);function g(e){let{className:n,block:i,selectedValue:s,selectValue:l,tabValues:c}=e;const t=[],{blockElementScrollPositionUntilNextRender:o}=(0,r.a_)(),a=e=>{const n=e.currentTarget,i=t.indexOf(n),d=c[i].value;d!==s&&(o(n),l(d))},h=e=>{let n=null;switch(e.key){case"Enter":a(e);break;case"ArrowRight":{const i=t.indexOf(e.currentTarget)+1;n=t[i]??t[0];break}case"ArrowLeft":{const i=t.indexOf(e.currentTarget)-1;n=t[i]??t[t.length-1];break}}n?.focus()};return(0,f.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,d.A)("tabs",{"tabs--block":i},n),children:c.map((e=>{let{value:n,label:i,attributes:r}=e;return(0,f.jsx)("li",{role:"tab",tabIndex:s===n?0:-1,"aria-selected":s===n,ref:e=>t.push(e),onKeyDown:h,onClick:a,...r,className:(0,d.A)("tabs__item",b.tabItem,r?.className,{"tabs__item--active":s===n}),children:i??n},n)}))})}function y(e){let{lazy:n,children:i,selectedValue:d}=e;const r=(Array.isArray(i)?i:[i]).filter(Boolean);if(n){const e=r.find((e=>e.props.value===d));return e?(0,s.cloneElement)(e,{className:"margin-top--md"}):null}return(0,f.jsx)("div",{className:"margin-top--md",children:r.map(((e,n)=>(0,s.cloneElement)(e,{key:n,hidden:e.props.value!==d})))})}function T(e){const n=p(e);return(0,f.jsxs)("div",{className:(0,d.A)("tabs-container",b.tabList),children:[(0,f.jsx)(g,{...n,...e}),(0,f.jsx)(y,{...n,...e})]})}function _(e){const n=(0,m.A)();return(0,f.jsx)(T,{...e,children:h(e.children)},String(n))}},6684:(e,n,i)=>{i.d(n,{A:()=>a});var s=i(6540),d=i(3427),r=i(6347);const l={apiTable:"apiTable_flxF"};var c=i(4848);function t(e,n){let{name:i,children:l}=e;const t=function(e){let n=e;for(;(0,s.isValidElement)(n);)[n]=s.Children.toArray(n.props.children);if("string"!=typeof n)throw new Error(`Could not extract APITable row name from JSX tree:\n${JSON.stringify(e,null,2)}`);return n}(l),o=i?`${i}-${t}`:t,a=`#${o}`,h=(0,r.W6)();return(0,d.A)().collectAnchor(o),(0,c.jsx)("tr",{id:o,tabIndex:0,ref:h.location.hash===a?n:void 0,onClick:e=>{const n=e.target;[n,n.parentElement].some((e=>"A"===e?.tagName.toUpperCase()))||h.push(a)},onKeyDown:e=>{"Enter"===e.key&&h.push(a)},children:l.props.children})}const o=s.forwardRef(t);function a(e){let{children:n,name:i}=e;if("table"!==n.type)throw new Error("Bad usage of APITable component.\nIt is probably that your Markdown table is malformed.\nMake sure to double-check you have the appropriate number of columns for each table row.");const[d,r]=s.Children.toArray(n.props.children),t=(0,s.useRef)(null);(0,s.useEffect)((()=>{t.current?.focus()}),[t]);const a=s.Children.map(r.props.children,(e=>(0,c.jsx)(o,{name:i,ref:t,children:e})));return(0,c.jsxs)("table",{className:l.apiTable,children:[d,(0,c.jsx)("tbody",{children:a})]})}},7324:(e,n,i)=>{i.d(n,{$E:()=>m,A3:()=>f,CW:()=>b,Dx:()=>a,F4:()=>x,Fi:()=>o,J_:()=>_,LQ:()=>g,Lf:()=>v,OO:()=>d,Q7:()=>y,b:()=>c,cy:()=>t,gg:()=>u,kl:()=>j,os:()=>h,pW:()=>r,ux:()=>p,vf:()=>s,xj:()=>l,xt:()=>T});const s="shell",d="database",r="application",l="bash",c="pwsh",t="zsh",o="maria",a="mysql",h="postgres",x="sqlite",j="application",u="bash",p="pwsh",m="zsh",b="MariaDB",f="MySQL",g="PostgreSQL",y="SQLite",T="tinyorm.org",_="$HOME/Code/c/",v="$env:USERPROFILE\\Code\\c\\"},6362:(e,n,i)=>{i.d(n,{A:()=>r});var s=i(6540),d=i(1838);function r(){const e=(0,s.useContext)(d.A);if(null!=e)return e;throw new Error("useRootFolderContext is used outside of Layout component.")}},6694:(e,n,i)=>{i.d(n,{OZ:()=>t,Sn:()=>l,T3:()=>a,bw:()=>o,nC:()=>h,np:()=>c});var s=i(6362),d=i(2303),r=i(7324);const l=function(e,n){return void 0===n&&(n=!0),x((0,s.A)().rootFolder[e]??o(e),e,n)},c=()=>(0,s.A)().rootFolder[r.pW]??o(r.pW),t=function(e,n){if(void 0===n&&(n=!0),null==e)throw new Error("The groupId in the applicationFolderPath() can not be empty.");const i=n||e!==r.b?"/":"\\";return x(l(e)+i+c(),e,n)};function o(e){if(null==e)throw new Error("The groupId in the folderDefaultValue() can not be empty.");if(!(0,d.A)())return"";switch(e){case r.b:return r.Lf;case r.xj:return r.J_;case r.pW:return r.xt;default:throw new Error(`No default value for '${e}' groupId in the folderDefaultValue().`)}}function a(e){return e===r.pW}function h(e,n){if(null==n||""===n)return n;const i="$ENV{$1}$2";switch(e){case r.b:return u(n).replace(/\$env:(.+?)(\/.*)/,i);case r.xj:return n.replace(/\$(.+?)(\/.*)/,i);default:throw new Error(`Unsupported shell type '${e}' in the convertToCmakeEnvVariable().`)}}function x(e,n,i){if(void 0===i&&(i=!0),null==e||""===e)return e;if(n!==r.b)return j(e);const s=j(e);return i?u(s):function(e){return null==e||""===e?e:e.replaceAll(/\/+/g,"\\")}(s)}function j(e){return null==e||""===e?e:e.replace(/[/\\]+$/,"")}function u(e){return null==e||""===e?e:e.replaceAll(/\\+(?! )/g,"/")}},2721:(e,n,i)=>{i.d(n,{A:()=>s});const s=i.p+"assets/images/qmake-additional_arguments-14d3b6b82ad6d28db5b999a462500a6a.png"},7619:(e,n,i)=>{i.d(n,{A:()=>s});const s=i.p+"assets/images/qmake-build_settings-7caa6d7c86232484b82acb24b5a3a6a7.png"},885:(e,n,i)=>{i.d(n,{A:()=>s});const s=i.p+"assets/images/qmake-configure_project-0b6821ea0523567dab9f21b3215055a3.png"}}]); \ No newline at end of file diff --git a/assets/js/8a8faf8d.488a21d5.js b/assets/js/8a8faf8d.2e50ae37.js similarity index 99% rename from assets/js/8a8faf8d.488a21d5.js rename to assets/js/8a8faf8d.2e50ae37.js index 75eb5afd2..3756359fe 100644 --- a/assets/js/8a8faf8d.488a21d5.js +++ b/assets/js/8a8faf8d.2e50ae37.js @@ -1 +1 @@ -"use strict";(self.webpackChunktinyorm_org=self.webpackChunktinyorm_org||[]).push([[129],{5270:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>p,contentTitle:()=>u,default:()=>j,frontMatter:()=>h,metadata:()=>m,toc:()=>g});var s=i(4848),t=i(8453),a=i(8774),r=i(2364),l=i(9365),o=i(1470),d=i(7324),c=i(6694);const h={sidebar_position:3,sidebar_label:"Migrations",description:"How to compile the TinyORM migrations (tom) C++ console application on Windows and Linux.",keywords:["c++ orm","building","migrations","tinyorm"]},u="Building: Migrations",m={id:"building/migrations",title:"Building: Migrations",description:"How to compile the TinyORM migrations (tom) C++ console application on Windows and Linux.",source:"@site/docs/building/migrations.mdx",sourceDirName:"building",slug:"/building/migrations",permalink:"/building/migrations",draft:!1,unlisted:!1,tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3,sidebar_label:"Migrations",description:"How to compile the TinyORM migrations (tom) C++ console application on Windows and Linux.",keywords:["c++ orm","building","migrations","tinyorm"]},sidebar:"tinyormSidebar",previous:{title:"Hello world",permalink:"/building/hello-world"},next:{title:"\ud83d\udcc4 Features Summary",permalink:"/features-summary"}},p={},g=[{value:"Introduction",id:"introduction",level:2},{value:"Install dependencies",id:"install-dependencies",level:2},{value:"Using vcpkg.json (manifest mode)",id:"using-vcpkg-json-manifest-mode",level:4},{value:"Using vcpkg install (manually)",id:"using-vcpkg-install-manually",level:4},{value:"Source code",id:"source-code",level:2},{value:"Main file",id:"main-file",level:3},{value:"Migrations",id:"migrations",level:3},{value:"Seeders",id:"seeders",level:3},{value:"Migrations with CMake",id:"migrations-with-cmake",level:2},{value:"CMake project",id:"cmake-project",level:3},{value:"Build migrations",id:"build-migrations-cmake",level:3},{value:"Execute migrations",id:"execute-migrations-cmake",level:3},{value:"Migrations with qmake",id:"migrations-with-qmake",level:2},{value:"qmake project",id:"qmake-project",level:3},{value:"Auto-configure using .qmake.conf and .env",id:"auto-configure-using-qmakeconf-and-env",level:4},{value:"Migrations source files",id:"migrations-source-files",level:4},{value:"Seeders source files",id:"seeders-source-files",level:4},{value:"Build migrations",id:"build-migrations-qmake",level:3},{value:"Execute migrations",id:"execute-migrations-qmake",level:3},{value:"Finish",id:"finish",level:2}];function x(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"building-migrations",children:"Building: Migrations"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#introduction",children:"Introduction"})}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#install-dependencies",children:"Install dependencies"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#using-vcpkg-json-manifest-mode",children:"Using vcpkg.json"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#using-vcpkg-install-manually",children:"Using vcpkg install"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#source-code",children:"Source code"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#main-file",children:"Main file"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#migrations",children:"Migrations"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#seeders",children:"Seeders"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#migrations-with-cmake",children:"Migrations with CMake"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#cmake-project",children:"CMake project"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#build-migrations-cmake",children:"Build migrations"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#execute-migrations-cmake",children:"Execute migrations"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#migrations-with-qmake",children:"Migrations with qmake"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#qmake-project",children:"qmake project"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#build-migrations-qmake",children:"Build migrations"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#execute-migrations-qmake",children:"Execute migrations"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#finish",children:"Finish"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsxs)(n.p,{children:["We will try to create a working migrations console application called as ",(0,s.jsx)("abbr",{title:"TinyORM migrations",children:(0,s.jsx)(n.code,{children:"tom"})})," in the terminal with the ",(0,s.jsx)(n.code,{children:"CMake"})," and in the ",(0,s.jsx)(n.code,{children:"QtCreator IDE"})," with the ",(0,s.jsx)(n.code,{children:"qmake"})," build systems."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"tom"})," console application also expects the following ",(0,s.jsx)(n.a,{href:"/building/tinyorm#folders-structure",children:"folders structure"}),", let's create them."]}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(r.A,{className:"language-powershell",children:`cd ${(0,c.OZ)(d.b)}\nmkdir tom/tom\ncd tom`})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(r.A,{className:"language-bash",children:`cd ${(0,c.OZ)(d.xj)}\nmkdir -p tom/tom\ncd tom`})})]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"TinyORM"})," source tree contains the ",(0,s.jsx)(n.code,{children:"tom"})," example application, you can inspire or look at the ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/tree/main/examples/tom",children:"source code"}),". Also, ",(0,s.jsx)(n.code,{children:"TinyORM"})," unit tests use a ",(0,s.jsx)(n.code,{children:"tom"})," migrations internally to create the database structure, internally called as the ",(0,s.jsxs)(n.a,{href:"https://github.com/silverqx/TinyORM/tree/main/tests/testdata_tom",children:[(0,s.jsx)(n.code,{children:"tom"})," migrations for unit tests"]}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["All these three console applications the ",(0,s.jsx)(n.code,{children:"tom"})," example, ",(0,s.jsx)(n.code,{children:"tom"})," migrations for unit tests, and the application described in this tutorial have practically identical source code (the main.cpp file)."]}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"tom"})," is able to generate ",(0,s.jsx)("a",{href:"https://en.wikipedia.org/wiki/Data_definition_language",title:"Data Definition Language",children:"DDL"})," queries for all the ",(0,s.jsx)(n.a,{href:"/database/getting-started#introduction",children:"supported databases"})," databases."]})}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["You can see the ",(0,s.jsx)(n.a,{href:"/features-summary#tom-console-application",children:"Tom showcase image"})," of how the resulting ",(0,s.jsx)(n.code,{children:"tom"})," console application will look like."]})}),"\n",(0,s.jsx)(n.h2,{id:"install-dependencies",children:"Install dependencies"}),"\n",(0,s.jsxs)(n.p,{children:["First, install the ",(0,s.jsx)(n.code,{children:"vcpkg"})," package manager as is described ",(0,s.jsx)(n.a,{href:"/building/tinyorm#vcpkg",children:"here"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"range-v3"})," and ",(0,s.jsx)(n.code,{children:"tabulate"})," libraries are required dependencies because ",(0,s.jsx)(n.code,{children:"TinyORM"})," uses them in header files, you have to install them before you can use ",(0,s.jsx)(n.code,{children:"TinyORM"}),". The ",(0,s.jsx)(n.code,{children:"tabulate"})," library is only needed in the ",(0,s.jsx)(n.code,{children:"tom"})," migrations it's used by the ",(0,s.jsx)(n.code,{children:"migrate:status"})," command."]}),"\n",(0,s.jsxs)(n.p,{children:["There are two ways how to install the ",(0,s.jsx)(n.code,{children:"range-v3"})," and ",(0,s.jsx)(n.code,{children:"tabulate"})," libraries using ",(0,s.jsx)(n.code,{children:"vcpkg"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Also, don't forget to build the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library with the ",(0,s.jsx)(n.code,{children:"tom"})," source code enabled (it's enabled by default) as is described ",(0,s.jsx)(n.a,{href:"/building/tinyorm",children:"here"}),"."]}),"\n",(0,s.jsxs)(n.h4,{id:"using-vcpkg-json-manifest-mode",children:["Using vcpkg.json ",(0,s.jsx)("small",{children:"(manifest mode)"})]}),"\n",(0,s.jsxs)(n.p,{children:["Create a ",(0,s.jsx)(n.code,{children:"vcpkg.json"})," file with the following content. ",(0,s.jsx)(n.code,{children:"CMake"})," example below uses this method."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd tom\nvim vcpkg.json\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",metastring:"title='vcpkg.json'",children:'{\n "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json",\n "name": "tom",\n "version-semver": "0.1.0",\n "maintainers": "Silver Zachara ",\n "description": "Tom console application for TinyORM C++ library",\n "homepage": "https://github.com/silverqx/TinyORM",\n "documentation": "https://www.tinyorm.org/building/migrations",\n "supports": "!(uwp | arm | android | emscripten | osx | ios | xbox | freebsd | openbsd | wasm32)",\n "dependencies": [\n "range-v3",\n "tabulate"\n ]\n}\n'})}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Only ",(0,s.jsx)(n.code,{children:"CMake"})," via the ",(0,s.jsx)(n.code,{children:"toolchain file"})," supports this method."]})}),"\n",(0,s.jsxs)(n.h4,{id:"using-vcpkg-install-manually",children:["Using vcpkg install ",(0,s.jsx)("small",{children:"(manually)"})]}),"\n",(0,s.jsxs)(n.p,{children:["This method can be used with both ",(0,s.jsx)(n.code,{children:"CMake"})," and ",(0,s.jsx)(n.code,{children:"qmake"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd ../../vcpkg\n\nvcpkg search range-v3\nvcpkg search tabulate\nvcpkg install range-v3 tabulate\nvcpkg list\n"})}),"\n",(0,s.jsx)(n.h2,{id:"source-code",children:"Source code"}),"\n",(0,s.jsxs)(n.p,{children:["Let's start in the ",(0,s.jsx)(n.code,{children:"tom"})," project folder."]}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(r.A,{className:"language-powershell",children:`cd ${(0,c.OZ)(d.b)}/tom/tom`})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(r.A,{className:"language-bash",children:`cd ${(0,c.OZ)(d.xj)}/tom/tom`})})]}),"\n",(0,s.jsx)(n.h3,{id:"main-file",children:"Main file"}),"\n",(0,s.jsxs)(n.p,{children:["Create ",(0,s.jsx)(n.code,{children:"main.cpp"})," source file."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"vim main.cpp\n"})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["To paste a source code correctly in ",(0,s.jsx)(n.code,{children:"vim"}),", press ",(0,s.jsx)("kbd",{children:"Shift"})," + ",(0,s.jsx)("kbd",{children:"p"}),"."]})}),"\n",(0,s.jsx)(n.p,{children:"And paste the following code."}),"\n",(0,s.jsx)(a.A,{id:"string-constants-example"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-cpp",metastring:"title='main.cpp'",children:'#include \n\n#include \n\n#include "migrations/2014_10_12_000000_create_posts_table.hpp"\n\n#include "seeders/databaseseeder.hpp"\n\nusing Orm::DatabaseManager;\nusing Orm::DB;\n\nusing TomApplication = Tom::Application;\n\nusing namespace Migrations; // NOLINT(google-build-using-namespace)\nusing namespace Seeders; // NOLINT(google-build-using-namespace)\n\n/*! Create the database manager instance and add a database connection. */\nstd::shared_ptr setupDatabaseManager();\n\n/*! C++ main function. */\nint main(int argc, char *argv[])\n{\n try {\n // Ownership of the shared_ptr()\n auto db = setupDatabaseManager();\n\n return TomApplication(argc, argv, std::move(db), "TOM_EXAMPLE_ENV")\n .migrations()\n .seeders()\n // Fire it up \ud83d\udd25\ud83d\ude80\u2728\n .run();\n\n } catch (const std::exception &e) {\n\n TomApplication::logException(e);\n }\n\n return EXIT_FAILURE;\n}\n\nstd::shared_ptr setupDatabaseManager()\n{\n using namespace Orm::Constants; // NOLINT(google-build-using-namespace)\n\n // Ownership of the shared_ptr()\n return DB::create({\n {driver_, QMYSQL},\n {host_, qEnvironmentVariable("DB_MYSQL_HOST", H127001)},\n {port_, qEnvironmentVariable("DB_MYSQL_PORT", P3306)},\n {database_, qEnvironmentVariable("DB_MYSQL_DATABASE", EMPTY)},\n {username_, qEnvironmentVariable("DB_MYSQL_USERNAME", EMPTY)},\n {password_, qEnvironmentVariable("DB_MYSQL_PASSWORD", EMPTY)},\n {charset_, qEnvironmentVariable("DB_MYSQL_CHARSET", UTF8MB4)},\n {collation_, qEnvironmentVariable("DB_MYSQL_COLLATION", UTF8MB40900aici)},\n {timezone_, TZ00},\n /* Specifies what time zone all QDateTime-s will have, the overridden default is\n the Qt::UTC, set to the Qt::LocalTime or QtTimeZoneType::DontConvert to use\n the system local time. */\n {qt_timezone, QVariant::fromValue(Qt::UTC)},\n {strict_, true},\n },\n QStringLiteral("tinyorm_tom_mysql")); // shell:connection\n}\n'})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["If you have defined more database connections then you can tag the lines with the database connection names with the ",(0,s.jsx)(n.code,{children:"// shell:connection"})," comment and this connection names will be provided to the bash, zsh, pwsh completions for the ",(0,s.jsx)(n.code,{children:"--database="})," option \ud83d\ude0e, ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/examples/tom/main.cpp#L74",children:"example"}),"."]})}),"\n",(0,s.jsx)(n.h3,{id:"migrations",children:"Migrations"}),"\n",(0,s.jsxs)(n.p,{children:["If you have already built the ",(0,s.jsx)(n.code,{children:"tom"})," application then you can generate a migrations using the ",(0,s.jsx)(n.a,{href:"/database/migrations#generating-migrations",children:(0,s.jsx)(n.code,{children:"make:migration"})})," command \ud83d\ude0e."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"tom make:migration create_posts_table\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Below is the expected folders structure for the migrations. The ",(0,s.jsx)(n.a,{href:"#migrations-source-files",children:(0,s.jsx)(n.code,{children:"migrations.pri"})})," file is used only by the ",(0,s.jsx)(n.code,{children:"qmake"})," build system and is not needed with ",(0,s.jsx)(n.code,{children:"CMake"})," builds."]}),"\n",(0,s.jsx)(a.A,{id:"folders-structure"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-text",children:"tom/\n\u2514\u2500\u2500 database/\n \u251c\u2500\u2500 migrations/\n \u251c\u2500\u2500 seeders/\n \u251c\u2500\u2500 migrations.pri\n \u2514\u2500\u2500 seeders.pri\n"})}),"\n",(0,s.jsx)(n.p,{children:"Let's create the first migration manually."}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(r.A,{className:"language-powershell",children:"mkdir database/migrations\n\nvim database/migrations/2014_10_12_000000_create_posts_table.hpp"})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(r.A,{className:"language-bash",children:"mkdir -p database/migrations\n\nvim database/migrations/2014_10_12_000000_create_posts_table.hpp"})})]}),"\n",(0,s.jsx)(n.p,{children:"And paste the following code."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-cpp",metastring:"title='database/migrations/2014_10_12_000000_create_posts_table.hpp'",children:'#pragma once\n\n#include \n\nnamespace Migrations\n{\n\n struct CreatePostsTable : Migration\n {\n /*! Filename of the migration file. */\n T_MIGRATION\n\n /*! Run the migrations. */\n void up() const override\n {\n Schema::create("posts", [](Blueprint &table)\n {\n table.id();\n\n table.string(NAME);\n table.timestamps();\n });\n }\n\n /*! Reverse the migrations. */\n void down() const override\n {\n Schema::dropIfExists("posts");\n }\n };\n\n} // namespace Migrations\n'})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"TinyORM"})," source tree contains the ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/tests/database/migrations/2014_10_12_000000_create_posts_table.hpp#L5",children:(0,s.jsx)(n.code,{children:"CreatePostsTable"})})," example migration that also acts as the full-fledged example migration. It has defined and also nicely commented all possible features that migration classes can use or define."]})}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["If you want, you can also build the ",(0,s.jsx)(n.code,{children:"tom"})," application without the migrations, simply comment out the ",(0,s.jsx)(n.code,{children:"migrations"})," method and the corresponding ",(0,s.jsx)(n.code,{children:'#include "migrations/xyz.hpp"'})," files."]})}),"\n",(0,s.jsx)(n.h3,{id:"seeders",children:"Seeders"}),"\n",(0,s.jsxs)(n.p,{children:["If you have already built the ",(0,s.jsx)(n.code,{children:"tom"})," application then you can generate a seeder using the ",(0,s.jsx)(n.a,{href:"/database/seeding#writing-seeders",children:(0,s.jsx)(n.code,{children:"make:seeder"})})," command \ud83d\ude0e."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"tom make:seeder PostSeeder\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The expected folders structure is described a few paragraphs ",(0,s.jsx)(n.a,{href:"#folders-structure",children:"above"}),". The ",(0,s.jsx)(n.a,{href:"#seeders-source-files",children:(0,s.jsx)(n.code,{children:"seeders.pri"})})," file is used only by the ",(0,s.jsx)(n.code,{children:"qmake"})," build system and is not needed with ",(0,s.jsx)(n.code,{children:"CMake"})," builds."]}),"\n",(0,s.jsx)(n.p,{children:"Let's create the root seeder class manually."}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(r.A,{className:"language-powershell",children:"mkdir database/seeders\n\nvim database/seeders/databaseseeder.hpp"})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(r.A,{className:"language-bash",children:"mkdir -p database/seeders\n\nvim database/seeders/databaseseeder.hpp"})})]}),"\n",(0,s.jsx)(n.p,{children:"And paste the following code."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-cpp",metastring:"title='database/seeders/databaseseeder.hpp'",children:'#pragma once\n\n#include \n\nnamespace Seeders\n{\n\n /*! Main database seeder. */\n struct DatabaseSeeder : Seeder\n {\n /*! Run the database seeders. */\n void run() override\n {\n DB::table("posts")->insert({\n {{"name", "1. post"}},\n {{"name", "2. post"}},\n });\n }\n };\n\n} // namespace Seeders\n'})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"TinyORM"})," source tree contains the ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/tests/database/seeders/databaseseeder.hpp#L8",children:(0,s.jsx)(n.code,{children:"DatabaseSeeder"})})," root seeder example class that also acts as the full-fledged example seeder. It has defined and also nicely commented all possible features that seeder classes can use or define."]})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["You can create more seeder classes like this and use the ",(0,s.jsx)(n.code,{children:"call<>()"})," method to invoke them as is described in the ",(0,s.jsx)(n.a,{href:"/database/seeding#calling-additional-seeders",children:"Calling Additional Seeders"})," section."]})}),"\n",(0,s.jsx)(n.h2,{id:"migrations-with-cmake",children:"Migrations with CMake"}),"\n",(0,s.jsxs)(n.p,{children:["Create a folder for the ",(0,s.jsx)(n.code,{children:"CMake"})," build."]}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(r.A,{className:"language-powershell",children:"cd ..\nmkdir tom-builds-cmake/build-debug\n\ncd tom"})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(r.A,{className:"language-bash",children:"cd ..\nmkdir -p tom-builds-cmake/build-debug\n\ncd tom"})})]}),"\n",(0,s.jsx)(n.h3,{id:"cmake-project",children:"CMake project"}),"\n",(0,s.jsxs)(n.p,{children:["Create ",(0,s.jsx)(n.code,{children:"CMakeLists.txt"})," file with the following content. I leave the comments in the ",(0,s.jsx)(n.code,{children:"CMakeLists.txt"})," file because it's not as simple as the ",(0,s.jsx)(n.code,{children:"Hello world"})," example; to make it clear what's going on."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-cmake",metastring:"title='CMakeLists.txt'",children:'cmake_minimum_required(VERSION VERSION 3.22...3.29 FATAL_ERROR)\n\n# Specify the C++ standard\nset(CMAKE_CXX_STANDARD 20)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\nset(CMAKE_CXX_EXTENSIONS OFF)\n\n# Initialize variables\n# ---\n\nset(Tom_ns tom)\nset(Tom_target tom)\n\nfile(REAL_PATH "../../TinyORM" TinyMainDir)\n\nset(TinyOrmSourceDir "${TinyMainDir}/TinyORM")\nset(TinyOrmBuildDir "${TinyMainDir}/TinyORM-builds-cmake/build-debug")\n\n# TinyORM CMake modules (needed to set the executable version and RC file on Windows)\nlist(APPEND CMAKE_MODULE_PATH "${TinyOrmSourceDir}/cmake/CommonModules")\n\n# build tree\nlist(APPEND CMAKE_PREFIX_PATH "${TinyOrmBuildDir}")\n\n# Initialize Project Version\n# ---\n\ninclude(TinyHelpers)\ntiny_read_version(TINY_VERSION\n TINY_VERSION_MAJOR TINY_VERSION_MINOR TINY_VERSION_PATCH TINY_VERSION_TWEAK\n VERSION_HEADER "${TinyOrmSourceDir}/tom/include/tom/version.hpp"\n PREFIX TINYTOM\n HEADER_FOR "${Tom_ns}"\n)\n\n# Basic project\n# ---\n\nproject(${Tom_ns}\n DESCRIPTION "Tom console application for TinyORM C++ library"\n HOMEPAGE_URL "https://www.tinyorm.org"\n LANGUAGES CXX\n VERSION ${TINY_VERSION}\n)\n\n# Tom command-line application\n# ---\n\nadd_executable(${Tom_target}\n main.cpp\n)\nadd_executable(${Tom_ns}::${Tom_target} ALIAS ${Tom_target})\n\n# Tom command-line application specific configuration\n# ---\n\nset_target_properties(${Tom_target}\n PROPERTIES\n C_VISIBILITY_PRESET "hidden"\n CXX_VISIBILITY_PRESET "hidden"\n VISIBILITY_INLINES_HIDDEN YES\n VERSION ${PROJECT_VERSION}\n)\n\ntarget_include_directories(${Tom_target}\n PRIVATE "$"\n)\n\n# Tom command-line application defines\n# ---\n\ntarget_compile_definitions(${Tom_target}\n PRIVATE\n PROJECT_TOM\n)\n\n# Windows resource and manifest files\n# ---\n\n# Find icons, tom/version.hpp, and Windows manifest file for MinGW\nif(CMAKE_SYSTEM_NAME STREQUAL "Windows")\n tiny_set_rc_flags("-I \\"${TinyOrmSourceDir}/tom/resources\\"")\nendif()\n\ninclude(TinyResourceAndManifest)\ntiny_resource_and_manifest(${Tom_target}\n OUTPUT_DIR "${TINY_BUILD_GENDIR}/tmp/"\n RESOURCES_DIR "${TinyOrmSourceDir}/tom/resources"\n)\n\n# Resolve and link dependencies\n# ---\n\nfind_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)\nfind_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)\nfind_package(TinyOrm 0.37.3 CONFIG REQUIRED)\n\n# Unconditional dependencies\ntarget_link_libraries(${Tom_target}\n PRIVATE\n Qt${QT_VERSION_MAJOR}::Core\n TinyOrm::TinyOrm\n)\n'})}),"\n",(0,s.jsx)(n.h3,{id:"build-migrations-cmake",children:"Build migrations"}),"\n",(0,s.jsxs)(n.p,{children:["Now you are ready to configure ",(0,s.jsx)(n.code,{children:"tom"})," ",(0,s.jsx)(n.code,{children:"CMake"})," application. Don't forget to prepare the build environment with the ",(0,s.jsx)(n.a,{href:"/building/tinyorm#windows-prerequisites",children:(0,s.jsx)(n.code,{children:"qtenv6.ps1"})})," command if you are building with the ",(0,s.jsx)(n.code,{children:"msvc"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd ../tom-builds-cmake/build-debug\n"})}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(r.A,{className:"language-powershell",children:`cmake.exe \`\n-S "${(0,c.OZ)(d.b)}/tom/tom" \`\n-B "${(0,c.OZ)(d.b)}/tom/tom-builds-cmake/build-debug" \`\n-G 'Ninja' \`\n-D CMAKE_BUILD_TYPE:STRING='Debug' \`\n-D CMAKE_TOOLCHAIN_FILE:FILEPATH="${(0,c.Sn)(d.b)}/vcpkg/scripts/buildsystems/vcpkg.cmake" \`\n-D CMAKE_CXX_SCAN_FOR_MODULES:BOOL=OFF \`\n-D CMAKE_INSTALL_PREFIX:PATH="${(0,c.Sn)(d.b)}/tmp/tom"`})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(r.A,{className:"language-bash",children:`cmake \\\n-S "${(0,c.OZ)(d.xj)}/tom/tom" \\\n-B "${(0,c.OZ)(d.xj)}/tom/tom-builds-cmake/build-debug" \\\n-G 'Ninja' \\\n-D CMAKE_BUILD_TYPE:STRING='Debug' \\\n-D CMAKE_TOOLCHAIN_FILE:FILEPATH="${(0,c.Sn)(d.xj)}/vcpkg/scripts/buildsystems/vcpkg.cmake" \\\n-D CMAKE_CXX_SCAN_FOR_MODULES:BOOL=OFF \\\n-D CMAKE_INSTALL_PREFIX:PATH="${(0,c.Sn)(d.xj)}/tmp/tom"`})})]}),"\n",(0,s.jsx)(n.p,{children:"And build."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cmake --build . --target all\n"})}),"\n",(0,s.jsx)(n.h3,{id:"execute-migrations-cmake",children:"Execute migrations"}),"\n",(0,s.jsxs)(n.p,{children:["Do not forget to add ",(0,s.jsx)(n.code,{children:"TinyOrm0d.dll"})," on the path on Windows and on the ",(0,s.jsx)(n.code,{children:"LD_LIBRARY_PATH"})," on Linux, so ",(0,s.jsx)(n.code,{children:"tom"})," application can find it during execution, as is described ",(0,s.jsx)(n.a,{href:"/building/tinyorm#tinyorm-on-path-cmake",children:"here"}),"."]}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,name:"tinyorm-on-path",children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(r.A,{className:"language-powershell",children:`$env:Path = "${(0,c.OZ)(d.b,!1)}\\TinyORM\\TinyORM-builds-cmake\\build-debug;" + $env:Path`})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(r.A,{className:"language-bash",children:`export LD_LIBRARY_PATH=${(0,c.OZ)(d.xj)}/TinyORM/TinyORM-builds-cmake/build-debug\${PATH:+:}$PATH`})})]}),"\n",(0,s.jsxs)(n.p,{children:["Execute ",(0,s.jsx)(n.code,{children:"tom"})," application."]}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-powershell",children:".\\tom.exe migrate:status\n"})})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"./tom migrate:status\n"})})})]}),"\n",(0,s.jsx)(n.p,{children:"The output will look something like this."}),"\n",(0,s.jsx)("img",{src:i(53).A,alt:"Tom migrations - migrate:status command output",width:"660"}),"\n",(0,s.jsxs)(n.p,{children:["See also the ",(0,s.jsx)(n.a,{href:"#finish",children:"final thoughts"})," on how to verify the ",(0,s.jsx)(n.code,{children:"tom"})," executable file properties."]}),"\n",(0,s.jsx)(n.p,{children:"Happy migrating \ud83c\udf89\ud83d\udc4c"}),"\n",(0,s.jsx)(n.h2,{id:"migrations-with-qmake",children:"Migrations with qmake"}),"\n",(0,s.jsxs)(n.p,{children:["Create a folder for the ",(0,s.jsx)(n.code,{children:"qmake"})," build."]}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(r.A,{className:"language-powershell",children:`cd ${(0,c.OZ)(d.b)}/tom\n\nmkdir tom-builds-qmake`})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(r.A,{className:"language-bash",children:`cd ${(0,c.OZ)(d.xj)}/tom\n\nmkdir tom-builds-qmake`})})]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"#source-code",children:(0,s.jsx)(n.code,{children:"source code"})})," is the same as for the ",(0,s.jsx)(n.code,{children:"Migrations with CMake"})," console application."]}),"\n",(0,s.jsx)(n.h3,{id:"qmake-project",children:"qmake project"}),"\n",(0,s.jsxs)(n.p,{children:["Create ",(0,s.jsx)(n.code,{children:"tom.pro"})," qmake file with the following content."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd tom\nvim tom.pro\n"})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["To paste a source code correctly in ",(0,s.jsx)(n.code,{children:"vim"}),", press ",(0,s.jsx)("kbd",{children:"Shift"})," + ",(0,s.jsx)("kbd",{children:"p"}),"."]})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",metastring:"title='tom.pro'",children:"QT -= gui\n\nTEMPLATE = app\nTARGET = tom\n\nCONFIG *= cmdline\n\nDEFINES *= PROJECT_TOM\n\nSOURCES += $$PWD/main.cpp\n\n# Database migrations\ninclude($$PWD/database/migrations.pri)\n# Database seeders\ninclude($$PWD/database/seeders.pri)\n\n# Auto-configure TinyORM library for the migrations purposes \ud83d\udd25\ninclude($$TINY_MAIN_DIR/TinyORM/qmake/tom.pri)\n"})}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsxs)(n.p,{children:["The exact ",(0,s.jsx)(n.a,{href:"/building/tinyorm#folders-structure",children:"folders structure"})," is crucial in this example because the paths to the ",(0,s.jsx)(n.code,{children:"TinyORM"})," source and build folders are relative."]})}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsx)(n.p,{children:"Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!"})}),"\n",(0,s.jsxs)(n.h4,{id:"auto-configure-using-qmakeconf-and-env",children:[(0,s.jsx)(n.code,{children:"Auto-configure"})," using ",(0,s.jsx)(n.code,{children:".qmake.conf"})," and ",(0,s.jsx)(n.code,{children:".env"})]}),"\n",(0,s.jsxs)(n.p,{children:["If you want to have properly configured ",(0,s.jsx)(n.code,{children:"DEFINES"})," (C preprocessor macros), have Qt headers marked as system headers, or eg. have properly set properties of an executable file such as version and description, then you need to specify a path to the ",(0,s.jsx)(n.code,{children:"TinyORM"})," qmake features (",(0,s.jsx)(n.code,{children:".prf"})," files) which handle this correctly; this path is provided by the ",(0,s.jsx)(n.code,{children:"QMAKEFEATURES"})," variable and can only be set in the ",(0,s.jsx)(n.code,{children:".qmake.conf"})," file."]}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["Read the ",(0,s.jsx)(n.a,{href:"/building/tinyorm#consume-tinyorm-library-qmake",children:"Consume TinyOrm library (qmake)"})," section, as everything that is described in that section applies here as well."]})}),"\n",(0,s.jsxs)(n.p,{children:["Create the ",(0,s.jsx)(n.code,{children:".qmake.conf"})," file in the ",(0,s.jsx)(n.code,{children:"tom"})," application root folder with the following content."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",metastring:"title='.qmake.conf'",children:"# Path to the PARENT folder of the TinyORM source folder\nTINY_MAIN_DIR = $$clean_path($$PWD/../../TinyORM/)\n# To find .env and .env.$$QMAKE_PLATFORM files\nTINY_DOTENV_ROOT = $$PWD\n# Path to the current build tree (used to guess the TinyORM build tree)\n#TINY_BUILD_TREE = $$shadowed($$PWD)\n\n# To find .prf files, needed by eg. CONFIG += tiny_system_headers inline/extern_constants\nQMAKEFEATURES *= $$quote($$TINY_MAIN_DIR/TinyORM/qmake/features)\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Then, create a ",(0,s.jsx)("code",{children:".env.(win32|unix|mingw)"})," file in the ",(0,s.jsx)(n.code,{children:"tom"})," application root folder with the following content."]}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:".env.win32",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",children:"# Names and values of these qmake variables are crucial, they are used in the tom.pro\n# Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!\n\n# Path to the TinyORM build folder\nTINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_0_MSVC2022_64bit-Debug/)\n\n# Path to the vcpkg - range-v3 and tabulate\n# Will use the TINY_VCPKG_ROOT or VCPKG_ROOT environment variable if is empty\nTINY_VCPKG_ROOT = $$clean_path($$PWD/../../../vcpkg/)\nTINY_VCPKG_TRIPLET = x64-windows\n\n# Enable ccache wrapper\n#CONFIG *= tiny_ccache_win32\n"})})}),(0,s.jsx)(l.A,{value:d.xj,label:".env.unix",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",children:"# Names and values of these qmake variables are crucial, they are used in the tom.pro\n# Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!\n\n# Path to the TinyORM build folder\nTINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_0_clang16_64bit_ccache-Debug/)\n\n# Path to the vcpkg - range-v3 and tabulate\n# Will use the TINY_VCPKG_ROOT or VCPKG_ROOT environment variable if is empty\nTINY_VCPKG_ROOT = $$clean_path($$PWD/../../../vcpkg/)\nTINY_VCPKG_TRIPLET = x64-linux\n\n# Use faster linker\nclang: CONFIG *= use_lld_linker\nelse: CONFIG *= use_gold_linker\n\n# Or use the mold linker\n#QMAKE_LFLAGS *= -fuse-ld=mold\n"})})}),(0,s.jsx)(l.A,{value:"mingw",label:".env.mingw",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",children:"# Names and values of these qmake variables are crucial, they are used in the tom.pro\n# Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!\n\n# Path to the TinyORM build folder\nTINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_0_MSYS2_UCRT64_clang_64bit-Debug/)\n\n# Path to the vcpkg - range-v3 and tabulate\n# Will use the TINY_VCPKG_ROOT or VCPKG_ROOT environment variable if is empty\nTINY_VCPKG_ROOT = $$clean_path($$PWD/../../../vcpkg/)\nTINY_VCPKG_TRIPLET = x64-mingw-dynamic\n\n# Enable ccache wrapper\n#CONFIG *= tiny_ccache_win32\n\n# Use faster linker (for both GCC and Clang)\n# CONFIG *= use_lld_linker does not work on MinGW\nQMAKE_LFLAGS *= -fuse-ld=lld\n"})})})]}),"\n",(0,s.jsxs)(n.p,{children:["Don't forget to update the ",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})," and ",(0,s.jsx)(n.code,{children:"TINY_VCPKG_ROOT"})," folder paths to your needs if you are not using the recommended ",(0,s.jsx)(n.a,{href:"/building/tinyorm#folders-structure",children:(0,s.jsx)(n.code,{children:"Folders structure"})}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["You can use the ",(0,s.jsxs)(n.a,{href:"/building/tinyorm#partial-guessing-of-the-tinyorm_build_tree",children:["Partial guessing of the ",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})]})," if you don't like to specify it manually. Just comment out the ",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})," and uncomment the ",(0,s.jsx)(n.code,{children:"TINY_BUILD_TREE = $$shadowed($$PWD)"})," in the ",(0,s.jsx)(n.code,{children:".qmake.conf"})," file."]}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["You can entirely avoid the ",(0,s.jsx)(n.code,{children:".env"})," files, just move the ",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})," to the ",(0,s.jsx)(n.code,{children:".qmake.conf"})," or remove it by help of ",(0,s.jsxs)(n.a,{href:"/building/tinyorm#partial-guessing-of-the-tinyorm_build_tree",children:["Partial guessing of the ",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})]})," and set the ",(0,s.jsx)(n.code,{children:"VCPKG_ROOT"})," environment variable at system level as is described in ",(0,s.jsx)(n.a,{href:"/building/tinyorm#set-up-vcpkg-environment",children:(0,s.jsx)(n.code,{children:"Set up vcpkg environment"})}),"."]})}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["Configuring by the ",(0,s.jsx)(n.code,{children:".qmake.conf"})," and ",(0,s.jsx)(n.code,{children:".env"})," files has one big advantage, which is that you don't have to modify the project files."]})}),"\n",(0,s.jsx)(n.h4,{id:"migrations-source-files",children:"Migrations source files"}),"\n",(0,s.jsxs)(n.p,{children:["Create ",(0,s.jsx)(n.code,{children:"database/migrations.pri"})," file and paste the following code."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",metastring:"title='database/migrations.pri'",children:"INCLUDEPATH *= $$PWD\n\nHEADERS += \\\n $$PWD/migrations/2014_10_12_000000_create_posts_table.hpp \\\n"})}),"\n",(0,s.jsx)(n.h4,{id:"seeders-source-files",children:"Seeders source files"}),"\n",(0,s.jsxs)(n.p,{children:["Create ",(0,s.jsx)(n.code,{children:"database/seeders.pri"})," file and paste the following code."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",metastring:"title='database/seeders.pri'",children:"INCLUDEPATH *= $$PWD\n\nHEADERS += \\\n $$PWD/seeders/databaseseeder.hpp \\\n"})}),"\n",(0,s.jsx)(n.h3,{id:"build-migrations-qmake",children:"Build migrations"}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["I recommend creating a new ",(0,s.jsx)(n.code,{children:"Session"})," in the ",(0,s.jsx)(n.code,{children:"QtCreator IDE"})," as is described ",(0,s.jsx)(n.a,{href:"/building/tinyorm#open-qtcreator-ide",children:"here"}),"."]})}),"\n",(0,s.jsxs)(n.p,{children:["Now you can open the ",(0,s.jsx)(n.code,{children:"tom.pro"})," project in the ",(0,s.jsx)(n.code,{children:"QtCreator IDE"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["This will open the ",(0,s.jsx)(n.code,{children:"Configure Project"})," tab, select some kit and update build folder paths to meet our ",(0,s.jsx)(n.a,{href:"/building/tinyorm#folders-structure",children:"folders structure"})," or like you want."]}),"\n",(0,s.jsx)("img",{src:i(2394).A,alt:"tom - QtCreator - Configure Project",width:"760"}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["You can force the ",(0,s.jsx)(n.code,{children:"QtCreator"})," to generate a build folders structure as is described ",(0,s.jsx)(n.a,{href:"/building/tinyorm#qtcreator-default-build-directory",children:"here"}),"."]})}),"\n",(0,s.jsxs)(n.p,{children:["You are ready to configure build options, hit ",(0,s.jsx)("kbd",{children:"Ctrl"}),"+",(0,s.jsx)("kbd",{children:"5"})," to open ",(0,s.jsx)(n.code,{children:"Project Settings"})," tab and select ",(0,s.jsx)(n.code,{children:"Build"})," in the left sidebar to open the ",(0,s.jsx)(n.code,{children:"Build Settings"}),", it should look similar to the following picture."]}),"\n",(0,s.jsx)("img",{src:i(6106).A,className:"no-blurry",alt:"tom - QtCreator - Build Settings",width:"760"}),"\n",(0,s.jsxs)(n.p,{children:["Disable ",(0,s.jsx)(n.code,{children:"QML debugging and profiling"})," and ",(0,s.jsx)(n.code,{children:"Qt Quick Compiler"}),", they are not used."]}),"\n",(0,s.jsxs)(n.p,{children:["In the left sidebar open ",(0,s.jsx)(n.code,{children:"Dependencies"})," and check ",(0,s.jsx)(n.code,{children:"TinyORM"})," project and ",(0,s.jsx)(n.code,{children:"Synchronize configuration"}),", this setting ensures that the current project will be rebuilt correctly when the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library source code changes."]}),"\n",(0,s.jsxs)(n.p,{children:["Everything is ready to build, you can press ",(0,s.jsx)("kbd",{children:"Ctrl"}),"+",(0,s.jsx)("kbd",{children:"b"})," to build the project."]}),"\n",(0,s.jsx)(n.h3,{id:"execute-migrations-qmake",children:"Execute migrations"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"QtCreator"})," takes care of all the necessary configurations, sets up the build environment correctly, and also prepends dependency libraries on the system path on Windows and on the ",(0,s.jsx)(n.code,{children:"LD_LIBRARY_PATH"})," on Linux."]}),"\n",(0,s.jsxs)(n.p,{children:["The only thing you might want to change is to run the ",(0,s.jsx)(n.code,{children:"tom"})," application in the new terminal window. To do so, hit ",(0,s.jsx)("kbd",{children:"Ctrl"}),"+",(0,s.jsx)("kbd",{children:"5"})," to open the ",(0,s.jsx)(n.code,{children:"Project Settings"})," tab and select ",(0,s.jsx)(n.code,{children:"Run"})," in the left sidebar to open the ",(0,s.jsx)(n.code,{children:"Run Settings"}),", then in the ",(0,s.jsx)(n.code,{children:"Run"})," section select the ",(0,s.jsx)(n.code,{children:"Run in terminal"})," checkbox."]}),"\n",(0,s.jsxs)(n.p,{children:["You can also set the ",(0,s.jsx)(n.code,{children:"Command line arguments"})," in this ",(0,s.jsx)(n.code,{children:"Run"})," section, eg. the ",(0,s.jsx)(n.code,{children:"migrate:status"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["To execute the ",(0,s.jsx)(n.code,{children:"tom"})," application press ",(0,s.jsx)("kbd",{children:"Ctrl"})," + ",(0,s.jsx)("kbd",{children:"r"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["The output will look ",(0,s.jsx)(n.strong,{children:"very similar"})," to this if you add more migrations."]}),"\n",(0,s.jsx)("img",{src:i(53).A,alt:"Tom migrations - migrate:status command output",width:"660"}),"\n",(0,s.jsx)(n.p,{children:"Happy migrating \ud83c\udf89\ud83d\udc4c"}),"\n",(0,s.jsx)(n.h2,{id:"finish",children:"Finish"}),"\n",(0,s.jsxs)(n.p,{children:["As the last thing, you can check that all the file properties were correctly set by the ",(0,s.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/windows/win32/menurc/resource-compiler",children:(0,s.jsx)(n.code,{children:"rc"})})," compiler."]}),"\n",(0,s.jsxs)(n.p,{children:["Find the ",(0,s.jsx)(n.code,{children:"tom.exe"})," file and press ",(0,s.jsx)("kbd",{children:"Alt"})," + ",(0,s.jsx)("kbd",{children:"Enter"})," to open the file properties. To check the executable manifest you can use eg. the ",(0,s.jsx)(n.a,{href:"http://www.angusj.com/resourcehacker/",children:"Resource Hacker"}),"."]}),"\n",(0,s.jsx)("img",{src:i(4679).A,alt:"tom.exe file properties detail",width:"440"})]})}function j(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(x,{...e})}):x(e)}},9365:(e,n,i)=>{i.d(n,{A:()=>r});i(6540);var s=i(4164);const t={tabItem:"tabItem_Ymn6"};var a=i(4848);function r(e){let{children:n,hidden:i,className:r}=e;return(0,a.jsx)("div",{role:"tabpanel",className:(0,s.A)(t.tabItem,r),hidden:i,children:n})}},1470:(e,n,i)=>{i.d(n,{A:()=>v});var s=i(6540),t=i(4164),a=i(3104),r=i(6347),l=i(205),o=i(7485),d=i(1682),c=i(9466);function h(e){return s.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,s.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function u(e){const{values:n,children:i}=e;return(0,s.useMemo)((()=>{const e=n??function(e){return h(e).map((e=>{let{props:{value:n,label:i,attributes:s,default:t}}=e;return{value:n,label:i,attributes:s,default:t}}))}(i);return function(e){const n=(0,d.X)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[n,i])}function m(e){let{value:n,tabValues:i}=e;return i.some((e=>e.value===n))}function p(e){let{queryString:n=!1,groupId:i}=e;const t=(0,r.W6)(),a=function(e){let{queryString:n=!1,groupId:i}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!i)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return i??null}({queryString:n,groupId:i});return[(0,o.aZ)(a),(0,s.useCallback)((e=>{if(!a)return;const n=new URLSearchParams(t.location.search);n.set(a,e),t.replace({...t.location,search:n.toString()})}),[a,t])]}function g(e){const{defaultValue:n,queryString:i=!1,groupId:t}=e,a=u(e),[r,o]=(0,s.useState)((()=>function(e){let{defaultValue:n,tabValues:i}=e;if(0===i.length)throw new Error("Docusaurus error: the component requires at least one children component");if(n){if(!m({value:n,tabValues:i}))throw new Error(`Docusaurus error: The has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${i.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const s=i.find((e=>e.default))??i[0];if(!s)throw new Error("Unexpected error: 0 tabValues");return s.value}({defaultValue:n,tabValues:a}))),[d,h]=p({queryString:i,groupId:t}),[g,x]=function(e){let{groupId:n}=e;const i=function(e){return e?`docusaurus.tab.${e}`:null}(n),[t,a]=(0,c.Dv)(i);return[t,(0,s.useCallback)((e=>{i&&a.set(e)}),[i,a])]}({groupId:t}),j=(()=>{const e=d??g;return m({value:e,tabValues:a})?e:null})();(0,l.A)((()=>{j&&o(j)}),[j]);return{selectedValue:r,selectValue:(0,s.useCallback)((e=>{if(!m({value:e,tabValues:a}))throw new Error(`Can't select invalid tab value=${e}`);o(e),h(e),x(e)}),[h,x,a]),tabValues:a}}var x=i(2303);const j={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var b=i(4848);function f(e){let{className:n,block:i,selectedValue:s,selectValue:r,tabValues:l}=e;const o=[],{blockElementScrollPositionUntilNextRender:d}=(0,a.a_)(),c=e=>{const n=e.currentTarget,i=o.indexOf(n),t=l[i].value;t!==s&&(d(n),r(t))},h=e=>{let n=null;switch(e.key){case"Enter":c(e);break;case"ArrowRight":{const i=o.indexOf(e.currentTarget)+1;n=o[i]??o[0];break}case"ArrowLeft":{const i=o.indexOf(e.currentTarget)-1;n=o[i]??o[o.length-1];break}}n?.focus()};return(0,b.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,t.A)("tabs",{"tabs--block":i},n),children:l.map((e=>{let{value:n,label:i,attributes:a}=e;return(0,b.jsx)("li",{role:"tab",tabIndex:s===n?0:-1,"aria-selected":s===n,ref:e=>o.push(e),onKeyDown:h,onClick:c,...a,className:(0,t.A)("tabs__item",j.tabItem,a?.className,{"tabs__item--active":s===n}),children:i??n},n)}))})}function _(e){let{lazy:n,children:i,selectedValue:t}=e;const a=(Array.isArray(i)?i:[i]).filter(Boolean);if(n){const e=a.find((e=>e.props.value===t));return e?(0,s.cloneElement)(e,{className:"margin-top--md"}):null}return(0,b.jsx)("div",{className:"margin-top--md",children:a.map(((e,n)=>(0,s.cloneElement)(e,{key:n,hidden:e.props.value!==t})))})}function T(e){const n=g(e);return(0,b.jsxs)("div",{className:(0,t.A)("tabs-container",j.tabList),children:[(0,b.jsx)(f,{...n,...e}),(0,b.jsx)(_,{...n,...e})]})}function v(e){const n=(0,x.A)();return(0,b.jsx)(T,{...e,children:h(e.children)},String(n))}},7324:(e,n,i)=>{i.d(n,{$E:()=>x,A3:()=>b,CW:()=>j,Dx:()=>c,F4:()=>u,Fi:()=>d,J_:()=>v,LQ:()=>f,Lf:()=>y,OO:()=>t,Q7:()=>_,b:()=>l,cy:()=>o,gg:()=>p,kl:()=>m,os:()=>h,pW:()=>a,ux:()=>g,vf:()=>s,xj:()=>r,xt:()=>T});const s="shell",t="database",a="application",r="bash",l="pwsh",o="zsh",d="maria",c="mysql",h="postgres",u="sqlite",m="application",p="bash",g="pwsh",x="zsh",j="MariaDB",b="MySQL",f="PostgreSQL",_="SQLite",T="tinyorm.org",v="$HOME/Code/c/",y="$env:USERPROFILE\\Code\\c\\"},6362:(e,n,i)=>{i.d(n,{A:()=>a});var s=i(6540),t=i(1838);function a(){const e=(0,s.useContext)(t.A);if(null!=e)return e;throw new Error("useRootFolderContext is used outside of Layout component.")}},6694:(e,n,i)=>{i.d(n,{OZ:()=>o,Sn:()=>r,T3:()=>c,bw:()=>d,nC:()=>h,np:()=>l});var s=i(6362),t=i(2303),a=i(7324);const r=function(e,n){return void 0===n&&(n=!0),u((0,s.A)().rootFolder[e]??d(e),e,n)},l=()=>(0,s.A)().rootFolder[a.pW]??d(a.pW),o=function(e,n){if(void 0===n&&(n=!0),null==e)throw new Error("The groupId in the applicationFolderPath() can not be empty.");const i=n||e!==a.b?"/":"\\";return u(r(e)+i+l(),e,n)};function d(e){if(null==e)throw new Error("The groupId in the folderDefaultValue() can not be empty.");if(!(0,t.A)())return"";switch(e){case a.b:return a.Lf;case a.xj:return a.J_;case a.pW:return a.xt;default:throw new Error(`No default value for '${e}' groupId in the folderDefaultValue().`)}}function c(e){return e===a.pW}function h(e,n){if(null==n||""===n)return n;const i="$ENV{$1}$2";switch(e){case a.b:return p(n).replace(/\$env:(.+?)(\/.*)/,i);case a.xj:return n.replace(/\$(.+?)(\/.*)/,i);default:throw new Error(`Unsupported shell type '${e}' in the convertToCmakeEnvVariable().`)}}function u(e,n,i){if(void 0===i&&(i=!0),null==e||""===e)return e;if(n!==a.b)return m(e);const s=m(e);return i?p(s):function(e){return null==e||""===e?e:e.replaceAll(/\/+/g,"\\")}(s)}function m(e){return null==e||""===e?e:e.replace(/[/\\]+$/,"")}function p(e){return null==e||""===e?e:e.replaceAll(/\\+(?! )/g,"/")}},6106:(e,n,i)=>{i.d(n,{A:()=>s});const s=i.p+"assets/images/qmake-build_settings-e10927d1c4ed852620f9eb7564198940.png"},2394:(e,n,i)=>{i.d(n,{A:()=>s});const s=i.p+"assets/images/qmake-configure_project-4721257090370204b0272d166512adef.png"},4679:(e,n,i)=>{i.d(n,{A:()=>s});const s=i.p+"assets/images/tom_file_properties-0df513c47ceadd5c09165e41c6b53086.png"},53:(e,n,i)=>{i.d(n,{A:()=>s});const s=i.p+"assets/images/tom_migrate_status-63c129a10bfe6bffe8d2d5ea280860e5.png"}}]); \ No newline at end of file +"use strict";(self.webpackChunktinyorm_org=self.webpackChunktinyorm_org||[]).push([[129],{5270:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>p,contentTitle:()=>u,default:()=>j,frontMatter:()=>h,metadata:()=>m,toc:()=>g});var s=i(4848),t=i(8453),a=i(8774),r=i(2364),l=i(9365),o=i(1470),d=i(7324),c=i(6694);const h={sidebar_position:3,sidebar_label:"Migrations",description:"How to compile the TinyORM migrations (tom) C++ console application on Windows and Linux.",keywords:["c++ orm","building","migrations","tinyorm"]},u="Building: Migrations",m={id:"building/migrations",title:"Building: Migrations",description:"How to compile the TinyORM migrations (tom) C++ console application on Windows and Linux.",source:"@site/docs/building/migrations.mdx",sourceDirName:"building",slug:"/building/migrations",permalink:"/building/migrations",draft:!1,unlisted:!1,tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3,sidebar_label:"Migrations",description:"How to compile the TinyORM migrations (tom) C++ console application on Windows and Linux.",keywords:["c++ orm","building","migrations","tinyorm"]},sidebar:"tinyormSidebar",previous:{title:"Hello world",permalink:"/building/hello-world"},next:{title:"\ud83d\udcc4 Features Summary",permalink:"/features-summary"}},p={},g=[{value:"Introduction",id:"introduction",level:2},{value:"Install dependencies",id:"install-dependencies",level:2},{value:"Using vcpkg.json (manifest mode)",id:"using-vcpkg-json-manifest-mode",level:4},{value:"Using vcpkg install (manually)",id:"using-vcpkg-install-manually",level:4},{value:"Source code",id:"source-code",level:2},{value:"Main file",id:"main-file",level:3},{value:"Migrations",id:"migrations",level:3},{value:"Seeders",id:"seeders",level:3},{value:"Migrations with CMake",id:"migrations-with-cmake",level:2},{value:"CMake project",id:"cmake-project",level:3},{value:"Build migrations",id:"build-migrations-cmake",level:3},{value:"Execute migrations",id:"execute-migrations-cmake",level:3},{value:"Migrations with qmake",id:"migrations-with-qmake",level:2},{value:"qmake project",id:"qmake-project",level:3},{value:"Auto-configure using .qmake.conf and .env",id:"auto-configure-using-qmakeconf-and-env",level:4},{value:"Migrations source files",id:"migrations-source-files",level:4},{value:"Seeders source files",id:"seeders-source-files",level:4},{value:"Build migrations",id:"build-migrations-qmake",level:3},{value:"Execute migrations",id:"execute-migrations-qmake",level:3},{value:"Finish",id:"finish",level:2}];function x(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"building-migrations",children:"Building: Migrations"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#introduction",children:"Introduction"})}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#install-dependencies",children:"Install dependencies"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#using-vcpkg-json-manifest-mode",children:"Using vcpkg.json"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#using-vcpkg-install-manually",children:"Using vcpkg install"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#source-code",children:"Source code"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#main-file",children:"Main file"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#migrations",children:"Migrations"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#seeders",children:"Seeders"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#migrations-with-cmake",children:"Migrations with CMake"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#cmake-project",children:"CMake project"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#build-migrations-cmake",children:"Build migrations"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#execute-migrations-cmake",children:"Execute migrations"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#migrations-with-qmake",children:"Migrations with qmake"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#qmake-project",children:"qmake project"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#build-migrations-qmake",children:"Build migrations"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#execute-migrations-qmake",children:"Execute migrations"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#finish",children:"Finish"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsxs)(n.p,{children:["We will try to create a working migrations console application called as ",(0,s.jsx)("abbr",{title:"TinyORM migrations",children:(0,s.jsx)(n.code,{children:"tom"})})," in the terminal with the ",(0,s.jsx)(n.code,{children:"CMake"})," and in the ",(0,s.jsx)(n.code,{children:"QtCreator IDE"})," with the ",(0,s.jsx)(n.code,{children:"qmake"})," build systems."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"tom"})," console application also expects the following ",(0,s.jsx)(n.a,{href:"/building/tinyorm#folders-structure",children:"folders structure"}),", let's create them."]}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(r.A,{className:"language-powershell",children:`cd ${(0,c.OZ)(d.b)}\nmkdir tom/tom\ncd tom`})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(r.A,{className:"language-bash",children:`cd ${(0,c.OZ)(d.xj)}\nmkdir -p tom/tom\ncd tom`})})]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"TinyORM"})," source tree contains the ",(0,s.jsx)(n.code,{children:"tom"})," example application, you can inspire or look at the ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/tree/main/examples/tom",children:"source code"}),". Also, ",(0,s.jsx)(n.code,{children:"TinyORM"})," unit tests use a ",(0,s.jsx)(n.code,{children:"tom"})," migrations internally to create the database structure, internally called as the ",(0,s.jsxs)(n.a,{href:"https://github.com/silverqx/TinyORM/tree/main/tests/testdata_tom",children:[(0,s.jsx)(n.code,{children:"tom"})," migrations for unit tests"]}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["All these three console applications the ",(0,s.jsx)(n.code,{children:"tom"})," example, ",(0,s.jsx)(n.code,{children:"tom"})," migrations for unit tests, and the application described in this tutorial have practically identical source code (the main.cpp file)."]}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"tom"})," is able to generate ",(0,s.jsx)("a",{href:"https://en.wikipedia.org/wiki/Data_definition_language",title:"Data Definition Language",children:"DDL"})," queries for all the ",(0,s.jsx)(n.a,{href:"/database/getting-started#introduction",children:"supported databases"})," databases."]})}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["You can see the ",(0,s.jsx)(n.a,{href:"/features-summary#tom-console-application",children:"Tom showcase image"})," of how the resulting ",(0,s.jsx)(n.code,{children:"tom"})," console application will look like."]})}),"\n",(0,s.jsx)(n.h2,{id:"install-dependencies",children:"Install dependencies"}),"\n",(0,s.jsxs)(n.p,{children:["First, install the ",(0,s.jsx)(n.code,{children:"vcpkg"})," package manager as is described ",(0,s.jsx)(n.a,{href:"/building/tinyorm#vcpkg",children:"here"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"range-v3"})," and ",(0,s.jsx)(n.code,{children:"tabulate"})," libraries are required dependencies because ",(0,s.jsx)(n.code,{children:"TinyORM"})," uses them in header files, you have to install them before you can use ",(0,s.jsx)(n.code,{children:"TinyORM"}),". The ",(0,s.jsx)(n.code,{children:"tabulate"})," library is only needed in the ",(0,s.jsx)(n.code,{children:"tom"})," migrations it's used by the ",(0,s.jsx)(n.code,{children:"migrate:status"})," command."]}),"\n",(0,s.jsxs)(n.p,{children:["There are two ways how to install the ",(0,s.jsx)(n.code,{children:"range-v3"})," and ",(0,s.jsx)(n.code,{children:"tabulate"})," libraries using ",(0,s.jsx)(n.code,{children:"vcpkg"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Also, don't forget to build the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library with the ",(0,s.jsx)(n.code,{children:"tom"})," source code enabled (it's enabled by default) as is described ",(0,s.jsx)(n.a,{href:"/building/tinyorm",children:"here"}),"."]}),"\n",(0,s.jsxs)(n.h4,{id:"using-vcpkg-json-manifest-mode",children:["Using vcpkg.json ",(0,s.jsx)("small",{children:"(manifest mode)"})]}),"\n",(0,s.jsxs)(n.p,{children:["Create a ",(0,s.jsx)(n.code,{children:"vcpkg.json"})," file with the following content. ",(0,s.jsx)(n.code,{children:"CMake"})," example below uses this method."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd tom\nvim vcpkg.json\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",metastring:"title='vcpkg.json'",children:'{\n "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json",\n "name": "tom",\n "version-semver": "0.1.0",\n "maintainers": "Silver Zachara ",\n "description": "Tom console application for TinyORM C++ library",\n "homepage": "https://github.com/silverqx/TinyORM",\n "documentation": "https://www.tinyorm.org/building/migrations",\n "supports": "!(uwp | arm | android | emscripten | osx | ios | xbox | freebsd | openbsd | wasm32)",\n "dependencies": [\n "range-v3",\n "tabulate"\n ]\n}\n'})}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Only ",(0,s.jsx)(n.code,{children:"CMake"})," via the ",(0,s.jsx)(n.code,{children:"toolchain file"})," supports this method."]})}),"\n",(0,s.jsxs)(n.h4,{id:"using-vcpkg-install-manually",children:["Using vcpkg install ",(0,s.jsx)("small",{children:"(manually)"})]}),"\n",(0,s.jsxs)(n.p,{children:["This method can be used with both ",(0,s.jsx)(n.code,{children:"CMake"})," and ",(0,s.jsx)(n.code,{children:"qmake"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd ../../vcpkg\n\nvcpkg search range-v3\nvcpkg search tabulate\nvcpkg install range-v3 tabulate\nvcpkg list\n"})}),"\n",(0,s.jsx)(n.h2,{id:"source-code",children:"Source code"}),"\n",(0,s.jsxs)(n.p,{children:["Let's start in the ",(0,s.jsx)(n.code,{children:"tom"})," project folder."]}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(r.A,{className:"language-powershell",children:`cd ${(0,c.OZ)(d.b)}/tom/tom`})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(r.A,{className:"language-bash",children:`cd ${(0,c.OZ)(d.xj)}/tom/tom`})})]}),"\n",(0,s.jsx)(n.h3,{id:"main-file",children:"Main file"}),"\n",(0,s.jsxs)(n.p,{children:["Create ",(0,s.jsx)(n.code,{children:"main.cpp"})," source file."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"vim main.cpp\n"})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["To paste a source code correctly in ",(0,s.jsx)(n.code,{children:"vim"}),", press ",(0,s.jsx)("kbd",{children:"Shift"})," + ",(0,s.jsx)("kbd",{children:"p"}),"."]})}),"\n",(0,s.jsx)(n.p,{children:"And paste the following code."}),"\n",(0,s.jsx)(a.A,{id:"string-constants-example"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-cpp",metastring:"title='main.cpp'",children:'#include \n\n#include \n\n#include "migrations/2014_10_12_000000_create_posts_table.hpp"\n\n#include "seeders/databaseseeder.hpp"\n\nusing Orm::DatabaseManager;\nusing Orm::DB;\n\nusing TomApplication = Tom::Application;\n\nusing namespace Migrations; // NOLINT(google-build-using-namespace)\nusing namespace Seeders; // NOLINT(google-build-using-namespace)\n\n/*! Create the database manager instance and add a database connection. */\nstd::shared_ptr setupDatabaseManager();\n\n/*! C++ main function. */\nint main(int argc, char *argv[])\n{\n try {\n // Ownership of the shared_ptr()\n auto db = setupDatabaseManager();\n\n return TomApplication(argc, argv, std::move(db), "TOM_EXAMPLE_ENV")\n .migrations()\n .seeders()\n // Fire it up \ud83d\udd25\ud83d\ude80\u2728\n .run();\n\n } catch (const std::exception &e) {\n\n TomApplication::logException(e);\n }\n\n return EXIT_FAILURE;\n}\n\nstd::shared_ptr setupDatabaseManager()\n{\n using namespace Orm::Constants; // NOLINT(google-build-using-namespace)\n\n // Ownership of the shared_ptr()\n return DB::create({\n {driver_, QMYSQL},\n {host_, qEnvironmentVariable("DB_MYSQL_HOST", H127001)},\n {port_, qEnvironmentVariable("DB_MYSQL_PORT", P3306)},\n {database_, qEnvironmentVariable("DB_MYSQL_DATABASE", EMPTY)},\n {username_, qEnvironmentVariable("DB_MYSQL_USERNAME", EMPTY)},\n {password_, qEnvironmentVariable("DB_MYSQL_PASSWORD", EMPTY)},\n {charset_, qEnvironmentVariable("DB_MYSQL_CHARSET", UTF8MB4)},\n {collation_, qEnvironmentVariable("DB_MYSQL_COLLATION", UTF8MB40900aici)},\n {timezone_, TZ00},\n /* Specifies what time zone all QDateTime-s will have, the overridden default is\n the Qt::UTC, set to the Qt::LocalTime or QtTimeZoneType::DontConvert to use\n the system local time. */\n {qt_timezone, QVariant::fromValue(Qt::UTC)},\n {strict_, true},\n },\n QStringLiteral("tinyorm_tom_mysql")); // shell:connection\n}\n'})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["If you have defined more database connections then you can tag the lines with the database connection names with the ",(0,s.jsx)(n.code,{children:"// shell:connection"})," comment and this connection names will be provided to the bash, zsh, pwsh completions for the ",(0,s.jsx)(n.code,{children:"--database="})," option \ud83d\ude0e, ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/examples/tom/main.cpp#L74",children:"example"}),"."]})}),"\n",(0,s.jsx)(n.h3,{id:"migrations",children:"Migrations"}),"\n",(0,s.jsxs)(n.p,{children:["If you have already built the ",(0,s.jsx)(n.code,{children:"tom"})," application then you can generate a migrations using the ",(0,s.jsx)(n.a,{href:"/database/migrations#generating-migrations",children:(0,s.jsx)(n.code,{children:"make:migration"})})," command \ud83d\ude0e."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"tom make:migration create_posts_table\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Below is the expected folders structure for the migrations. The ",(0,s.jsx)(n.a,{href:"#migrations-source-files",children:(0,s.jsx)(n.code,{children:"migrations.pri"})})," file is used only by the ",(0,s.jsx)(n.code,{children:"qmake"})," build system and is not needed with ",(0,s.jsx)(n.code,{children:"CMake"})," builds."]}),"\n",(0,s.jsx)(a.A,{id:"folders-structure"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-text",children:"tom/\n\u2514\u2500\u2500 database/\n \u251c\u2500\u2500 migrations/\n \u251c\u2500\u2500 seeders/\n \u251c\u2500\u2500 migrations.pri\n \u2514\u2500\u2500 seeders.pri\n"})}),"\n",(0,s.jsx)(n.p,{children:"Let's create the first migration manually."}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(r.A,{className:"language-powershell",children:"mkdir database/migrations\n\nvim database/migrations/2014_10_12_000000_create_posts_table.hpp"})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(r.A,{className:"language-bash",children:"mkdir -p database/migrations\n\nvim database/migrations/2014_10_12_000000_create_posts_table.hpp"})})]}),"\n",(0,s.jsx)(n.p,{children:"And paste the following code."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-cpp",metastring:"title='database/migrations/2014_10_12_000000_create_posts_table.hpp'",children:'#pragma once\n\n#include \n\nnamespace Migrations\n{\n\n struct CreatePostsTable : Migration\n {\n /*! Filename of the migration file. */\n T_MIGRATION\n\n /*! Run the migrations. */\n void up() const override\n {\n Schema::create("posts", [](Blueprint &table)\n {\n table.id();\n\n table.string(NAME);\n table.timestamps();\n });\n }\n\n /*! Reverse the migrations. */\n void down() const override\n {\n Schema::dropIfExists("posts");\n }\n };\n\n} // namespace Migrations\n'})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"TinyORM"})," source tree contains the ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/tests/database/migrations/2014_10_12_000000_create_posts_table.hpp#L5",children:(0,s.jsx)(n.code,{children:"CreatePostsTable"})})," example migration that also acts as the full-fledged example migration. It has defined and also nicely commented all possible features that migration classes can use or define."]})}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["If you want, you can also build the ",(0,s.jsx)(n.code,{children:"tom"})," application without the migrations, simply comment out the ",(0,s.jsx)(n.code,{children:"migrations"})," method and the corresponding ",(0,s.jsx)(n.code,{children:'#include "migrations/xyz.hpp"'})," files."]})}),"\n",(0,s.jsx)(n.h3,{id:"seeders",children:"Seeders"}),"\n",(0,s.jsxs)(n.p,{children:["If you have already built the ",(0,s.jsx)(n.code,{children:"tom"})," application then you can generate a seeder using the ",(0,s.jsx)(n.a,{href:"/database/seeding#writing-seeders",children:(0,s.jsx)(n.code,{children:"make:seeder"})})," command \ud83d\ude0e."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"tom make:seeder PostSeeder\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The expected folders structure is described a few paragraphs ",(0,s.jsx)(n.a,{href:"#folders-structure",children:"above"}),". The ",(0,s.jsx)(n.a,{href:"#seeders-source-files",children:(0,s.jsx)(n.code,{children:"seeders.pri"})})," file is used only by the ",(0,s.jsx)(n.code,{children:"qmake"})," build system and is not needed with ",(0,s.jsx)(n.code,{children:"CMake"})," builds."]}),"\n",(0,s.jsx)(n.p,{children:"Let's create the root seeder class manually."}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(r.A,{className:"language-powershell",children:"mkdir database/seeders\n\nvim database/seeders/databaseseeder.hpp"})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(r.A,{className:"language-bash",children:"mkdir -p database/seeders\n\nvim database/seeders/databaseseeder.hpp"})})]}),"\n",(0,s.jsx)(n.p,{children:"And paste the following code."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-cpp",metastring:"title='database/seeders/databaseseeder.hpp'",children:'#pragma once\n\n#include \n\nnamespace Seeders\n{\n\n /*! Main database seeder. */\n struct DatabaseSeeder : Seeder\n {\n /*! Run the database seeders. */\n void run() override\n {\n DB::table("posts")->insert({\n {{"name", "1. post"}},\n {{"name", "2. post"}},\n });\n }\n };\n\n} // namespace Seeders\n'})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"TinyORM"})," source tree contains the ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/tests/database/seeders/databaseseeder.hpp#L8",children:(0,s.jsx)(n.code,{children:"DatabaseSeeder"})})," root seeder example class that also acts as the full-fledged example seeder. It has defined and also nicely commented all possible features that seeder classes can use or define."]})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["You can create more seeder classes like this and use the ",(0,s.jsx)(n.code,{children:"call<>()"})," method to invoke them as is described in the ",(0,s.jsx)(n.a,{href:"/database/seeding#calling-additional-seeders",children:"Calling Additional Seeders"})," section."]})}),"\n",(0,s.jsx)(n.h2,{id:"migrations-with-cmake",children:"Migrations with CMake"}),"\n",(0,s.jsxs)(n.p,{children:["Create a folder for the ",(0,s.jsx)(n.code,{children:"CMake"})," build."]}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(r.A,{className:"language-powershell",children:"cd ..\nmkdir tom-builds-cmake/build-debug\n\ncd tom"})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(r.A,{className:"language-bash",children:"cd ..\nmkdir -p tom-builds-cmake/build-debug\n\ncd tom"})})]}),"\n",(0,s.jsx)(n.h3,{id:"cmake-project",children:"CMake project"}),"\n",(0,s.jsxs)(n.p,{children:["Create ",(0,s.jsx)(n.code,{children:"CMakeLists.txt"})," file with the following content. I leave the comments in the ",(0,s.jsx)(n.code,{children:"CMakeLists.txt"})," file because it's not as simple as the ",(0,s.jsx)(n.code,{children:"Hello world"})," example; to make it clear what's going on."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-cmake",metastring:"title='CMakeLists.txt'",children:'cmake_minimum_required(VERSION VERSION 3.22...3.29 FATAL_ERROR)\n\n# Specify the C++ standard\nset(CMAKE_CXX_STANDARD 20)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\nset(CMAKE_CXX_EXTENSIONS OFF)\n\n# Initialize variables\n# ---\n\nset(Tom_ns tom)\nset(Tom_target tom)\n\nfile(REAL_PATH "../../TinyORM" TinyMainDir)\n\nset(TinyOrmSourceDir "${TinyMainDir}/TinyORM")\nset(TinyOrmBuildDir "${TinyMainDir}/TinyORM-builds-cmake/build-debug")\n\n# TinyORM CMake modules (needed to set the executable version and RC file on Windows)\nlist(APPEND CMAKE_MODULE_PATH "${TinyOrmSourceDir}/cmake/CommonModules")\n\n# build tree\nlist(APPEND CMAKE_PREFIX_PATH "${TinyOrmBuildDir}")\n\n# Initialize Project Version\n# ---\n\ninclude(TinyHelpers)\ntiny_read_version(TINY_VERSION\n TINY_VERSION_MAJOR TINY_VERSION_MINOR TINY_VERSION_PATCH TINY_VERSION_TWEAK\n VERSION_HEADER "${TinyOrmSourceDir}/tom/include/tom/version.hpp"\n PREFIX TINYTOM\n HEADER_FOR "${Tom_ns}"\n)\n\n# Basic project\n# ---\n\nproject(${Tom_ns}\n DESCRIPTION "Tom console application for TinyORM C++ library"\n HOMEPAGE_URL "https://www.tinyorm.org"\n LANGUAGES CXX\n VERSION ${TINY_VERSION}\n)\n\n# Tom command-line application\n# ---\n\nadd_executable(${Tom_target}\n main.cpp\n)\nadd_executable(${Tom_ns}::${Tom_target} ALIAS ${Tom_target})\n\n# Tom command-line application specific configuration\n# ---\n\nset_target_properties(${Tom_target}\n PROPERTIES\n C_VISIBILITY_PRESET "hidden"\n CXX_VISIBILITY_PRESET "hidden"\n VISIBILITY_INLINES_HIDDEN YES\n VERSION ${PROJECT_VERSION}\n)\n\ntarget_include_directories(${Tom_target}\n PRIVATE "$"\n)\n\n# Tom command-line application defines\n# ---\n\ntarget_compile_definitions(${Tom_target}\n PRIVATE\n PROJECT_TOM\n)\n\n# Windows resource and manifest files\n# ---\n\n# Find icons, tom/version.hpp, and Windows manifest file for MinGW\nif(CMAKE_SYSTEM_NAME STREQUAL "Windows")\n tiny_set_rc_flags("-I \\"${TinyOrmSourceDir}/tom/resources\\"")\nendif()\n\ninclude(TinyResourceAndManifest)\ntiny_resource_and_manifest(${Tom_target}\n OUTPUT_DIR "${TINY_BUILD_GENDIR}/tmp/"\n RESOURCES_DIR "${TinyOrmSourceDir}/tom/resources"\n)\n\n# Resolve and link dependencies\n# ---\n\nfind_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)\nfind_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)\nfind_package(TinyOrm 0.37.3 CONFIG REQUIRED)\n\n# Unconditional dependencies\ntarget_link_libraries(${Tom_target}\n PRIVATE\n Qt${QT_VERSION_MAJOR}::Core\n TinyOrm::TinyOrm\n)\n'})}),"\n",(0,s.jsx)(n.h3,{id:"build-migrations-cmake",children:"Build migrations"}),"\n",(0,s.jsxs)(n.p,{children:["Now you are ready to configure ",(0,s.jsx)(n.code,{children:"tom"})," ",(0,s.jsx)(n.code,{children:"CMake"})," application. Don't forget to prepare the build environment with the ",(0,s.jsx)(n.a,{href:"/building/tinyorm#windows-prerequisites",children:(0,s.jsx)(n.code,{children:"qtenv6.ps1"})})," command if you are building with the ",(0,s.jsx)(n.code,{children:"msvc"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd ../tom-builds-cmake/build-debug\n"})}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(r.A,{className:"language-powershell",children:`cmake.exe \`\n-S "${(0,c.OZ)(d.b)}/tom/tom" \`\n-B "${(0,c.OZ)(d.b)}/tom/tom-builds-cmake/build-debug" \`\n-G 'Ninja' \`\n-D CMAKE_BUILD_TYPE:STRING='Debug' \`\n-D CMAKE_TOOLCHAIN_FILE:FILEPATH="${(0,c.Sn)(d.b)}/vcpkg/scripts/buildsystems/vcpkg.cmake" \`\n-D CMAKE_CXX_SCAN_FOR_MODULES:BOOL=OFF \`\n-D CMAKE_INSTALL_PREFIX:PATH="${(0,c.Sn)(d.b)}/tmp/tom"`})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(r.A,{className:"language-bash",children:`cmake \\\n-S "${(0,c.OZ)(d.xj)}/tom/tom" \\\n-B "${(0,c.OZ)(d.xj)}/tom/tom-builds-cmake/build-debug" \\\n-G 'Ninja' \\\n-D CMAKE_BUILD_TYPE:STRING='Debug' \\\n-D CMAKE_TOOLCHAIN_FILE:FILEPATH="${(0,c.Sn)(d.xj)}/vcpkg/scripts/buildsystems/vcpkg.cmake" \\\n-D CMAKE_CXX_SCAN_FOR_MODULES:BOOL=OFF \\\n-D CMAKE_INSTALL_PREFIX:PATH="${(0,c.Sn)(d.xj)}/tmp/tom"`})})]}),"\n",(0,s.jsx)(n.p,{children:"And build."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cmake --build . --target all\n"})}),"\n",(0,s.jsx)(n.h3,{id:"execute-migrations-cmake",children:"Execute migrations"}),"\n",(0,s.jsxs)(n.p,{children:["Do not forget to add ",(0,s.jsx)(n.code,{children:"TinyOrm0d.dll"})," on the path on Windows and on the ",(0,s.jsx)(n.code,{children:"LD_LIBRARY_PATH"})," on Linux, so ",(0,s.jsx)(n.code,{children:"tom"})," application can find it during execution, as is described ",(0,s.jsx)(n.a,{href:"/building/tinyorm#tinyorm-on-path-cmake",children:"here"}),"."]}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,name:"tinyorm-on-path",children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(r.A,{className:"language-powershell",children:`$env:Path = "${(0,c.OZ)(d.b,!1)}\\TinyORM\\TinyORM-builds-cmake\\build-debug;" + $env:Path`})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(r.A,{className:"language-bash",children:`export LD_LIBRARY_PATH=${(0,c.OZ)(d.xj)}/TinyORM/TinyORM-builds-cmake/build-debug\${PATH:+:}$PATH`})})]}),"\n",(0,s.jsxs)(n.p,{children:["Execute ",(0,s.jsx)(n.code,{children:"tom"})," application."]}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-powershell",children:".\\tom.exe migrate:status\n"})})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"./tom migrate:status\n"})})})]}),"\n",(0,s.jsx)(n.p,{children:"The output will look something like this."}),"\n",(0,s.jsx)("img",{src:i(53).A,alt:"Tom migrations - migrate:status command output",width:"660"}),"\n",(0,s.jsxs)(n.p,{children:["See also the ",(0,s.jsx)(n.a,{href:"#finish",children:"final thoughts"})," on how to verify the ",(0,s.jsx)(n.code,{children:"tom"})," executable file properties."]}),"\n",(0,s.jsx)(n.p,{children:"Happy migrating \ud83c\udf89\ud83d\udc4c"}),"\n",(0,s.jsx)(n.h2,{id:"migrations-with-qmake",children:"Migrations with qmake"}),"\n",(0,s.jsxs)(n.p,{children:["Create a folder for the ",(0,s.jsx)(n.code,{children:"qmake"})," build."]}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(r.A,{className:"language-powershell",children:`cd ${(0,c.OZ)(d.b)}/tom\n\nmkdir tom-builds-qmake`})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(r.A,{className:"language-bash",children:`cd ${(0,c.OZ)(d.xj)}/tom\n\nmkdir tom-builds-qmake`})})]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"#source-code",children:(0,s.jsx)(n.code,{children:"source code"})})," is the same as for the ",(0,s.jsx)(n.code,{children:"Migrations with CMake"})," console application."]}),"\n",(0,s.jsx)(n.h3,{id:"qmake-project",children:"qmake project"}),"\n",(0,s.jsxs)(n.p,{children:["Create ",(0,s.jsx)(n.code,{children:"tom.pro"})," qmake file with the following content."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd tom\nvim tom.pro\n"})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["To paste a source code correctly in ",(0,s.jsx)(n.code,{children:"vim"}),", press ",(0,s.jsx)("kbd",{children:"Shift"})," + ",(0,s.jsx)("kbd",{children:"p"}),"."]})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",metastring:"title='tom.pro'",children:"QT -= gui\n\nTEMPLATE = app\nTARGET = tom\n\nCONFIG *= cmdline\n\nDEFINES *= PROJECT_TOM\n\nSOURCES += $$PWD/main.cpp\n\n# Database migrations\ninclude($$PWD/database/migrations.pri)\n# Database seeders\ninclude($$PWD/database/seeders.pri)\n\n# Auto-configure TinyORM library for the migrations purposes \ud83d\udd25\ninclude($$TINY_MAIN_DIR/TinyORM/qmake/tom.pri)\n"})}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsxs)(n.p,{children:["The exact ",(0,s.jsx)(n.a,{href:"/building/tinyorm#folders-structure",children:"folders structure"})," is crucial in this example because the paths to the ",(0,s.jsx)(n.code,{children:"TinyORM"})," source and build folders are relative."]})}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsx)(n.p,{children:"Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!"})}),"\n",(0,s.jsxs)(n.h4,{id:"auto-configure-using-qmakeconf-and-env",children:[(0,s.jsx)(n.code,{children:"Auto-configure"})," using ",(0,s.jsx)(n.code,{children:".qmake.conf"})," and ",(0,s.jsx)(n.code,{children:".env"})]}),"\n",(0,s.jsxs)(n.p,{children:["If you want to have properly configured ",(0,s.jsx)(n.code,{children:"DEFINES"})," (C preprocessor macros), have Qt headers marked as system headers, or eg. have properly set properties of an executable file such as version and description, then you need to specify a path to the ",(0,s.jsx)(n.code,{children:"TinyORM"})," qmake features (",(0,s.jsx)(n.code,{children:".prf"})," files) which handle this correctly; this path is provided by the ",(0,s.jsx)(n.code,{children:"QMAKEFEATURES"})," variable and can only be set in the ",(0,s.jsx)(n.code,{children:".qmake.conf"})," file."]}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["Read the ",(0,s.jsx)(n.a,{href:"/building/tinyorm#consume-tinyorm-library-qmake",children:"Consume TinyOrm library (qmake)"})," section, as everything that is described in that section applies here as well."]})}),"\n",(0,s.jsxs)(n.p,{children:["Create the ",(0,s.jsx)(n.code,{children:".qmake.conf"})," file in the ",(0,s.jsx)(n.code,{children:"tom"})," application root folder with the following content."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",metastring:"title='.qmake.conf'",children:"# Path to the PARENT folder of the TinyORM source folder\nTINY_MAIN_DIR = $$clean_path($$PWD/../../TinyORM/)\n# To find .env and .env.$$QMAKE_PLATFORM files\nTINY_DOTENV_ROOT = $$PWD\n# Path to the current build tree (used to guess the TinyORM build tree)\n#TINY_BUILD_TREE = $$shadowed($$PWD)\n\n# To find .prf files, needed by eg. CONFIG += tiny_system_headers inline/extern_constants\nQMAKEFEATURES *= $$quote($$TINY_MAIN_DIR/TinyORM/qmake/features)\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Then, create a ",(0,s.jsx)("code",{children:".env.(win32|unix|mingw)"})," file in the ",(0,s.jsx)(n.code,{children:"tom"})," application root folder with the following content."]}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:".env.win32",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",children:"# Names and values of these qmake variables are crucial, they are used in the tom.pro\n# Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!\n\n# Path to the TinyORM build folder\nTINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_1_MSVC2022_64bit-Debug/)\n\n# Path to the vcpkg - range-v3 and tabulate\n# Will use the TINY_VCPKG_ROOT or VCPKG_ROOT environment variable if is empty\nTINY_VCPKG_ROOT = $$clean_path($$PWD/../../../vcpkg/)\nTINY_VCPKG_TRIPLET = x64-windows\n\n# Enable ccache wrapper\n#CONFIG *= tiny_ccache_win32\n"})})}),(0,s.jsx)(l.A,{value:d.xj,label:".env.unix",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",children:"# Names and values of these qmake variables are crucial, they are used in the tom.pro\n# Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!\n\n# Path to the TinyORM build folder\nTINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_1_clang16_64bit_ccache-Debug/)\n\n# Path to the vcpkg - range-v3 and tabulate\n# Will use the TINY_VCPKG_ROOT or VCPKG_ROOT environment variable if is empty\nTINY_VCPKG_ROOT = $$clean_path($$PWD/../../../vcpkg/)\nTINY_VCPKG_TRIPLET = x64-linux\n\n# Use faster linker\nclang: CONFIG *= use_lld_linker\nelse: CONFIG *= use_gold_linker\n\n# Or use the mold linker\n#QMAKE_LFLAGS *= -fuse-ld=mold\n"})})}),(0,s.jsx)(l.A,{value:"mingw",label:".env.mingw",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",children:"# Names and values of these qmake variables are crucial, they are used in the tom.pro\n# Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!\n\n# Path to the TinyORM build folder\nTINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_1_MSYS2_UCRT64_clang_64bit-Debug/)\n\n# Path to the vcpkg - range-v3 and tabulate\n# Will use the TINY_VCPKG_ROOT or VCPKG_ROOT environment variable if is empty\nTINY_VCPKG_ROOT = $$clean_path($$PWD/../../../vcpkg/)\nTINY_VCPKG_TRIPLET = x64-mingw-dynamic\n\n# Enable ccache wrapper\n#CONFIG *= tiny_ccache_win32\n\n# Use faster linker (for both GCC and Clang)\n# CONFIG *= use_lld_linker does not work on MinGW\nQMAKE_LFLAGS *= -fuse-ld=lld\n"})})})]}),"\n",(0,s.jsxs)(n.p,{children:["Don't forget to update the ",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})," and ",(0,s.jsx)(n.code,{children:"TINY_VCPKG_ROOT"})," folder paths to your needs if you are not using the recommended ",(0,s.jsx)(n.a,{href:"/building/tinyorm#folders-structure",children:(0,s.jsx)(n.code,{children:"Folders structure"})}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["You can use the ",(0,s.jsxs)(n.a,{href:"/building/tinyorm#partial-guessing-of-the-tinyorm_build_tree",children:["Partial guessing of the ",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})]})," if you don't like to specify it manually. Just comment out the ",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})," and uncomment the ",(0,s.jsx)(n.code,{children:"TINY_BUILD_TREE = $$shadowed($$PWD)"})," in the ",(0,s.jsx)(n.code,{children:".qmake.conf"})," file."]}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["You can entirely avoid the ",(0,s.jsx)(n.code,{children:".env"})," files, just move the ",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})," to the ",(0,s.jsx)(n.code,{children:".qmake.conf"})," or remove it by help of ",(0,s.jsxs)(n.a,{href:"/building/tinyorm#partial-guessing-of-the-tinyorm_build_tree",children:["Partial guessing of the ",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})]})," and set the ",(0,s.jsx)(n.code,{children:"VCPKG_ROOT"})," environment variable at system level as is described in ",(0,s.jsx)(n.a,{href:"/building/tinyorm#set-up-vcpkg-environment",children:(0,s.jsx)(n.code,{children:"Set up vcpkg environment"})}),"."]})}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["Configuring by the ",(0,s.jsx)(n.code,{children:".qmake.conf"})," and ",(0,s.jsx)(n.code,{children:".env"})," files has one big advantage, which is that you don't have to modify the project files."]})}),"\n",(0,s.jsx)(n.h4,{id:"migrations-source-files",children:"Migrations source files"}),"\n",(0,s.jsxs)(n.p,{children:["Create ",(0,s.jsx)(n.code,{children:"database/migrations.pri"})," file and paste the following code."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",metastring:"title='database/migrations.pri'",children:"INCLUDEPATH *= $$PWD\n\nHEADERS += \\\n $$PWD/migrations/2014_10_12_000000_create_posts_table.hpp \\\n"})}),"\n",(0,s.jsx)(n.h4,{id:"seeders-source-files",children:"Seeders source files"}),"\n",(0,s.jsxs)(n.p,{children:["Create ",(0,s.jsx)(n.code,{children:"database/seeders.pri"})," file and paste the following code."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",metastring:"title='database/seeders.pri'",children:"INCLUDEPATH *= $$PWD\n\nHEADERS += \\\n $$PWD/seeders/databaseseeder.hpp \\\n"})}),"\n",(0,s.jsx)(n.h3,{id:"build-migrations-qmake",children:"Build migrations"}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["I recommend creating a new ",(0,s.jsx)(n.code,{children:"Session"})," in the ",(0,s.jsx)(n.code,{children:"QtCreator IDE"})," as is described ",(0,s.jsx)(n.a,{href:"/building/tinyorm#open-qtcreator-ide",children:"here"}),"."]})}),"\n",(0,s.jsxs)(n.p,{children:["Now you can open the ",(0,s.jsx)(n.code,{children:"tom.pro"})," project in the ",(0,s.jsx)(n.code,{children:"QtCreator IDE"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["This will open the ",(0,s.jsx)(n.code,{children:"Configure Project"})," tab, select some kit and update build folder paths to meet our ",(0,s.jsx)(n.a,{href:"/building/tinyorm#folders-structure",children:"folders structure"})," or like you want."]}),"\n",(0,s.jsx)("img",{src:i(2394).A,alt:"tom - QtCreator - Configure Project",width:"760"}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["You can force the ",(0,s.jsx)(n.code,{children:"QtCreator"})," to generate a build folders structure as is described ",(0,s.jsx)(n.a,{href:"/building/tinyorm#qtcreator-default-build-directory",children:"here"}),"."]})}),"\n",(0,s.jsxs)(n.p,{children:["You are ready to configure build options, hit ",(0,s.jsx)("kbd",{children:"Ctrl"}),"+",(0,s.jsx)("kbd",{children:"5"})," to open ",(0,s.jsx)(n.code,{children:"Project Settings"})," tab and select ",(0,s.jsx)(n.code,{children:"Build"})," in the left sidebar to open the ",(0,s.jsx)(n.code,{children:"Build Settings"}),", it should look similar to the following picture."]}),"\n",(0,s.jsx)("img",{src:i(6106).A,className:"no-blurry",alt:"tom - QtCreator - Build Settings",width:"760"}),"\n",(0,s.jsxs)(n.p,{children:["Disable ",(0,s.jsx)(n.code,{children:"QML debugging and profiling"})," and ",(0,s.jsx)(n.code,{children:"Qt Quick Compiler"}),", they are not used."]}),"\n",(0,s.jsxs)(n.p,{children:["In the left sidebar open ",(0,s.jsx)(n.code,{children:"Dependencies"})," and check ",(0,s.jsx)(n.code,{children:"TinyORM"})," project and ",(0,s.jsx)(n.code,{children:"Synchronize configuration"}),", this setting ensures that the current project will be rebuilt correctly when the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library source code changes."]}),"\n",(0,s.jsxs)(n.p,{children:["Everything is ready to build, you can press ",(0,s.jsx)("kbd",{children:"Ctrl"}),"+",(0,s.jsx)("kbd",{children:"b"})," to build the project."]}),"\n",(0,s.jsx)(n.h3,{id:"execute-migrations-qmake",children:"Execute migrations"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"QtCreator"})," takes care of all the necessary configurations, sets up the build environment correctly, and also prepends dependency libraries on the system path on Windows and on the ",(0,s.jsx)(n.code,{children:"LD_LIBRARY_PATH"})," on Linux."]}),"\n",(0,s.jsxs)(n.p,{children:["The only thing you might want to change is to run the ",(0,s.jsx)(n.code,{children:"tom"})," application in the new terminal window. To do so, hit ",(0,s.jsx)("kbd",{children:"Ctrl"}),"+",(0,s.jsx)("kbd",{children:"5"})," to open the ",(0,s.jsx)(n.code,{children:"Project Settings"})," tab and select ",(0,s.jsx)(n.code,{children:"Run"})," in the left sidebar to open the ",(0,s.jsx)(n.code,{children:"Run Settings"}),", then in the ",(0,s.jsx)(n.code,{children:"Run"})," section select the ",(0,s.jsx)(n.code,{children:"Run in terminal"})," checkbox."]}),"\n",(0,s.jsxs)(n.p,{children:["You can also set the ",(0,s.jsx)(n.code,{children:"Command line arguments"})," in this ",(0,s.jsx)(n.code,{children:"Run"})," section, eg. the ",(0,s.jsx)(n.code,{children:"migrate:status"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["To execute the ",(0,s.jsx)(n.code,{children:"tom"})," application press ",(0,s.jsx)("kbd",{children:"Ctrl"})," + ",(0,s.jsx)("kbd",{children:"r"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["The output will look ",(0,s.jsx)(n.strong,{children:"very similar"})," to this if you add more migrations."]}),"\n",(0,s.jsx)("img",{src:i(53).A,alt:"Tom migrations - migrate:status command output",width:"660"}),"\n",(0,s.jsx)(n.p,{children:"Happy migrating \ud83c\udf89\ud83d\udc4c"}),"\n",(0,s.jsx)(n.h2,{id:"finish",children:"Finish"}),"\n",(0,s.jsxs)(n.p,{children:["As the last thing, you can check that all the file properties were correctly set by the ",(0,s.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/windows/win32/menurc/resource-compiler",children:(0,s.jsx)(n.code,{children:"rc"})})," compiler."]}),"\n",(0,s.jsxs)(n.p,{children:["Find the ",(0,s.jsx)(n.code,{children:"tom.exe"})," file and press ",(0,s.jsx)("kbd",{children:"Alt"})," + ",(0,s.jsx)("kbd",{children:"Enter"})," to open the file properties. To check the executable manifest you can use eg. the ",(0,s.jsx)(n.a,{href:"http://www.angusj.com/resourcehacker/",children:"Resource Hacker"}),"."]}),"\n",(0,s.jsx)("img",{src:i(4679).A,alt:"tom.exe file properties detail",width:"440"})]})}function j(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(x,{...e})}):x(e)}},9365:(e,n,i)=>{i.d(n,{A:()=>r});i(6540);var s=i(4164);const t={tabItem:"tabItem_Ymn6"};var a=i(4848);function r(e){let{children:n,hidden:i,className:r}=e;return(0,a.jsx)("div",{role:"tabpanel",className:(0,s.A)(t.tabItem,r),hidden:i,children:n})}},1470:(e,n,i)=>{i.d(n,{A:()=>v});var s=i(6540),t=i(4164),a=i(3104),r=i(6347),l=i(205),o=i(7485),d=i(1682),c=i(9466);function h(e){return s.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,s.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function u(e){const{values:n,children:i}=e;return(0,s.useMemo)((()=>{const e=n??function(e){return h(e).map((e=>{let{props:{value:n,label:i,attributes:s,default:t}}=e;return{value:n,label:i,attributes:s,default:t}}))}(i);return function(e){const n=(0,d.X)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[n,i])}function m(e){let{value:n,tabValues:i}=e;return i.some((e=>e.value===n))}function p(e){let{queryString:n=!1,groupId:i}=e;const t=(0,r.W6)(),a=function(e){let{queryString:n=!1,groupId:i}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!i)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return i??null}({queryString:n,groupId:i});return[(0,o.aZ)(a),(0,s.useCallback)((e=>{if(!a)return;const n=new URLSearchParams(t.location.search);n.set(a,e),t.replace({...t.location,search:n.toString()})}),[a,t])]}function g(e){const{defaultValue:n,queryString:i=!1,groupId:t}=e,a=u(e),[r,o]=(0,s.useState)((()=>function(e){let{defaultValue:n,tabValues:i}=e;if(0===i.length)throw new Error("Docusaurus error: the component requires at least one children component");if(n){if(!m({value:n,tabValues:i}))throw new Error(`Docusaurus error: The has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${i.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const s=i.find((e=>e.default))??i[0];if(!s)throw new Error("Unexpected error: 0 tabValues");return s.value}({defaultValue:n,tabValues:a}))),[d,h]=p({queryString:i,groupId:t}),[g,x]=function(e){let{groupId:n}=e;const i=function(e){return e?`docusaurus.tab.${e}`:null}(n),[t,a]=(0,c.Dv)(i);return[t,(0,s.useCallback)((e=>{i&&a.set(e)}),[i,a])]}({groupId:t}),j=(()=>{const e=d??g;return m({value:e,tabValues:a})?e:null})();(0,l.A)((()=>{j&&o(j)}),[j]);return{selectedValue:r,selectValue:(0,s.useCallback)((e=>{if(!m({value:e,tabValues:a}))throw new Error(`Can't select invalid tab value=${e}`);o(e),h(e),x(e)}),[h,x,a]),tabValues:a}}var x=i(2303);const j={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var b=i(4848);function f(e){let{className:n,block:i,selectedValue:s,selectValue:r,tabValues:l}=e;const o=[],{blockElementScrollPositionUntilNextRender:d}=(0,a.a_)(),c=e=>{const n=e.currentTarget,i=o.indexOf(n),t=l[i].value;t!==s&&(d(n),r(t))},h=e=>{let n=null;switch(e.key){case"Enter":c(e);break;case"ArrowRight":{const i=o.indexOf(e.currentTarget)+1;n=o[i]??o[0];break}case"ArrowLeft":{const i=o.indexOf(e.currentTarget)-1;n=o[i]??o[o.length-1];break}}n?.focus()};return(0,b.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,t.A)("tabs",{"tabs--block":i},n),children:l.map((e=>{let{value:n,label:i,attributes:a}=e;return(0,b.jsx)("li",{role:"tab",tabIndex:s===n?0:-1,"aria-selected":s===n,ref:e=>o.push(e),onKeyDown:h,onClick:c,...a,className:(0,t.A)("tabs__item",j.tabItem,a?.className,{"tabs__item--active":s===n}),children:i??n},n)}))})}function _(e){let{lazy:n,children:i,selectedValue:t}=e;const a=(Array.isArray(i)?i:[i]).filter(Boolean);if(n){const e=a.find((e=>e.props.value===t));return e?(0,s.cloneElement)(e,{className:"margin-top--md"}):null}return(0,b.jsx)("div",{className:"margin-top--md",children:a.map(((e,n)=>(0,s.cloneElement)(e,{key:n,hidden:e.props.value!==t})))})}function T(e){const n=g(e);return(0,b.jsxs)("div",{className:(0,t.A)("tabs-container",j.tabList),children:[(0,b.jsx)(f,{...n,...e}),(0,b.jsx)(_,{...n,...e})]})}function v(e){const n=(0,x.A)();return(0,b.jsx)(T,{...e,children:h(e.children)},String(n))}},7324:(e,n,i)=>{i.d(n,{$E:()=>x,A3:()=>b,CW:()=>j,Dx:()=>c,F4:()=>u,Fi:()=>d,J_:()=>v,LQ:()=>f,Lf:()=>y,OO:()=>t,Q7:()=>_,b:()=>l,cy:()=>o,gg:()=>p,kl:()=>m,os:()=>h,pW:()=>a,ux:()=>g,vf:()=>s,xj:()=>r,xt:()=>T});const s="shell",t="database",a="application",r="bash",l="pwsh",o="zsh",d="maria",c="mysql",h="postgres",u="sqlite",m="application",p="bash",g="pwsh",x="zsh",j="MariaDB",b="MySQL",f="PostgreSQL",_="SQLite",T="tinyorm.org",v="$HOME/Code/c/",y="$env:USERPROFILE\\Code\\c\\"},6362:(e,n,i)=>{i.d(n,{A:()=>a});var s=i(6540),t=i(1838);function a(){const e=(0,s.useContext)(t.A);if(null!=e)return e;throw new Error("useRootFolderContext is used outside of Layout component.")}},6694:(e,n,i)=>{i.d(n,{OZ:()=>o,Sn:()=>r,T3:()=>c,bw:()=>d,nC:()=>h,np:()=>l});var s=i(6362),t=i(2303),a=i(7324);const r=function(e,n){return void 0===n&&(n=!0),u((0,s.A)().rootFolder[e]??d(e),e,n)},l=()=>(0,s.A)().rootFolder[a.pW]??d(a.pW),o=function(e,n){if(void 0===n&&(n=!0),null==e)throw new Error("The groupId in the applicationFolderPath() can not be empty.");const i=n||e!==a.b?"/":"\\";return u(r(e)+i+l(),e,n)};function d(e){if(null==e)throw new Error("The groupId in the folderDefaultValue() can not be empty.");if(!(0,t.A)())return"";switch(e){case a.b:return a.Lf;case a.xj:return a.J_;case a.pW:return a.xt;default:throw new Error(`No default value for '${e}' groupId in the folderDefaultValue().`)}}function c(e){return e===a.pW}function h(e,n){if(null==n||""===n)return n;const i="$ENV{$1}$2";switch(e){case a.b:return p(n).replace(/\$env:(.+?)(\/.*)/,i);case a.xj:return n.replace(/\$(.+?)(\/.*)/,i);default:throw new Error(`Unsupported shell type '${e}' in the convertToCmakeEnvVariable().`)}}function u(e,n,i){if(void 0===i&&(i=!0),null==e||""===e)return e;if(n!==a.b)return m(e);const s=m(e);return i?p(s):function(e){return null==e||""===e?e:e.replaceAll(/\/+/g,"\\")}(s)}function m(e){return null==e||""===e?e:e.replace(/[/\\]+$/,"")}function p(e){return null==e||""===e?e:e.replaceAll(/\\+(?! )/g,"/")}},6106:(e,n,i)=>{i.d(n,{A:()=>s});const s=i.p+"assets/images/qmake-build_settings-e10927d1c4ed852620f9eb7564198940.png"},2394:(e,n,i)=>{i.d(n,{A:()=>s});const s=i.p+"assets/images/qmake-configure_project-4721257090370204b0272d166512adef.png"},4679:(e,n,i)=>{i.d(n,{A:()=>s});const s=i.p+"assets/images/tom_file_properties-0df513c47ceadd5c09165e41c6b53086.png"},53:(e,n,i)=>{i.d(n,{A:()=>s});const s=i.p+"assets/images/tom_migrate_status-63c129a10bfe6bffe8d2d5ea280860e5.png"}}]); \ No newline at end of file diff --git a/assets/js/feaee7f3.0f0c7251.js b/assets/js/feaee7f3.956a0aab.js similarity index 99% rename from assets/js/feaee7f3.0f0c7251.js rename to assets/js/feaee7f3.956a0aab.js index 0151e6e9b..a0cd3edc3 100644 --- a/assets/js/feaee7f3.0f0c7251.js +++ b/assets/js/feaee7f3.956a0aab.js @@ -1 +1 @@ -"use strict";(self.webpackChunktinyorm_org=self.webpackChunktinyorm_org||[]).push([[983],{3750:(e,n,l)=>{l.r(n),l.d(n,{assets:()=>p,contentTitle:()=>h,default:()=>j,frontMatter:()=>c,metadata:()=>u,toc:()=>m});var i=l(4848),r=l(8453),t=l(2364),o=l(9365),a=l(1470),s=l(7324),d=l(6694);const c={sidebar_position:2,sidebar_label:"Hello world",description:"Hello world example created in the terminal and QtCreator IDE.",keywords:["c++ orm","building","hello world","tinyorm"]},h="Building: Hello world",u={id:"building/hello-world",title:"Building: Hello world",description:"Hello world example created in the terminal and QtCreator IDE.",source:"@site/docs/building/hello-world.mdx",sourceDirName:"building",slug:"/building/hello-world",permalink:"/building/hello-world",draft:!1,unlisted:!1,tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2,sidebar_label:"Hello world",description:"Hello world example created in the terminal and QtCreator IDE.",keywords:["c++ orm","building","hello world","tinyorm"]},sidebar:"tinyormSidebar",previous:{title:"TinyORM",permalink:"/building/tinyorm"},next:{title:"Migrations",permalink:"/building/migrations"}},p={},m=[{value:"Introduction",id:"introduction",level:2},{value:"Prepare SQLite 3 database",id:"prepare-sqlite-3-database",level:2},{value:"Install dependencies",id:"install-dependencies",level:2},{value:"Using vcpkg.json (manifest mode)",id:"using-vcpkg-json-manifest-mode",level:4},{value:"Using vcpkg install (manually)",id:"using-vcpkg-install-manually",level:4},{value:"Source code",id:"source-code",level:2},{value:"Hello world with CMake",id:"hello-world-with-cmake",level:2},{value:"CMake project",id:"cmake-project",level:3},{value:"FetchContent",id:"fetchcontent",level:3},{value:"How FetchContent module works",id:"how-fetchcontent-module-works",level:4},{value:"Build Hello world",id:"build-hello-world-cmake",level:3},{value:"Execute Hello world",id:"execute-hello-world-cmake",level:3},{value:"Hello world with qmake",id:"hello-world-with-qmake",level:2},{value:"qmake project",id:"qmake-project",level:3},{value:"Auto-configure using .qmake.conf and .env",id:"auto-configure-using-qmake_conf-and-env",level:4},{value:"Build Hello world",id:"build-hello-world-qmake",level:3},{value:"Execute Hello world",id:"execute-hello-world-qmake",level:3}];function x(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"building-hello-world",children:"Building: Hello world"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#introduction",children:"Introduction"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#prepare-sqlite-3-database",children:"Prepare SQLite 3 database"})}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"#install-dependencies",children:"Install dependencies"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#using-vcpkg-json-manifest-mode",children:"Using vcpkg.json"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#using-vcpkg-install-manually",children:"Using vcpkg install"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#source-code",children:"Source code"})}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"#hello-world-with-cmake",children:"Hello world with CMake"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#cmake-project",children:"CMake project"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#fetchcontent",children:"FetchContent"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#build-hello-world-cmake",children:"Build Hello world"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#execute-hello-world-cmake",children:"Execute Hello world"})}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"#hello-world-with-qmake",children:"Hello world with qmake"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#qmake-project",children:"qmake project"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#build-hello-world-qmake",children:"Build Hello world"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#execute-hello-world-qmake",children:"Execute Hello world"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsxs)(n.p,{children:["We will try to create the simplest working console application, in the terminal with the ",(0,i.jsx)(n.code,{children:"CMake"})," and in the ",(0,i.jsx)(n.code,{children:"QtCreator IDE"})," with the ",(0,i.jsx)(n.code,{children:"qmake"})," build systems."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"HelloWorld"})," example also expects the following ",(0,i.jsx)(n.a,{href:"/building/tinyorm#folders-structure",children:"folders structure"}),", let's create them."]}),"\n",(0,i.jsxs)(a.A,{groupId:s.vf,children:[(0,i.jsx)(o.A,{value:s.b,label:s.ux,children:(0,i.jsx)(t.A,{className:"language-powershell",children:`cd ${(0,d.OZ)(s.b)}\nmkdir HelloWorld/HelloWorld\ncd HelloWorld`})}),(0,i.jsx)(o.A,{value:s.xj,label:s.gg,children:(0,i.jsx)(t.A,{className:"language-bash",children:`cd ${(0,d.OZ)(s.xj)}\nmkdir -p HelloWorld/HelloWorld\ncd HelloWorld`})})]}),"\n",(0,i.jsx)(n.h2,{id:"prepare-sqlite-3-database",children:"Prepare SQLite 3 database"}),"\n",(0,i.jsxs)(n.p,{children:["The easiest way to demonstrate the ",(0,i.jsx)(n.code,{children:"HelloWorld"})," example will be with a ",(0,i.jsx)(n.code,{children:"SQLite 3"})," database."]}),"\n",(0,i.jsxs)(n.p,{children:["Execute the following command in the terminal to create and insert two rows into the ",(0,i.jsx)(n.code,{children:"SQLite 3"})," database."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sqlite3 HelloWorld.sqlite3 \"\ncreate table posts(id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name VARCHAR NOT NULL);\ninsert into posts values(1, 'First Post');\ninsert into posts values(2, 'Second Post');\nselect * from posts;\"\n"})}),"\n",(0,i.jsx)(n.h2,{id:"install-dependencies",children:"Install dependencies"}),"\n",(0,i.jsxs)(n.p,{children:["First, install the ",(0,i.jsx)(n.code,{children:"vcpkg"})," package manager as is described ",(0,i.jsx)(n.a,{href:"/building/tinyorm#vcpkg",children:"here"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"range-v3"})," and ",(0,i.jsx)(n.code,{children:"tabulate"})," libraries are required dependencies because ",(0,i.jsx)(n.code,{children:"TinyORM"})," uses them in header files, you have to install them before you can use ",(0,i.jsx)(n.code,{children:"TinyORM"}),". The ",(0,i.jsx)(n.code,{children:"tabulate"})," library is only needed in the ",(0,i.jsx)(n.code,{children:"tom"})," migrations it's used by the ",(0,i.jsx)(n.code,{children:"migrate:status"})," command."]}),"\n",(0,i.jsxs)(n.p,{children:["There are two ways how to install the ",(0,i.jsx)(n.code,{children:"range-v3"})," and ",(0,i.jsx)(n.code,{children:"tabulate"})," libraries using ",(0,i.jsx)(n.code,{children:"vcpkg"}),"."]}),"\n",(0,i.jsxs)(n.h4,{id:"using-vcpkg-json-manifest-mode",children:["Using vcpkg.json ",(0,i.jsx)("small",{children:"(manifest mode)"})]}),"\n",(0,i.jsxs)(n.p,{children:["Create a ",(0,i.jsx)(n.code,{children:"vcpkg.json"})," file with the following content. ",(0,i.jsx)(n.code,{children:"CMake"})," example below uses this method."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"cd HelloWorld\nvim vcpkg.json\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",metastring:"title='vcpkg.json'",children:'{\n "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json",\n "name": "tinyorm-helloworld",\n "version-semver": "0.1.0",\n "maintainers": "Silver Zachara ",\n "description": "Hello world console application for TinyORM C++ library",\n "homepage": "https://github.com/silverqx/TinyORM",\n "documentation": "https://www.tinyorm.org/building/hello-world",\n "supports": "!(uwp | arm | android | emscripten | osx | ios | xbox | freebsd | openbsd | wasm32)",\n "dependencies": [\n "range-v3",\n "tabulate"\n ]\n}\n'})}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsxs)(n.p,{children:["Only ",(0,i.jsx)(n.code,{children:"CMake"})," via the ",(0,i.jsx)(n.code,{children:"toolchain file"})," supports this method."]})}),"\n",(0,i.jsxs)(n.h4,{id:"using-vcpkg-install-manually",children:["Using vcpkg install ",(0,i.jsx)("small",{children:"(manually)"})]}),"\n",(0,i.jsxs)(n.p,{children:["This method can be used with both ",(0,i.jsx)(n.code,{children:"CMake"})," and ",(0,i.jsx)(n.code,{children:"qmake"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"cd ../../vcpkg\n\nvcpkg search range-v3\nvcpkg search tabulate\nvcpkg install range-v3 tabulate\nvcpkg list\n"})}),"\n",(0,i.jsx)(n.h2,{id:"source-code",children:"Source code"}),"\n",(0,i.jsxs)(n.p,{children:["Let's start in the ",(0,i.jsx)(n.code,{children:"HelloWorld"})," project folder."]}),"\n",(0,i.jsxs)(a.A,{groupId:s.vf,children:[(0,i.jsx)(o.A,{value:s.b,label:s.ux,children:(0,i.jsx)(t.A,{className:"language-powershell",children:`cd ${(0,d.OZ)(s.b)}/HelloWorld/HelloWorld`})}),(0,i.jsx)(o.A,{value:s.xj,label:s.gg,children:(0,i.jsx)(t.A,{className:"language-bash",children:`cd ${(0,d.OZ)(s.xj)}/HelloWorld/HelloWorld`})})]}),"\n",(0,i.jsxs)(n.p,{children:["Create ",(0,i.jsx)(n.code,{children:"main.cpp"})," source file."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"vim main.cpp\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["To paste a source code correctly in ",(0,i.jsx)(n.code,{children:"vim"}),", press ",(0,i.jsx)("kbd",{children:"Shift"})," + ",(0,i.jsx)("kbd",{children:"p"}),"."]})}),"\n",(0,i.jsx)(n.p,{children:"And paste the following code."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-cpp",metastring:"title='main.cpp'",children:'#include \n#include \n\n#ifdef _WIN32\n# include \n#endif\n\n#include \n\nusing Orm::DB;\n\nint main(int argc, char *argv[])\n{\n#ifdef _WIN32\n SetConsoleOutputCP(CP_UTF8);\n// SetConsoleOutputCP(1250);\n#endif\n\n /* Needed from Qt v6.5.3 to avoid:\n qt.core.qobject.connect: QObject::connect(QObject, Unknown): invalid nullptr parameter */\n QCoreApplication app(argc, argv);\n\n // Ownership of a shared_ptr()\n auto manager = DB::create({\n {"driver", "QSQLITE"},\n {"database", qEnvironmentVariable("TINYORM_HELLOWORLD_DB_SQLITE_DATABASE",\n "../../HelloWorld.sqlite3")},\n {"check_database_exists", true},\n });\n\n auto posts = DB::select("select * from posts");\n\n while(posts.next())\n qDebug() << posts.value("id").toULongLong()\n << posts.value("name").toString();\n}\n'})}),"\n",(0,i.jsx)(n.admonition,{type:"warning",children:(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"QSqlDatabase"})," depends on ",(0,i.jsx)(n.code,{children:"QCoreApplication"})," from ",(0,i.jsx)(n.code,{children:"Qt v6.5.3"})," so you must create the ",(0,i.jsx)(n.code,{children:"QCoreApplication"})," instance before you will call anything from the ",(0,i.jsx)(n.code,{children:"TinyORM"})," library. \ud83e\udee4 The change was made ",(0,i.jsx)(n.a,{href:"https://github.com/qt/qtbase/commit/8d2bdc9cd5482eace12ba7e45304857bd24db0e6#diff-1d355c25c0b0eddec2be48253407780c4dc510d986739aec61e1ec892ccaf86e",children:"here"}),"."]})}),"\n",(0,i.jsx)(n.h2,{id:"hello-world-with-cmake",children:"Hello world with CMake"}),"\n",(0,i.jsxs)(n.p,{children:["Create a folder for the ",(0,i.jsx)(n.code,{children:"CMake"})," build."]}),"\n",(0,i.jsxs)(a.A,{groupId:s.vf,children:[(0,i.jsx)(o.A,{value:s.b,label:s.ux,children:(0,i.jsx)(t.A,{className:"language-powershell",children:"cd ..\nmkdir HelloWorld-builds-cmake/build-debug\n\ncd HelloWorld"})}),(0,i.jsx)(o.A,{value:s.xj,label:s.gg,children:(0,i.jsx)(t.A,{className:"language-bash",children:"cd ..\nmkdir -p HelloWorld-builds-cmake/build-debug\n\ncd HelloWorld"})})]}),"\n",(0,i.jsx)(n.h3,{id:"cmake-project",children:"CMake project"}),"\n",(0,i.jsxs)(n.p,{children:["Create ",(0,i.jsx)(n.code,{children:"CMakeLists.txt"})," file with the following content."]}),"\n",(0,i.jsxs)(a.A,{groupId:s.vf,children:[(0,i.jsx)(o.A,{value:s.b,label:s.ux,children:(0,i.jsx)(t.A,{className:"language-cmake",children:`cmake_minimum_required(VERSION VERSION 3.22...3.29 FATAL_ERROR)\n\nproject(HelloWorld LANGUAGES CXX)\n\n# build tree\nlist(APPEND CMAKE_PREFIX_PATH "${(0,d.nC)(s.b,(0,d.OZ)(s.b))}/TinyORM/TinyORM-builds-cmake/build-debug")\n\nset(CMAKE_CXX_STANDARD 20)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\nset(CMAKE_CXX_EXTENSIONS OFF)\n\nadd_executable(HelloWorld\n main.cpp\n)\n\nfind_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)\nfind_package(Qt\${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)\nfind_package(TinyOrm 0.37.3 CONFIG REQUIRED)\n\ntarget_link_libraries(HelloWorld\n PRIVATE\n Qt\${QT_VERSION_MAJOR}::Core\n TinyOrm::TinyOrm\n)`})}),(0,i.jsx)(o.A,{value:s.xj,label:s.gg,children:(0,i.jsx)(t.A,{className:"language-cmake",children:`cmake_minimum_required(VERSION VERSION 3.22...3.29 FATAL_ERROR)\n\nproject(HelloWorld LANGUAGES CXX)\n\n# build tree\nlist(APPEND CMAKE_PREFIX_PATH "${(0,d.nC)(s.xj,(0,d.OZ)(s.xj))}/TinyORM/TinyORM-builds-cmake/build-debug")\n\nset(CMAKE_CXX_STANDARD 20)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\nset(CMAKE_CXX_EXTENSIONS OFF)\n\nadd_executable(HelloWorld\n main.cpp\n)\n\nfind_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)\nfind_package(Qt\${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)\nfind_package(TinyOrm 0.37.3 CONFIG REQUIRED)\n\ntarget_link_libraries(HelloWorld\n PRIVATE\n Qt\${QT_VERSION_MAJOR}::Core\n TinyOrm::TinyOrm\n)`})})]}),"\n",(0,i.jsx)(n.h3,{id:"fetchcontent",children:"FetchContent"}),"\n",(0,i.jsxs)(n.p,{children:["If you don't have cloned and built the ",(0,i.jsx)(n.code,{children:"TinyORM"})," library, or you want to quickly try TinyORM without wasting time with cloning and building the TinyORM library, then you can use CMake's ",(0,i.jsx)(n.a,{href:"https://cmake.org/cmake/help/latest/module/FetchContent.html",children:(0,i.jsx)(n.code,{children:"FetchContent"})})," module that will do all of this for you."]}),"\n",(0,i.jsxs)(n.p,{children:["Instead of providing a path by the ",(0,i.jsx)(n.code,{children:"CMAKE_PREFIX_PATH"})," (or using the ",(0,i.jsx)(n.code,{children:"User Package Registry"}),") like in the example below:"]}),"\n",(0,i.jsxs)(a.A,{groupId:s.vf,children:[(0,i.jsx)(o.A,{value:s.b,label:s.ux,children:(0,i.jsx)(t.A,{className:"language-cmake",children:`# build tree\nlist(APPEND CMAKE_PREFIX_PATH "${(0,d.nC)(s.b,(0,d.OZ)(s.b))}/TinyORM/TinyORM-builds-cmake/build-debug")`})}),(0,i.jsx)(o.A,{value:s.xj,label:s.gg,children:(0,i.jsx)(t.A,{className:"language-cmake",children:`# build tree\nlist(APPEND CMAKE_PREFIX_PATH "${(0,d.nC)(s.xj,(0,d.OZ)(s.xj))}/TinyORM/TinyORM-builds-cmake/build-debug")`})})]}),"\n",(0,i.jsxs)(n.p,{children:["You can use the ",(0,i.jsx)(n.a,{href:"https://cmake.org/cmake/help/latest/module/FetchContent.html",children:(0,i.jsx)(n.code,{children:"FetchContent"})})," module like in the following example."]}),"\n",(0,i.jsxs)(a.A,{groupId:s.vf,children:[(0,i.jsx)(o.A,{value:s.b,label:s.ux,children:(0,i.jsx)(t.A,{className:"language-cmake",children:"cmake_minimum_required(VERSION VERSION 3.22...3.29 FATAL_ERROR)\n\nproject(HelloWorld LANGUAGES CXX)\n\nset(CMAKE_CXX_STANDARD 20)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\nset(CMAKE_CXX_EXTENSIONS OFF)\n\n# FetchContent method\ninclude(FetchContent)\nFetchContent_Declare(TinyOrm\n GIT_REPOSITORY https://github.com/silverqx/TinyORM.git\n GIT_TAG origin/main\n OVERRIDE_FIND_PACKAGE\n)\n# Here you can configure TinyORM CMake options\nset(MYSQL_PING OFF)\nset(TOM_EXAMPLE ON)\n\nadd_executable(HelloWorld\n main.cpp\n)\n\nfind_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)\nfind_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)\nfind_package(TinyOrm 0.37.3 CONFIG REQUIRED)\n\ntarget_link_libraries(HelloWorld\n PRIVATE\n Qt${QT_VERSION_MAJOR}::Core\n TinyOrm::TinyOrm\n)"})}),(0,i.jsx)(o.A,{value:s.xj,label:s.gg,children:(0,i.jsx)(t.A,{className:"language-cmake",children:"cmake_minimum_required(VERSION VERSION 3.22...3.29 FATAL_ERROR)\n\nproject(HelloWorld LANGUAGES CXX)\n\nset(CMAKE_CXX_STANDARD 20)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\nset(CMAKE_CXX_EXTENSIONS OFF)\n\n# FetchContent method\ninclude(FetchContent)\nFetchContent_Declare(TinyOrm\n GIT_REPOSITORY https://github.com/silverqx/TinyORM.git\n GIT_TAG origin/main\n OVERRIDE_FIND_PACKAGE\n)\n# Here you can configure TinyORM CMake options\nset(MYSQL_PING OFF)\nset(TOM_EXAMPLE ON)\n\nadd_executable(HelloWorld\n main.cpp\n)\n\nfind_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)\nfind_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)\nfind_package(TinyOrm 0.37.3 CONFIG REQUIRED)\n\ntarget_link_libraries(HelloWorld\n PRIVATE\n Qt${QT_VERSION_MAJOR}::Core\n TinyOrm::TinyOrm\n)"})})]}),"\n",(0,i.jsx)(n.h4,{id:"how-fetchcontent-module-works",children:"How FetchContent module works"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"FetchContent_Declare"})," command is like calling the git clone inside the build folder and then adding a cloned folder in a similar way as the ",(0,i.jsx)(n.code,{children:"add_subdirectory()"})," command does."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"FetchContent_MakeAvailable()"})," internally calls the ",(0,i.jsx)(n.code,{children:"find_package()"})," command or if you pass the ",(0,i.jsx)(n.code,{children:"OVERRIDE_FIND_PACKAGE"})," argument, then you don't have to call the the ",(0,i.jsx)(n.code,{children:"FetchContent_MakeAvailable"}),", but you must call the ",(0,i.jsx)(n.code,{children:"find_package( x.y.z CONFIG REQUIRED)"})," command manually."]}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsxs)(n.p,{children:["An advantage of the ",(0,i.jsx)(n.code,{children:"OVERRIDE_FIND_PACKAGE"})," argument is that you can call the ",(0,i.jsx)(n.code,{children:"find_package"})," command much later, and you can insert additional configurations between."]})}),"\n",(0,i.jsx)(n.h3,{id:"build-hello-world-cmake",children:"Build Hello world"}),"\n",(0,i.jsxs)(n.p,{children:["Now you are ready to configure ",(0,i.jsx)(n.code,{children:"HelloWorld"})," ",(0,i.jsx)(n.code,{children:"CMake"})," application."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"cd ../HelloWorld-builds-cmake/build-debug\n"})}),"\n",(0,i.jsxs)(a.A,{groupId:s.vf,children:[(0,i.jsx)(o.A,{value:s.b,label:s.ux,children:(0,i.jsx)(t.A,{className:"language-powershell",children:`cmake.exe \`\n-S "${(0,d.OZ)(s.b)}/HelloWorld/HelloWorld" \`\n-B "${(0,d.OZ)(s.b)}/HelloWorld/HelloWorld-builds-cmake/build-debug" \`\n-G 'Ninja' \`\n-D CMAKE_BUILD_TYPE:STRING='Debug' \`\n-D CMAKE_TOOLCHAIN_FILE:FILEPATH="${(0,d.Sn)(s.b)}/vcpkg/scripts/buildsystems/vcpkg.cmake" \`\n-D CMAKE_CXX_SCAN_FOR_MODULES:BOOL=OFF \`\n-D CMAKE_INSTALL_PREFIX:PATH="${(0,d.Sn)(s.b)}/tmp/HelloWorld"`})}),(0,i.jsx)(o.A,{value:s.xj,label:s.gg,children:(0,i.jsx)(t.A,{className:"language-bash",children:`cmake \\\n-S "${(0,d.OZ)(s.xj)}/HelloWorld/HelloWorld" \\\n-B "${(0,d.OZ)(s.xj)}/HelloWorld/HelloWorld-builds-cmake/build-debug" \\\n-G 'Ninja' \\\n-D CMAKE_BUILD_TYPE:STRING='Debug' \\\n-D CMAKE_TOOLCHAIN_FILE:FILEPATH="${(0,d.Sn)(s.xj)}/vcpkg/scripts/buildsystems/vcpkg.cmake" \\\n-D CMAKE_CXX_SCAN_FOR_MODULES:BOOL=OFF \\\n-D CMAKE_INSTALL_PREFIX:PATH="${(0,d.Sn)(s.xj)}/tmp/TinyORM"`})})]}),"\n",(0,i.jsx)(n.p,{children:"And build."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"cmake --build . --target all\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["Enable the ",(0,i.jsx)(n.a,{href:"/building/tinyorm#cmake-strict_mode-option",children:(0,i.jsx)(n.code,{children:"TINYORM_STRICT_MODE"})})," environment variable to produce better code and to follow good code practices."]})}),"\n",(0,i.jsx)(n.h3,{id:"execute-hello-world-cmake",children:"Execute Hello world"}),"\n",(0,i.jsxs)(n.p,{children:["Do not forget to add ",(0,i.jsx)(n.code,{children:"TinyOrm0d.dll"})," on the path on Windows and on the ",(0,i.jsx)(n.code,{children:"LD_LIBRARY_PATH"})," on Linux, so ",(0,i.jsx)(n.code,{children:"HelloWorld"})," application can find it during execution, as is described ",(0,i.jsx)(n.a,{href:"/building/tinyorm#tinyorm-on-path-cmake",children:"here"}),"."]}),"\n",(0,i.jsxs)(a.A,{groupId:s.vf,name:"tinyorm-on-path",children:[(0,i.jsx)(o.A,{value:s.b,label:s.ux,children:(0,i.jsx)(t.A,{className:"language-powershell",children:`$env:Path = "${(0,d.OZ)(s.b,!1)}\\TinyORM\\TinyORM-builds-cmake\\build-debug;" + $env:Path`})}),(0,i.jsx)(o.A,{value:s.xj,label:s.gg,children:(0,i.jsx)(t.A,{className:"language-bash",children:`export LD_LIBRARY_PATH=${(0,d.OZ)(s.xj)}/TinyORM/TinyORM-builds-cmake/build-debug\${PATH:+:}$PATH`})})]}),"\n",(0,i.jsxs)(n.p,{children:["Execute ",(0,i.jsx)(n.code,{children:"HelloWorld"})," example."]}),"\n",(0,i.jsxs)(a.A,{groupId:s.vf,children:[(0,i.jsx)(o.A,{value:s.b,label:s.ux,children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-powershell",children:".\\HelloWorld.exe\n"})})}),(0,i.jsx)(o.A,{value:s.xj,label:s.gg,children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"./HelloWorld\n"})})})]}),"\n",(0,i.jsx)(n.p,{children:"The output will look like this."}),"\n",(0,i.jsx)(t.A,{className:"language-less",children:'Executed prepared query (6ms, -1 results, 0 affected, tinyorm_default) : select * from posts\n1 "First Post"\n2 "Second Post"'}),"\n",(0,i.jsx)(n.h2,{id:"hello-world-with-qmake",children:"Hello world with qmake"}),"\n",(0,i.jsxs)(n.p,{children:["Create a folder for the ",(0,i.jsx)(n.code,{children:"qmake"})," build."]}),"\n",(0,i.jsxs)(a.A,{groupId:s.vf,children:[(0,i.jsx)(o.A,{value:s.b,label:s.ux,children:(0,i.jsx)(t.A,{className:"language-powershell",children:`cd ${(0,d.OZ)(s.b)}/HelloWorld\n\nmkdir HelloWorld-builds-qmake`})}),(0,i.jsx)(o.A,{value:s.xj,label:s.gg,children:(0,i.jsx)(t.A,{className:"language-bash",children:`cd ${(0,d.OZ)(s.xj)}/HelloWorld\n\nmkdir HelloWorld-builds-qmake`})})]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.a,{href:"#source-code",children:(0,i.jsx)(n.code,{children:"source code"})})," is the same as for the ",(0,i.jsx)(n.code,{children:"HelloWorld CMake"})," example."]}),"\n",(0,i.jsx)(n.h3,{id:"qmake-project",children:"qmake project"}),"\n",(0,i.jsxs)(n.p,{children:["Create ",(0,i.jsx)(n.code,{children:"HelloWorld.pro"})," qmake file with the following content."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"cd HelloWorld\nvim HelloWorld.pro\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["To paste a source code correctly in ",(0,i.jsx)(n.code,{children:"vim"}),", press ",(0,i.jsx)("kbd",{children:"Shift"})," + ",(0,i.jsx)("kbd",{children:"p"}),"."]})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-qmake",metastring:"title='HelloWorld.pro'",children:"QT -= gui\n\nTEMPLATE = app\n\nCONFIG *= cmdline\n\nDEFINES *= PROJECT_TINYORM_HELLOWORLD\n\nSOURCES += $$PWD/main.cpp\n\n# Auto-configure TinyORM library \ud83d\udd25\ninclude($$TINY_MAIN_DIR/TinyORM/qmake/TinyOrm.pri)\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"warning",children:(0,i.jsxs)(n.p,{children:["The exact ",(0,i.jsx)(n.a,{href:"/building/tinyorm#folders-structure",children:"folders structure"})," is crucial in this example because the paths to the ",(0,i.jsx)(n.code,{children:"TinyORM"})," source and build folders are relative."]})}),"\n",(0,i.jsx)(n.admonition,{type:"warning",children:(0,i.jsx)(n.p,{children:"Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!"})}),"\n",(0,i.jsxs)(n.h4,{id:"auto-configure-using-qmake_conf-and-env",children:[(0,i.jsx)(n.code,{children:"Auto-configure"})," using ",(0,i.jsx)(n.code,{children:".qmake.conf"})," and ",(0,i.jsx)(n.code,{children:".env"})]}),"\n",(0,i.jsxs)(n.p,{children:["If you want to have properly configured ",(0,i.jsx)(n.code,{children:"DEFINES"})," (C preprocessor macros) or have Qt headers marked as system headers, then you need to specify a path to the ",(0,i.jsx)(n.code,{children:"TinyORM"})," qmake features (",(0,i.jsx)(n.code,{children:".prf"})," files) which handle this correctly; this path is provided by the ",(0,i.jsx)(n.code,{children:"QMAKEFEATURES"})," variable and can only be set in the ",(0,i.jsx)(n.code,{children:".qmake.conf"})," file."]}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["Read the ",(0,i.jsx)(n.a,{href:"/building/tinyorm#consume-tinyorm-library-qmake",children:"Consume TinyOrm library (qmake)"})," section, as everything that is described in that section applies here as well."]})}),"\n",(0,i.jsxs)(n.p,{children:["Create the ",(0,i.jsx)(n.code,{children:".qmake.conf"})," file in the ",(0,i.jsx)(n.code,{children:"HelloWorld"})," project root folder with the following content."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-qmake",metastring:"title='.qmake.conf'",children:"# Path to the PARENT folder of the TinyORM source folder\nTINY_MAIN_DIR = $$clean_path($$PWD/../../TinyORM/)\n# To find .env and .env.$$QMAKE_PLATFORM files\nTINY_DOTENV_ROOT = $$PWD\n# Path to the current build tree (used to guess the TinyORM build tree)\n#TINY_BUILD_TREE = $$shadowed($$PWD)\n\n# To find .prf files, needed by eg. CONFIG += tiny_system_headers inline/extern_constants\nQMAKEFEATURES *= $$quote($$TINY_MAIN_DIR/TinyORM/qmake/features)\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Then, create a ",(0,i.jsx)("code",{children:".env.(win32|unix|mingw)"})," file in the ",(0,i.jsx)(n.code,{children:"HelloWorld"})," project root folder with the following content."]}),"\n",(0,i.jsxs)(a.A,{groupId:s.vf,children:[(0,i.jsx)(o.A,{value:s.b,label:".env.win32",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-qmake",children:"# Names and values of these qmake variables are crucial, they are used in HelloWorld.pro\n# Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!\n\n# Path to the TinyORM build folder\nTINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_0_MSVC2022_64bit-Debug/)\n\n# Path to the vcpkg - range-v3\n# Will use the TINY_VCPKG_ROOT or VCPKG_ROOT environment variable if is empty\nTINY_VCPKG_ROOT = $$clean_path($$PWD/../../../vcpkg/)\nTINY_VCPKG_TRIPLET = x64-windows\n\n# Enable ccache wrapper\n#CONFIG *= tiny_ccache_win32\n"})})}),(0,i.jsx)(o.A,{value:s.xj,label:".env.unix",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-qmake",children:"# Names and values of these qmake variables are crucial, they are used in HelloWorld.pro\n# Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!\n\n# Path to the TinyORM build folder\nTINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_0_clang16_64bit_ccache-Debug/)\n\n# Path to the vcpkg - range-v3\n# Will use the TINY_VCPKG_ROOT or VCPKG_ROOT environment variable if is empty\nTINY_VCPKG_ROOT = $$clean_path($$PWD/../../../vcpkg/)\nTINY_VCPKG_TRIPLET = x64-linux\n\n# Use faster linker\nclang: CONFIG *= use_lld_linker\nelse: CONFIG *= use_gold_linker\n\n# Or use the mold linker\n#QMAKE_LFLAGS *= -fuse-ld=mold\n"})})}),(0,i.jsx)(o.A,{value:"mingw",label:".env.mingw",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-qmake",children:"# Names and values of these qmake variables are crucial, they are used in HelloWorld.pro\n# Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!\n\n# Path to the TinyORM build folder\nTINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_0_MSYS2_UCRT64_clang_64bit-Debug/)\n\n# Path to the vcpkg - range-v3\n# Will use the TINY_VCPKG_ROOT or VCPKG_ROOT environment variable if is empty\nTINY_VCPKG_ROOT = $$clean_path($$PWD/../../../vcpkg/)\nTINY_VCPKG_TRIPLET = x64-mingw-dynamic\n\n# Enable ccache wrapper\n#CONFIG *= tiny_ccache_win32\n\n# Use faster linker (for both GCC and Clang)\n# CONFIG *= use_lld_linker does not work on MinGW\nQMAKE_LFLAGS *= -fuse-ld=lld\n"})})})]}),"\n",(0,i.jsxs)(n.p,{children:["Don't forget to update the ",(0,i.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})," and ",(0,i.jsx)(n.code,{children:"TINY_VCPKG_ROOT"})," folder paths to your needs if you are not using the recommended ",(0,i.jsx)(n.a,{href:"/building/tinyorm#folders-structure",children:(0,i.jsx)(n.code,{children:"Folders structure"})}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["You can use the ",(0,i.jsxs)(n.a,{href:"/building/tinyorm#partial-guessing-of-the-tinyorm_build_tree",children:["Partial guessing of the ",(0,i.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})]})," if you don't like to specify it manually. Just comment out the ",(0,i.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})," and uncomment the ",(0,i.jsx)(n.code,{children:"TINY_BUILD_TREE = $$shadowed($$PWD)"})," in the ",(0,i.jsx)(n.code,{children:".qmake.conf"})," file."]}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["You can entirely avoid the ",(0,i.jsx)(n.code,{children:".env"})," files, just move the ",(0,i.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})," to the ",(0,i.jsx)(n.code,{children:".qmake.conf"})," or remove it by help of ",(0,i.jsxs)(n.a,{href:"/building/tinyorm#partial-guessing-of-the-tinyorm_build_tree",children:["Partial guessing of the ",(0,i.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})]})," and set the ",(0,i.jsx)(n.code,{children:"VCPKG_ROOT"})," environment variable at system level as is described in ",(0,i.jsx)(n.a,{href:"/building/tinyorm#set-up-vcpkg-environment",children:(0,i.jsx)(n.code,{children:"Set up vcpkg environment"})}),"."]})}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsxs)(n.p,{children:["Configuring by the ",(0,i.jsx)(n.code,{children:".qmake.conf"})," and ",(0,i.jsx)(n.code,{children:".env"})," files has one big advantage, which is that you don't have to modify the project files."]})}),"\n",(0,i.jsx)(n.h3,{id:"build-hello-world-qmake",children:"Build Hello world"}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["I recommend creating a new ",(0,i.jsx)(n.code,{children:"Session"})," in the ",(0,i.jsx)(n.code,{children:"QtCreator IDE"})," as is described ",(0,i.jsx)(n.a,{href:"/building/tinyorm#open-qtcreator-ide",children:"here"}),"."]})}),"\n",(0,i.jsxs)(n.p,{children:["Now you can open the ",(0,i.jsx)(n.code,{children:"HelloWorld.pro"})," project in the ",(0,i.jsx)(n.code,{children:"QtCreator IDE"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["This will open the ",(0,i.jsx)(n.code,{children:"Configure Project"})," tab, select some kit and update build folder paths to meet our ",(0,i.jsx)(n.a,{href:"/building/tinyorm#folders-structure",children:"folders structure"})," or like you want."]}),"\n",(0,i.jsx)("img",{src:l(3180).A,alt:"HelloWorld - QtCreator - Configure Project",width:"760"}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["You can force the ",(0,i.jsx)(n.code,{children:"QtCreator"})," to generate a build folders structure as is described ",(0,i.jsx)(n.a,{href:"/building/tinyorm#qtcreator-default-build-directory",children:"here"}),"."]})}),"\n",(0,i.jsxs)(n.p,{children:["You are ready to configure build options, hit ",(0,i.jsx)("kbd",{children:"Ctrl"}),"+",(0,i.jsx)("kbd",{children:"5"})," to open ",(0,i.jsx)(n.code,{children:"Project Settings"})," tab and select ",(0,i.jsx)(n.code,{children:"Build"})," in the left sidebar to open the ",(0,i.jsx)(n.code,{children:"Build Settings"}),", it should look similar to the following picture."]}),"\n",(0,i.jsx)("img",{src:l(7028).A,className:"no-blurry",alt:"HelloWorld - QtCreator - Build Settings",width:"760"}),"\n",(0,i.jsxs)(n.p,{children:["Disable ",(0,i.jsx)(n.code,{children:"QML debugging and profiling"})," and ",(0,i.jsx)(n.code,{children:"Qt Quick Compiler"}),", they are not used."]}),"\n",(0,i.jsxs)(n.p,{children:["In the left sidebar open ",(0,i.jsx)(n.code,{children:"Dependencies"})," and check ",(0,i.jsx)(n.code,{children:"TinyORM"})," project and ",(0,i.jsx)(n.code,{children:"Synchronize configuration"}),", this setting ensures that the current project will be rebuilt correctly when the ",(0,i.jsx)(n.code,{children:"TinyORM"})," library source code changes."]}),"\n",(0,i.jsxs)(n.p,{children:["Everything is ready to build, you can press ",(0,i.jsx)("kbd",{children:"Ctrl"}),"+",(0,i.jsx)("kbd",{children:"b"})," to build the project."]}),"\n",(0,i.jsx)(n.h3,{id:"execute-hello-world-qmake",children:"Execute Hello world"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"QtCreator"})," takes care of all the necessary configurations, sets up the build environment correctly, and also prepends dependency libraries on the system path on Windows and on the ",(0,i.jsx)(n.code,{children:"LD_LIBRARY_PATH"})," on Linux."]}),"\n",(0,i.jsxs)(n.p,{children:["The only thing you might want to change is to run the ",(0,i.jsx)(n.code,{children:"HelloWorld"})," example in the new terminal window. To do so, hit ",(0,i.jsx)("kbd",{children:"Ctrl"}),"+",(0,i.jsx)("kbd",{children:"5"})," to open the ",(0,i.jsx)(n.code,{children:"Project Settings"})," tab and select ",(0,i.jsx)(n.code,{children:"Run"})," in the left sidebar to open the ",(0,i.jsx)(n.code,{children:"Run Settings"}),", then in the ",(0,i.jsx)(n.code,{children:"Run"})," section select the ",(0,i.jsx)(n.code,{children:"Run in terminal"})," checkbox."]}),"\n",(0,i.jsxs)(n.p,{children:["To execute the ",(0,i.jsx)(n.code,{children:"HelloWorld"})," example press ",(0,i.jsx)("kbd",{children:"Ctrl"})," + ",(0,i.jsx)("kbd",{children:"r"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"The output will look like this."}),"\n",(0,i.jsx)(t.A,{className:"language-less",children:'Executed prepared query (6ms, -1 results, 0 affected, tinyorm_default) : select * from posts\n1 "First Post"\n2 "Second Post"'})]})}function j(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(x,{...e})}):x(e)}},9365:(e,n,l)=>{l.d(n,{A:()=>o});l(6540);var i=l(4164);const r={tabItem:"tabItem_Ymn6"};var t=l(4848);function o(e){let{children:n,hidden:l,className:o}=e;return(0,t.jsx)("div",{role:"tabpanel",className:(0,i.A)(r.tabItem,o),hidden:l,children:n})}},1470:(e,n,l)=>{l.d(n,{A:()=>y});var i=l(6540),r=l(4164),t=l(3104),o=l(6347),a=l(205),s=l(7485),d=l(1682),c=l(9466);function h(e){return i.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,i.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function u(e){const{values:n,children:l}=e;return(0,i.useMemo)((()=>{const e=n??function(e){return h(e).map((e=>{let{props:{value:n,label:l,attributes:i,default:r}}=e;return{value:n,label:l,attributes:i,default:r}}))}(l);return function(e){const n=(0,d.X)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[n,l])}function p(e){let{value:n,tabValues:l}=e;return l.some((e=>e.value===n))}function m(e){let{queryString:n=!1,groupId:l}=e;const r=(0,o.W6)(),t=function(e){let{queryString:n=!1,groupId:l}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!l)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return l??null}({queryString:n,groupId:l});return[(0,s.aZ)(t),(0,i.useCallback)((e=>{if(!t)return;const n=new URLSearchParams(r.location.search);n.set(t,e),r.replace({...r.location,search:n.toString()})}),[t,r])]}function x(e){const{defaultValue:n,queryString:l=!1,groupId:r}=e,t=u(e),[o,s]=(0,i.useState)((()=>function(e){let{defaultValue:n,tabValues:l}=e;if(0===l.length)throw new Error("Docusaurus error: the component requires at least one children component");if(n){if(!p({value:n,tabValues:l}))throw new Error(`Docusaurus error: The has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${l.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const i=l.find((e=>e.default))??l[0];if(!i)throw new Error("Unexpected error: 0 tabValues");return i.value}({defaultValue:n,tabValues:t}))),[d,h]=m({queryString:l,groupId:r}),[x,j]=function(e){let{groupId:n}=e;const l=function(e){return e?`docusaurus.tab.${e}`:null}(n),[r,t]=(0,c.Dv)(l);return[r,(0,i.useCallback)((e=>{l&&t.set(e)}),[l,t])]}({groupId:r}),g=(()=>{const e=d??x;return p({value:e,tabValues:t})?e:null})();(0,a.A)((()=>{g&&s(g)}),[g]);return{selectedValue:o,selectValue:(0,i.useCallback)((e=>{if(!p({value:e,tabValues:t}))throw new Error(`Can't select invalid tab value=${e}`);s(e),h(e),j(e)}),[h,j,t]),tabValues:t}}var j=l(2303);const g={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var b=l(4848);function f(e){let{className:n,block:l,selectedValue:i,selectValue:o,tabValues:a}=e;const s=[],{blockElementScrollPositionUntilNextRender:d}=(0,t.a_)(),c=e=>{const n=e.currentTarget,l=s.indexOf(n),r=a[l].value;r!==i&&(d(n),o(r))},h=e=>{let n=null;switch(e.key){case"Enter":c(e);break;case"ArrowRight":{const l=s.indexOf(e.currentTarget)+1;n=s[l]??s[0];break}case"ArrowLeft":{const l=s.indexOf(e.currentTarget)-1;n=s[l]??s[s.length-1];break}}n?.focus()};return(0,b.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,r.A)("tabs",{"tabs--block":l},n),children:a.map((e=>{let{value:n,label:l,attributes:t}=e;return(0,b.jsx)("li",{role:"tab",tabIndex:i===n?0:-1,"aria-selected":i===n,ref:e=>s.push(e),onKeyDown:h,onClick:c,...t,className:(0,r.A)("tabs__item",g.tabItem,t?.className,{"tabs__item--active":i===n}),children:l??n},n)}))})}function _(e){let{lazy:n,children:l,selectedValue:r}=e;const t=(Array.isArray(l)?l:[l]).filter(Boolean);if(n){const e=t.find((e=>e.props.value===r));return e?(0,i.cloneElement)(e,{className:"margin-top--md"}):null}return(0,b.jsx)("div",{className:"margin-top--md",children:t.map(((e,n)=>(0,i.cloneElement)(e,{key:n,hidden:e.props.value!==r})))})}function T(e){const n=x(e);return(0,b.jsxs)("div",{className:(0,r.A)("tabs-container",g.tabList),children:[(0,b.jsx)(f,{...n,...e}),(0,b.jsx)(_,{...n,...e})]})}function y(e){const n=(0,j.A)();return(0,b.jsx)(T,{...e,children:h(e.children)},String(n))}},7324:(e,n,l)=>{l.d(n,{$E:()=>j,A3:()=>b,CW:()=>g,Dx:()=>c,F4:()=>u,Fi:()=>d,J_:()=>y,LQ:()=>f,Lf:()=>k,OO:()=>r,Q7:()=>_,b:()=>a,cy:()=>s,gg:()=>m,kl:()=>p,os:()=>h,pW:()=>t,ux:()=>x,vf:()=>i,xj:()=>o,xt:()=>T});const i="shell",r="database",t="application",o="bash",a="pwsh",s="zsh",d="maria",c="mysql",h="postgres",u="sqlite",p="application",m="bash",x="pwsh",j="zsh",g="MariaDB",b="MySQL",f="PostgreSQL",_="SQLite",T="tinyorm.org",y="$HOME/Code/c/",k="$env:USERPROFILE\\Code\\c\\"},6362:(e,n,l)=>{l.d(n,{A:()=>t});var i=l(6540),r=l(1838);function t(){const e=(0,i.useContext)(r.A);if(null!=e)return e;throw new Error("useRootFolderContext is used outside of Layout component.")}},6694:(e,n,l)=>{l.d(n,{OZ:()=>s,Sn:()=>o,T3:()=>c,bw:()=>d,nC:()=>h,np:()=>a});var i=l(6362),r=l(2303),t=l(7324);const o=function(e,n){return void 0===n&&(n=!0),u((0,i.A)().rootFolder[e]??d(e),e,n)},a=()=>(0,i.A)().rootFolder[t.pW]??d(t.pW),s=function(e,n){if(void 0===n&&(n=!0),null==e)throw new Error("The groupId in the applicationFolderPath() can not be empty.");const l=n||e!==t.b?"/":"\\";return u(o(e)+l+a(),e,n)};function d(e){if(null==e)throw new Error("The groupId in the folderDefaultValue() can not be empty.");if(!(0,r.A)())return"";switch(e){case t.b:return t.Lf;case t.xj:return t.J_;case t.pW:return t.xt;default:throw new Error(`No default value for '${e}' groupId in the folderDefaultValue().`)}}function c(e){return e===t.pW}function h(e,n){if(null==n||""===n)return n;const l="$ENV{$1}$2";switch(e){case t.b:return m(n).replace(/\$env:(.+?)(\/.*)/,l);case t.xj:return n.replace(/\$(.+?)(\/.*)/,l);default:throw new Error(`Unsupported shell type '${e}' in the convertToCmakeEnvVariable().`)}}function u(e,n,l){if(void 0===l&&(l=!0),null==e||""===e)return e;if(n!==t.b)return p(e);const i=p(e);return l?m(i):function(e){return null==e||""===e?e:e.replaceAll(/\/+/g,"\\")}(i)}function p(e){return null==e||""===e?e:e.replace(/[/\\]+$/,"")}function m(e){return null==e||""===e?e:e.replaceAll(/\\+(?! )/g,"/")}},7028:(e,n,l)=>{l.d(n,{A:()=>i});const i=l.p+"assets/images/qmake-build_settings-ebdc6c0c056d11462096ff10cba682a1.png"},3180:(e,n,l)=>{l.d(n,{A:()=>i});const i=l.p+"assets/images/qmake-configure_project-8caf87e6af4452f0c28bd15c85c392fc.png"}}]); \ No newline at end of file +"use strict";(self.webpackChunktinyorm_org=self.webpackChunktinyorm_org||[]).push([[983],{3750:(e,n,l)=>{l.r(n),l.d(n,{assets:()=>p,contentTitle:()=>h,default:()=>j,frontMatter:()=>c,metadata:()=>u,toc:()=>m});var i=l(4848),r=l(8453),t=l(2364),o=l(9365),a=l(1470),s=l(7324),d=l(6694);const c={sidebar_position:2,sidebar_label:"Hello world",description:"Hello world example created in the terminal and QtCreator IDE.",keywords:["c++ orm","building","hello world","tinyorm"]},h="Building: Hello world",u={id:"building/hello-world",title:"Building: Hello world",description:"Hello world example created in the terminal and QtCreator IDE.",source:"@site/docs/building/hello-world.mdx",sourceDirName:"building",slug:"/building/hello-world",permalink:"/building/hello-world",draft:!1,unlisted:!1,tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2,sidebar_label:"Hello world",description:"Hello world example created in the terminal and QtCreator IDE.",keywords:["c++ orm","building","hello world","tinyorm"]},sidebar:"tinyormSidebar",previous:{title:"TinyORM",permalink:"/building/tinyorm"},next:{title:"Migrations",permalink:"/building/migrations"}},p={},m=[{value:"Introduction",id:"introduction",level:2},{value:"Prepare SQLite 3 database",id:"prepare-sqlite-3-database",level:2},{value:"Install dependencies",id:"install-dependencies",level:2},{value:"Using vcpkg.json (manifest mode)",id:"using-vcpkg-json-manifest-mode",level:4},{value:"Using vcpkg install (manually)",id:"using-vcpkg-install-manually",level:4},{value:"Source code",id:"source-code",level:2},{value:"Hello world with CMake",id:"hello-world-with-cmake",level:2},{value:"CMake project",id:"cmake-project",level:3},{value:"FetchContent",id:"fetchcontent",level:3},{value:"How FetchContent module works",id:"how-fetchcontent-module-works",level:4},{value:"Build Hello world",id:"build-hello-world-cmake",level:3},{value:"Execute Hello world",id:"execute-hello-world-cmake",level:3},{value:"Hello world with qmake",id:"hello-world-with-qmake",level:2},{value:"qmake project",id:"qmake-project",level:3},{value:"Auto-configure using .qmake.conf and .env",id:"auto-configure-using-qmake_conf-and-env",level:4},{value:"Build Hello world",id:"build-hello-world-qmake",level:3},{value:"Execute Hello world",id:"execute-hello-world-qmake",level:3}];function x(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"building-hello-world",children:"Building: Hello world"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#introduction",children:"Introduction"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#prepare-sqlite-3-database",children:"Prepare SQLite 3 database"})}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"#install-dependencies",children:"Install dependencies"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#using-vcpkg-json-manifest-mode",children:"Using vcpkg.json"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#using-vcpkg-install-manually",children:"Using vcpkg install"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#source-code",children:"Source code"})}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"#hello-world-with-cmake",children:"Hello world with CMake"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#cmake-project",children:"CMake project"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#fetchcontent",children:"FetchContent"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#build-hello-world-cmake",children:"Build Hello world"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#execute-hello-world-cmake",children:"Execute Hello world"})}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"#hello-world-with-qmake",children:"Hello world with qmake"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#qmake-project",children:"qmake project"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#build-hello-world-qmake",children:"Build Hello world"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#execute-hello-world-qmake",children:"Execute Hello world"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsxs)(n.p,{children:["We will try to create the simplest working console application, in the terminal with the ",(0,i.jsx)(n.code,{children:"CMake"})," and in the ",(0,i.jsx)(n.code,{children:"QtCreator IDE"})," with the ",(0,i.jsx)(n.code,{children:"qmake"})," build systems."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"HelloWorld"})," example also expects the following ",(0,i.jsx)(n.a,{href:"/building/tinyorm#folders-structure",children:"folders structure"}),", let's create them."]}),"\n",(0,i.jsxs)(a.A,{groupId:s.vf,children:[(0,i.jsx)(o.A,{value:s.b,label:s.ux,children:(0,i.jsx)(t.A,{className:"language-powershell",children:`cd ${(0,d.OZ)(s.b)}\nmkdir HelloWorld/HelloWorld\ncd HelloWorld`})}),(0,i.jsx)(o.A,{value:s.xj,label:s.gg,children:(0,i.jsx)(t.A,{className:"language-bash",children:`cd ${(0,d.OZ)(s.xj)}\nmkdir -p HelloWorld/HelloWorld\ncd HelloWorld`})})]}),"\n",(0,i.jsx)(n.h2,{id:"prepare-sqlite-3-database",children:"Prepare SQLite 3 database"}),"\n",(0,i.jsxs)(n.p,{children:["The easiest way to demonstrate the ",(0,i.jsx)(n.code,{children:"HelloWorld"})," example will be with a ",(0,i.jsx)(n.code,{children:"SQLite 3"})," database."]}),"\n",(0,i.jsxs)(n.p,{children:["Execute the following command in the terminal to create and insert two rows into the ",(0,i.jsx)(n.code,{children:"SQLite 3"})," database."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sqlite3 HelloWorld.sqlite3 \"\ncreate table posts(id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name VARCHAR NOT NULL);\ninsert into posts values(1, 'First Post');\ninsert into posts values(2, 'Second Post');\nselect * from posts;\"\n"})}),"\n",(0,i.jsx)(n.h2,{id:"install-dependencies",children:"Install dependencies"}),"\n",(0,i.jsxs)(n.p,{children:["First, install the ",(0,i.jsx)(n.code,{children:"vcpkg"})," package manager as is described ",(0,i.jsx)(n.a,{href:"/building/tinyorm#vcpkg",children:"here"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"range-v3"})," and ",(0,i.jsx)(n.code,{children:"tabulate"})," libraries are required dependencies because ",(0,i.jsx)(n.code,{children:"TinyORM"})," uses them in header files, you have to install them before you can use ",(0,i.jsx)(n.code,{children:"TinyORM"}),". The ",(0,i.jsx)(n.code,{children:"tabulate"})," library is only needed in the ",(0,i.jsx)(n.code,{children:"tom"})," migrations it's used by the ",(0,i.jsx)(n.code,{children:"migrate:status"})," command."]}),"\n",(0,i.jsxs)(n.p,{children:["There are two ways how to install the ",(0,i.jsx)(n.code,{children:"range-v3"})," and ",(0,i.jsx)(n.code,{children:"tabulate"})," libraries using ",(0,i.jsx)(n.code,{children:"vcpkg"}),"."]}),"\n",(0,i.jsxs)(n.h4,{id:"using-vcpkg-json-manifest-mode",children:["Using vcpkg.json ",(0,i.jsx)("small",{children:"(manifest mode)"})]}),"\n",(0,i.jsxs)(n.p,{children:["Create a ",(0,i.jsx)(n.code,{children:"vcpkg.json"})," file with the following content. ",(0,i.jsx)(n.code,{children:"CMake"})," example below uses this method."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"cd HelloWorld\nvim vcpkg.json\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",metastring:"title='vcpkg.json'",children:'{\n "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json",\n "name": "tinyorm-helloworld",\n "version-semver": "0.1.0",\n "maintainers": "Silver Zachara ",\n "description": "Hello world console application for TinyORM C++ library",\n "homepage": "https://github.com/silverqx/TinyORM",\n "documentation": "https://www.tinyorm.org/building/hello-world",\n "supports": "!(uwp | arm | android | emscripten | osx | ios | xbox | freebsd | openbsd | wasm32)",\n "dependencies": [\n "range-v3",\n "tabulate"\n ]\n}\n'})}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsxs)(n.p,{children:["Only ",(0,i.jsx)(n.code,{children:"CMake"})," via the ",(0,i.jsx)(n.code,{children:"toolchain file"})," supports this method."]})}),"\n",(0,i.jsxs)(n.h4,{id:"using-vcpkg-install-manually",children:["Using vcpkg install ",(0,i.jsx)("small",{children:"(manually)"})]}),"\n",(0,i.jsxs)(n.p,{children:["This method can be used with both ",(0,i.jsx)(n.code,{children:"CMake"})," and ",(0,i.jsx)(n.code,{children:"qmake"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"cd ../../vcpkg\n\nvcpkg search range-v3\nvcpkg search tabulate\nvcpkg install range-v3 tabulate\nvcpkg list\n"})}),"\n",(0,i.jsx)(n.h2,{id:"source-code",children:"Source code"}),"\n",(0,i.jsxs)(n.p,{children:["Let's start in the ",(0,i.jsx)(n.code,{children:"HelloWorld"})," project folder."]}),"\n",(0,i.jsxs)(a.A,{groupId:s.vf,children:[(0,i.jsx)(o.A,{value:s.b,label:s.ux,children:(0,i.jsx)(t.A,{className:"language-powershell",children:`cd ${(0,d.OZ)(s.b)}/HelloWorld/HelloWorld`})}),(0,i.jsx)(o.A,{value:s.xj,label:s.gg,children:(0,i.jsx)(t.A,{className:"language-bash",children:`cd ${(0,d.OZ)(s.xj)}/HelloWorld/HelloWorld`})})]}),"\n",(0,i.jsxs)(n.p,{children:["Create ",(0,i.jsx)(n.code,{children:"main.cpp"})," source file."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"vim main.cpp\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["To paste a source code correctly in ",(0,i.jsx)(n.code,{children:"vim"}),", press ",(0,i.jsx)("kbd",{children:"Shift"})," + ",(0,i.jsx)("kbd",{children:"p"}),"."]})}),"\n",(0,i.jsx)(n.p,{children:"And paste the following code."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-cpp",metastring:"title='main.cpp'",children:'#include \n#include \n\n#ifdef _WIN32\n# include \n#endif\n\n#include \n\nusing Orm::DB;\n\nint main(int argc, char *argv[])\n{\n#ifdef _WIN32\n SetConsoleOutputCP(CP_UTF8);\n// SetConsoleOutputCP(1250);\n#endif\n\n /* Needed from Qt v6.5.3 to avoid:\n qt.core.qobject.connect: QObject::connect(QObject, Unknown): invalid nullptr parameter */\n QCoreApplication app(argc, argv);\n\n // Ownership of a shared_ptr()\n auto manager = DB::create({\n {"driver", "QSQLITE"},\n {"database", qEnvironmentVariable("TINYORM_HELLOWORLD_DB_SQLITE_DATABASE",\n "../../HelloWorld.sqlite3")},\n {"check_database_exists", true},\n });\n\n auto posts = DB::select("select * from posts");\n\n while(posts.next())\n qDebug() << posts.value("id").toULongLong()\n << posts.value("name").toString();\n}\n'})}),"\n",(0,i.jsx)(n.admonition,{type:"warning",children:(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"QSqlDatabase"})," depends on ",(0,i.jsx)(n.code,{children:"QCoreApplication"})," from ",(0,i.jsx)(n.code,{children:"Qt v6.5.3"})," so you must create the ",(0,i.jsx)(n.code,{children:"QCoreApplication"})," instance before you will call anything from the ",(0,i.jsx)(n.code,{children:"TinyORM"})," library. \ud83e\udee4 The change was made ",(0,i.jsx)(n.a,{href:"https://github.com/qt/qtbase/commit/8d2bdc9cd5482eace12ba7e45304857bd24db0e6#diff-1d355c25c0b0eddec2be48253407780c4dc510d986739aec61e1ec892ccaf86e",children:"here"}),"."]})}),"\n",(0,i.jsx)(n.h2,{id:"hello-world-with-cmake",children:"Hello world with CMake"}),"\n",(0,i.jsxs)(n.p,{children:["Create a folder for the ",(0,i.jsx)(n.code,{children:"CMake"})," build."]}),"\n",(0,i.jsxs)(a.A,{groupId:s.vf,children:[(0,i.jsx)(o.A,{value:s.b,label:s.ux,children:(0,i.jsx)(t.A,{className:"language-powershell",children:"cd ..\nmkdir HelloWorld-builds-cmake/build-debug\n\ncd HelloWorld"})}),(0,i.jsx)(o.A,{value:s.xj,label:s.gg,children:(0,i.jsx)(t.A,{className:"language-bash",children:"cd ..\nmkdir -p HelloWorld-builds-cmake/build-debug\n\ncd HelloWorld"})})]}),"\n",(0,i.jsx)(n.h3,{id:"cmake-project",children:"CMake project"}),"\n",(0,i.jsxs)(n.p,{children:["Create ",(0,i.jsx)(n.code,{children:"CMakeLists.txt"})," file with the following content."]}),"\n",(0,i.jsxs)(a.A,{groupId:s.vf,children:[(0,i.jsx)(o.A,{value:s.b,label:s.ux,children:(0,i.jsx)(t.A,{className:"language-cmake",children:`cmake_minimum_required(VERSION VERSION 3.22...3.29 FATAL_ERROR)\n\nproject(HelloWorld LANGUAGES CXX)\n\n# build tree\nlist(APPEND CMAKE_PREFIX_PATH "${(0,d.nC)(s.b,(0,d.OZ)(s.b))}/TinyORM/TinyORM-builds-cmake/build-debug")\n\nset(CMAKE_CXX_STANDARD 20)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\nset(CMAKE_CXX_EXTENSIONS OFF)\n\nadd_executable(HelloWorld\n main.cpp\n)\n\nfind_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)\nfind_package(Qt\${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)\nfind_package(TinyOrm 0.37.3 CONFIG REQUIRED)\n\ntarget_link_libraries(HelloWorld\n PRIVATE\n Qt\${QT_VERSION_MAJOR}::Core\n TinyOrm::TinyOrm\n)`})}),(0,i.jsx)(o.A,{value:s.xj,label:s.gg,children:(0,i.jsx)(t.A,{className:"language-cmake",children:`cmake_minimum_required(VERSION VERSION 3.22...3.29 FATAL_ERROR)\n\nproject(HelloWorld LANGUAGES CXX)\n\n# build tree\nlist(APPEND CMAKE_PREFIX_PATH "${(0,d.nC)(s.xj,(0,d.OZ)(s.xj))}/TinyORM/TinyORM-builds-cmake/build-debug")\n\nset(CMAKE_CXX_STANDARD 20)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\nset(CMAKE_CXX_EXTENSIONS OFF)\n\nadd_executable(HelloWorld\n main.cpp\n)\n\nfind_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)\nfind_package(Qt\${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)\nfind_package(TinyOrm 0.37.3 CONFIG REQUIRED)\n\ntarget_link_libraries(HelloWorld\n PRIVATE\n Qt\${QT_VERSION_MAJOR}::Core\n TinyOrm::TinyOrm\n)`})})]}),"\n",(0,i.jsx)(n.h3,{id:"fetchcontent",children:"FetchContent"}),"\n",(0,i.jsxs)(n.p,{children:["If you don't have cloned and built the ",(0,i.jsx)(n.code,{children:"TinyORM"})," library, or you want to quickly try TinyORM without wasting time with cloning and building the TinyORM library, then you can use CMake's ",(0,i.jsx)(n.a,{href:"https://cmake.org/cmake/help/latest/module/FetchContent.html",children:(0,i.jsx)(n.code,{children:"FetchContent"})})," module that will do all of this for you."]}),"\n",(0,i.jsxs)(n.p,{children:["Instead of providing a path by the ",(0,i.jsx)(n.code,{children:"CMAKE_PREFIX_PATH"})," (or using the ",(0,i.jsx)(n.code,{children:"User Package Registry"}),") like in the example below:"]}),"\n",(0,i.jsxs)(a.A,{groupId:s.vf,children:[(0,i.jsx)(o.A,{value:s.b,label:s.ux,children:(0,i.jsx)(t.A,{className:"language-cmake",children:`# build tree\nlist(APPEND CMAKE_PREFIX_PATH "${(0,d.nC)(s.b,(0,d.OZ)(s.b))}/TinyORM/TinyORM-builds-cmake/build-debug")`})}),(0,i.jsx)(o.A,{value:s.xj,label:s.gg,children:(0,i.jsx)(t.A,{className:"language-cmake",children:`# build tree\nlist(APPEND CMAKE_PREFIX_PATH "${(0,d.nC)(s.xj,(0,d.OZ)(s.xj))}/TinyORM/TinyORM-builds-cmake/build-debug")`})})]}),"\n",(0,i.jsxs)(n.p,{children:["You can use the ",(0,i.jsx)(n.a,{href:"https://cmake.org/cmake/help/latest/module/FetchContent.html",children:(0,i.jsx)(n.code,{children:"FetchContent"})})," module like in the following example."]}),"\n",(0,i.jsxs)(a.A,{groupId:s.vf,children:[(0,i.jsx)(o.A,{value:s.b,label:s.ux,children:(0,i.jsx)(t.A,{className:"language-cmake",children:"cmake_minimum_required(VERSION VERSION 3.22...3.29 FATAL_ERROR)\n\nproject(HelloWorld LANGUAGES CXX)\n\nset(CMAKE_CXX_STANDARD 20)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\nset(CMAKE_CXX_EXTENSIONS OFF)\n\n# FetchContent method\ninclude(FetchContent)\nFetchContent_Declare(TinyOrm\n GIT_REPOSITORY https://github.com/silverqx/TinyORM.git\n GIT_TAG origin/main\n OVERRIDE_FIND_PACKAGE\n)\n# Here you can configure TinyORM CMake options\nset(MYSQL_PING OFF)\nset(TOM_EXAMPLE ON)\n\nadd_executable(HelloWorld\n main.cpp\n)\n\nfind_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)\nfind_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)\nfind_package(TinyOrm 0.37.3 CONFIG REQUIRED)\n\ntarget_link_libraries(HelloWorld\n PRIVATE\n Qt${QT_VERSION_MAJOR}::Core\n TinyOrm::TinyOrm\n)"})}),(0,i.jsx)(o.A,{value:s.xj,label:s.gg,children:(0,i.jsx)(t.A,{className:"language-cmake",children:"cmake_minimum_required(VERSION VERSION 3.22...3.29 FATAL_ERROR)\n\nproject(HelloWorld LANGUAGES CXX)\n\nset(CMAKE_CXX_STANDARD 20)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\nset(CMAKE_CXX_EXTENSIONS OFF)\n\n# FetchContent method\ninclude(FetchContent)\nFetchContent_Declare(TinyOrm\n GIT_REPOSITORY https://github.com/silverqx/TinyORM.git\n GIT_TAG origin/main\n OVERRIDE_FIND_PACKAGE\n)\n# Here you can configure TinyORM CMake options\nset(MYSQL_PING OFF)\nset(TOM_EXAMPLE ON)\n\nadd_executable(HelloWorld\n main.cpp\n)\n\nfind_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)\nfind_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)\nfind_package(TinyOrm 0.37.3 CONFIG REQUIRED)\n\ntarget_link_libraries(HelloWorld\n PRIVATE\n Qt${QT_VERSION_MAJOR}::Core\n TinyOrm::TinyOrm\n)"})})]}),"\n",(0,i.jsx)(n.h4,{id:"how-fetchcontent-module-works",children:"How FetchContent module works"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"FetchContent_Declare"})," command is like calling the git clone inside the build folder and then adding a cloned folder in a similar way as the ",(0,i.jsx)(n.code,{children:"add_subdirectory()"})," command does."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"FetchContent_MakeAvailable()"})," internally calls the ",(0,i.jsx)(n.code,{children:"find_package()"})," command or if you pass the ",(0,i.jsx)(n.code,{children:"OVERRIDE_FIND_PACKAGE"})," argument, then you don't have to call the the ",(0,i.jsx)(n.code,{children:"FetchContent_MakeAvailable"}),", but you must call the ",(0,i.jsx)(n.code,{children:"find_package( x.y.z CONFIG REQUIRED)"})," command manually."]}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsxs)(n.p,{children:["An advantage of the ",(0,i.jsx)(n.code,{children:"OVERRIDE_FIND_PACKAGE"})," argument is that you can call the ",(0,i.jsx)(n.code,{children:"find_package"})," command much later, and you can insert additional configurations between."]})}),"\n",(0,i.jsx)(n.h3,{id:"build-hello-world-cmake",children:"Build Hello world"}),"\n",(0,i.jsxs)(n.p,{children:["Now you are ready to configure ",(0,i.jsx)(n.code,{children:"HelloWorld"})," ",(0,i.jsx)(n.code,{children:"CMake"})," application."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"cd ../HelloWorld-builds-cmake/build-debug\n"})}),"\n",(0,i.jsxs)(a.A,{groupId:s.vf,children:[(0,i.jsx)(o.A,{value:s.b,label:s.ux,children:(0,i.jsx)(t.A,{className:"language-powershell",children:`cmake.exe \`\n-S "${(0,d.OZ)(s.b)}/HelloWorld/HelloWorld" \`\n-B "${(0,d.OZ)(s.b)}/HelloWorld/HelloWorld-builds-cmake/build-debug" \`\n-G 'Ninja' \`\n-D CMAKE_BUILD_TYPE:STRING='Debug' \`\n-D CMAKE_TOOLCHAIN_FILE:FILEPATH="${(0,d.Sn)(s.b)}/vcpkg/scripts/buildsystems/vcpkg.cmake" \`\n-D CMAKE_CXX_SCAN_FOR_MODULES:BOOL=OFF \`\n-D CMAKE_INSTALL_PREFIX:PATH="${(0,d.Sn)(s.b)}/tmp/HelloWorld"`})}),(0,i.jsx)(o.A,{value:s.xj,label:s.gg,children:(0,i.jsx)(t.A,{className:"language-bash",children:`cmake \\\n-S "${(0,d.OZ)(s.xj)}/HelloWorld/HelloWorld" \\\n-B "${(0,d.OZ)(s.xj)}/HelloWorld/HelloWorld-builds-cmake/build-debug" \\\n-G 'Ninja' \\\n-D CMAKE_BUILD_TYPE:STRING='Debug' \\\n-D CMAKE_TOOLCHAIN_FILE:FILEPATH="${(0,d.Sn)(s.xj)}/vcpkg/scripts/buildsystems/vcpkg.cmake" \\\n-D CMAKE_CXX_SCAN_FOR_MODULES:BOOL=OFF \\\n-D CMAKE_INSTALL_PREFIX:PATH="${(0,d.Sn)(s.xj)}/tmp/TinyORM"`})})]}),"\n",(0,i.jsx)(n.p,{children:"And build."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"cmake --build . --target all\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["Enable the ",(0,i.jsx)(n.a,{href:"/building/tinyorm#cmake-strict_mode-option",children:(0,i.jsx)(n.code,{children:"TINYORM_STRICT_MODE"})})," environment variable to produce better code and to follow good code practices."]})}),"\n",(0,i.jsx)(n.h3,{id:"execute-hello-world-cmake",children:"Execute Hello world"}),"\n",(0,i.jsxs)(n.p,{children:["Do not forget to add ",(0,i.jsx)(n.code,{children:"TinyOrm0d.dll"})," on the path on Windows and on the ",(0,i.jsx)(n.code,{children:"LD_LIBRARY_PATH"})," on Linux, so ",(0,i.jsx)(n.code,{children:"HelloWorld"})," application can find it during execution, as is described ",(0,i.jsx)(n.a,{href:"/building/tinyorm#tinyorm-on-path-cmake",children:"here"}),"."]}),"\n",(0,i.jsxs)(a.A,{groupId:s.vf,name:"tinyorm-on-path",children:[(0,i.jsx)(o.A,{value:s.b,label:s.ux,children:(0,i.jsx)(t.A,{className:"language-powershell",children:`$env:Path = "${(0,d.OZ)(s.b,!1)}\\TinyORM\\TinyORM-builds-cmake\\build-debug;" + $env:Path`})}),(0,i.jsx)(o.A,{value:s.xj,label:s.gg,children:(0,i.jsx)(t.A,{className:"language-bash",children:`export LD_LIBRARY_PATH=${(0,d.OZ)(s.xj)}/TinyORM/TinyORM-builds-cmake/build-debug\${PATH:+:}$PATH`})})]}),"\n",(0,i.jsxs)(n.p,{children:["Execute ",(0,i.jsx)(n.code,{children:"HelloWorld"})," example."]}),"\n",(0,i.jsxs)(a.A,{groupId:s.vf,children:[(0,i.jsx)(o.A,{value:s.b,label:s.ux,children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-powershell",children:".\\HelloWorld.exe\n"})})}),(0,i.jsx)(o.A,{value:s.xj,label:s.gg,children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"./HelloWorld\n"})})})]}),"\n",(0,i.jsx)(n.p,{children:"The output will look like this."}),"\n",(0,i.jsx)(t.A,{className:"language-less",children:'Executed prepared query (6ms, -1 results, 0 affected, tinyorm_default) : select * from posts\n1 "First Post"\n2 "Second Post"'}),"\n",(0,i.jsx)(n.h2,{id:"hello-world-with-qmake",children:"Hello world with qmake"}),"\n",(0,i.jsxs)(n.p,{children:["Create a folder for the ",(0,i.jsx)(n.code,{children:"qmake"})," build."]}),"\n",(0,i.jsxs)(a.A,{groupId:s.vf,children:[(0,i.jsx)(o.A,{value:s.b,label:s.ux,children:(0,i.jsx)(t.A,{className:"language-powershell",children:`cd ${(0,d.OZ)(s.b)}/HelloWorld\n\nmkdir HelloWorld-builds-qmake`})}),(0,i.jsx)(o.A,{value:s.xj,label:s.gg,children:(0,i.jsx)(t.A,{className:"language-bash",children:`cd ${(0,d.OZ)(s.xj)}/HelloWorld\n\nmkdir HelloWorld-builds-qmake`})})]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.a,{href:"#source-code",children:(0,i.jsx)(n.code,{children:"source code"})})," is the same as for the ",(0,i.jsx)(n.code,{children:"HelloWorld CMake"})," example."]}),"\n",(0,i.jsx)(n.h3,{id:"qmake-project",children:"qmake project"}),"\n",(0,i.jsxs)(n.p,{children:["Create ",(0,i.jsx)(n.code,{children:"HelloWorld.pro"})," qmake file with the following content."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"cd HelloWorld\nvim HelloWorld.pro\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["To paste a source code correctly in ",(0,i.jsx)(n.code,{children:"vim"}),", press ",(0,i.jsx)("kbd",{children:"Shift"})," + ",(0,i.jsx)("kbd",{children:"p"}),"."]})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-qmake",metastring:"title='HelloWorld.pro'",children:"QT -= gui\n\nTEMPLATE = app\n\nCONFIG *= cmdline\n\nDEFINES *= PROJECT_TINYORM_HELLOWORLD\n\nSOURCES += $$PWD/main.cpp\n\n# Auto-configure TinyORM library \ud83d\udd25\ninclude($$TINY_MAIN_DIR/TinyORM/qmake/TinyOrm.pri)\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"warning",children:(0,i.jsxs)(n.p,{children:["The exact ",(0,i.jsx)(n.a,{href:"/building/tinyorm#folders-structure",children:"folders structure"})," is crucial in this example because the paths to the ",(0,i.jsx)(n.code,{children:"TinyORM"})," source and build folders are relative."]})}),"\n",(0,i.jsx)(n.admonition,{type:"warning",children:(0,i.jsx)(n.p,{children:"Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!"})}),"\n",(0,i.jsxs)(n.h4,{id:"auto-configure-using-qmake_conf-and-env",children:[(0,i.jsx)(n.code,{children:"Auto-configure"})," using ",(0,i.jsx)(n.code,{children:".qmake.conf"})," and ",(0,i.jsx)(n.code,{children:".env"})]}),"\n",(0,i.jsxs)(n.p,{children:["If you want to have properly configured ",(0,i.jsx)(n.code,{children:"DEFINES"})," (C preprocessor macros) or have Qt headers marked as system headers, then you need to specify a path to the ",(0,i.jsx)(n.code,{children:"TinyORM"})," qmake features (",(0,i.jsx)(n.code,{children:".prf"})," files) which handle this correctly; this path is provided by the ",(0,i.jsx)(n.code,{children:"QMAKEFEATURES"})," variable and can only be set in the ",(0,i.jsx)(n.code,{children:".qmake.conf"})," file."]}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["Read the ",(0,i.jsx)(n.a,{href:"/building/tinyorm#consume-tinyorm-library-qmake",children:"Consume TinyOrm library (qmake)"})," section, as everything that is described in that section applies here as well."]})}),"\n",(0,i.jsxs)(n.p,{children:["Create the ",(0,i.jsx)(n.code,{children:".qmake.conf"})," file in the ",(0,i.jsx)(n.code,{children:"HelloWorld"})," project root folder with the following content."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-qmake",metastring:"title='.qmake.conf'",children:"# Path to the PARENT folder of the TinyORM source folder\nTINY_MAIN_DIR = $$clean_path($$PWD/../../TinyORM/)\n# To find .env and .env.$$QMAKE_PLATFORM files\nTINY_DOTENV_ROOT = $$PWD\n# Path to the current build tree (used to guess the TinyORM build tree)\n#TINY_BUILD_TREE = $$shadowed($$PWD)\n\n# To find .prf files, needed by eg. CONFIG += tiny_system_headers inline/extern_constants\nQMAKEFEATURES *= $$quote($$TINY_MAIN_DIR/TinyORM/qmake/features)\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Then, create a ",(0,i.jsx)("code",{children:".env.(win32|unix|mingw)"})," file in the ",(0,i.jsx)(n.code,{children:"HelloWorld"})," project root folder with the following content."]}),"\n",(0,i.jsxs)(a.A,{groupId:s.vf,children:[(0,i.jsx)(o.A,{value:s.b,label:".env.win32",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-qmake",children:"# Names and values of these qmake variables are crucial, they are used in HelloWorld.pro\n# Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!\n\n# Path to the TinyORM build folder\nTINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_1_MSVC2022_64bit-Debug/)\n\n# Path to the vcpkg - range-v3\n# Will use the TINY_VCPKG_ROOT or VCPKG_ROOT environment variable if is empty\nTINY_VCPKG_ROOT = $$clean_path($$PWD/../../../vcpkg/)\nTINY_VCPKG_TRIPLET = x64-windows\n\n# Enable ccache wrapper\n#CONFIG *= tiny_ccache_win32\n"})})}),(0,i.jsx)(o.A,{value:s.xj,label:".env.unix",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-qmake",children:"# Names and values of these qmake variables are crucial, they are used in HelloWorld.pro\n# Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!\n\n# Path to the TinyORM build folder\nTINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_1_clang16_64bit_ccache-Debug/)\n\n# Path to the vcpkg - range-v3\n# Will use the TINY_VCPKG_ROOT or VCPKG_ROOT environment variable if is empty\nTINY_VCPKG_ROOT = $$clean_path($$PWD/../../../vcpkg/)\nTINY_VCPKG_TRIPLET = x64-linux\n\n# Use faster linker\nclang: CONFIG *= use_lld_linker\nelse: CONFIG *= use_gold_linker\n\n# Or use the mold linker\n#QMAKE_LFLAGS *= -fuse-ld=mold\n"})})}),(0,i.jsx)(o.A,{value:"mingw",label:".env.mingw",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-qmake",children:"# Names and values of these qmake variables are crucial, they are used in HelloWorld.pro\n# Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!\n\n# Path to the TinyORM build folder\nTINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_1_MSYS2_UCRT64_clang_64bit-Debug/)\n\n# Path to the vcpkg - range-v3\n# Will use the TINY_VCPKG_ROOT or VCPKG_ROOT environment variable if is empty\nTINY_VCPKG_ROOT = $$clean_path($$PWD/../../../vcpkg/)\nTINY_VCPKG_TRIPLET = x64-mingw-dynamic\n\n# Enable ccache wrapper\n#CONFIG *= tiny_ccache_win32\n\n# Use faster linker (for both GCC and Clang)\n# CONFIG *= use_lld_linker does not work on MinGW\nQMAKE_LFLAGS *= -fuse-ld=lld\n"})})})]}),"\n",(0,i.jsxs)(n.p,{children:["Don't forget to update the ",(0,i.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})," and ",(0,i.jsx)(n.code,{children:"TINY_VCPKG_ROOT"})," folder paths to your needs if you are not using the recommended ",(0,i.jsx)(n.a,{href:"/building/tinyorm#folders-structure",children:(0,i.jsx)(n.code,{children:"Folders structure"})}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["You can use the ",(0,i.jsxs)(n.a,{href:"/building/tinyorm#partial-guessing-of-the-tinyorm_build_tree",children:["Partial guessing of the ",(0,i.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})]})," if you don't like to specify it manually. Just comment out the ",(0,i.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})," and uncomment the ",(0,i.jsx)(n.code,{children:"TINY_BUILD_TREE = $$shadowed($$PWD)"})," in the ",(0,i.jsx)(n.code,{children:".qmake.conf"})," file."]}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["You can entirely avoid the ",(0,i.jsx)(n.code,{children:".env"})," files, just move the ",(0,i.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})," to the ",(0,i.jsx)(n.code,{children:".qmake.conf"})," or remove it by help of ",(0,i.jsxs)(n.a,{href:"/building/tinyorm#partial-guessing-of-the-tinyorm_build_tree",children:["Partial guessing of the ",(0,i.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})]})," and set the ",(0,i.jsx)(n.code,{children:"VCPKG_ROOT"})," environment variable at system level as is described in ",(0,i.jsx)(n.a,{href:"/building/tinyorm#set-up-vcpkg-environment",children:(0,i.jsx)(n.code,{children:"Set up vcpkg environment"})}),"."]})}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsxs)(n.p,{children:["Configuring by the ",(0,i.jsx)(n.code,{children:".qmake.conf"})," and ",(0,i.jsx)(n.code,{children:".env"})," files has one big advantage, which is that you don't have to modify the project files."]})}),"\n",(0,i.jsx)(n.h3,{id:"build-hello-world-qmake",children:"Build Hello world"}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["I recommend creating a new ",(0,i.jsx)(n.code,{children:"Session"})," in the ",(0,i.jsx)(n.code,{children:"QtCreator IDE"})," as is described ",(0,i.jsx)(n.a,{href:"/building/tinyorm#open-qtcreator-ide",children:"here"}),"."]})}),"\n",(0,i.jsxs)(n.p,{children:["Now you can open the ",(0,i.jsx)(n.code,{children:"HelloWorld.pro"})," project in the ",(0,i.jsx)(n.code,{children:"QtCreator IDE"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["This will open the ",(0,i.jsx)(n.code,{children:"Configure Project"})," tab, select some kit and update build folder paths to meet our ",(0,i.jsx)(n.a,{href:"/building/tinyorm#folders-structure",children:"folders structure"})," or like you want."]}),"\n",(0,i.jsx)("img",{src:l(3180).A,alt:"HelloWorld - QtCreator - Configure Project",width:"760"}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["You can force the ",(0,i.jsx)(n.code,{children:"QtCreator"})," to generate a build folders structure as is described ",(0,i.jsx)(n.a,{href:"/building/tinyorm#qtcreator-default-build-directory",children:"here"}),"."]})}),"\n",(0,i.jsxs)(n.p,{children:["You are ready to configure build options, hit ",(0,i.jsx)("kbd",{children:"Ctrl"}),"+",(0,i.jsx)("kbd",{children:"5"})," to open ",(0,i.jsx)(n.code,{children:"Project Settings"})," tab and select ",(0,i.jsx)(n.code,{children:"Build"})," in the left sidebar to open the ",(0,i.jsx)(n.code,{children:"Build Settings"}),", it should look similar to the following picture."]}),"\n",(0,i.jsx)("img",{src:l(7028).A,className:"no-blurry",alt:"HelloWorld - QtCreator - Build Settings",width:"760"}),"\n",(0,i.jsxs)(n.p,{children:["Disable ",(0,i.jsx)(n.code,{children:"QML debugging and profiling"})," and ",(0,i.jsx)(n.code,{children:"Qt Quick Compiler"}),", they are not used."]}),"\n",(0,i.jsxs)(n.p,{children:["In the left sidebar open ",(0,i.jsx)(n.code,{children:"Dependencies"})," and check ",(0,i.jsx)(n.code,{children:"TinyORM"})," project and ",(0,i.jsx)(n.code,{children:"Synchronize configuration"}),", this setting ensures that the current project will be rebuilt correctly when the ",(0,i.jsx)(n.code,{children:"TinyORM"})," library source code changes."]}),"\n",(0,i.jsxs)(n.p,{children:["Everything is ready to build, you can press ",(0,i.jsx)("kbd",{children:"Ctrl"}),"+",(0,i.jsx)("kbd",{children:"b"})," to build the project."]}),"\n",(0,i.jsx)(n.h3,{id:"execute-hello-world-qmake",children:"Execute Hello world"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"QtCreator"})," takes care of all the necessary configurations, sets up the build environment correctly, and also prepends dependency libraries on the system path on Windows and on the ",(0,i.jsx)(n.code,{children:"LD_LIBRARY_PATH"})," on Linux."]}),"\n",(0,i.jsxs)(n.p,{children:["The only thing you might want to change is to run the ",(0,i.jsx)(n.code,{children:"HelloWorld"})," example in the new terminal window. To do so, hit ",(0,i.jsx)("kbd",{children:"Ctrl"}),"+",(0,i.jsx)("kbd",{children:"5"})," to open the ",(0,i.jsx)(n.code,{children:"Project Settings"})," tab and select ",(0,i.jsx)(n.code,{children:"Run"})," in the left sidebar to open the ",(0,i.jsx)(n.code,{children:"Run Settings"}),", then in the ",(0,i.jsx)(n.code,{children:"Run"})," section select the ",(0,i.jsx)(n.code,{children:"Run in terminal"})," checkbox."]}),"\n",(0,i.jsxs)(n.p,{children:["To execute the ",(0,i.jsx)(n.code,{children:"HelloWorld"})," example press ",(0,i.jsx)("kbd",{children:"Ctrl"})," + ",(0,i.jsx)("kbd",{children:"r"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"The output will look like this."}),"\n",(0,i.jsx)(t.A,{className:"language-less",children:'Executed prepared query (6ms, -1 results, 0 affected, tinyorm_default) : select * from posts\n1 "First Post"\n2 "Second Post"'})]})}function j(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(x,{...e})}):x(e)}},9365:(e,n,l)=>{l.d(n,{A:()=>o});l(6540);var i=l(4164);const r={tabItem:"tabItem_Ymn6"};var t=l(4848);function o(e){let{children:n,hidden:l,className:o}=e;return(0,t.jsx)("div",{role:"tabpanel",className:(0,i.A)(r.tabItem,o),hidden:l,children:n})}},1470:(e,n,l)=>{l.d(n,{A:()=>y});var i=l(6540),r=l(4164),t=l(3104),o=l(6347),a=l(205),s=l(7485),d=l(1682),c=l(9466);function h(e){return i.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,i.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function u(e){const{values:n,children:l}=e;return(0,i.useMemo)((()=>{const e=n??function(e){return h(e).map((e=>{let{props:{value:n,label:l,attributes:i,default:r}}=e;return{value:n,label:l,attributes:i,default:r}}))}(l);return function(e){const n=(0,d.X)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[n,l])}function p(e){let{value:n,tabValues:l}=e;return l.some((e=>e.value===n))}function m(e){let{queryString:n=!1,groupId:l}=e;const r=(0,o.W6)(),t=function(e){let{queryString:n=!1,groupId:l}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!l)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return l??null}({queryString:n,groupId:l});return[(0,s.aZ)(t),(0,i.useCallback)((e=>{if(!t)return;const n=new URLSearchParams(r.location.search);n.set(t,e),r.replace({...r.location,search:n.toString()})}),[t,r])]}function x(e){const{defaultValue:n,queryString:l=!1,groupId:r}=e,t=u(e),[o,s]=(0,i.useState)((()=>function(e){let{defaultValue:n,tabValues:l}=e;if(0===l.length)throw new Error("Docusaurus error: the component requires at least one children component");if(n){if(!p({value:n,tabValues:l}))throw new Error(`Docusaurus error: The has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${l.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const i=l.find((e=>e.default))??l[0];if(!i)throw new Error("Unexpected error: 0 tabValues");return i.value}({defaultValue:n,tabValues:t}))),[d,h]=m({queryString:l,groupId:r}),[x,j]=function(e){let{groupId:n}=e;const l=function(e){return e?`docusaurus.tab.${e}`:null}(n),[r,t]=(0,c.Dv)(l);return[r,(0,i.useCallback)((e=>{l&&t.set(e)}),[l,t])]}({groupId:r}),g=(()=>{const e=d??x;return p({value:e,tabValues:t})?e:null})();(0,a.A)((()=>{g&&s(g)}),[g]);return{selectedValue:o,selectValue:(0,i.useCallback)((e=>{if(!p({value:e,tabValues:t}))throw new Error(`Can't select invalid tab value=${e}`);s(e),h(e),j(e)}),[h,j,t]),tabValues:t}}var j=l(2303);const g={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var b=l(4848);function f(e){let{className:n,block:l,selectedValue:i,selectValue:o,tabValues:a}=e;const s=[],{blockElementScrollPositionUntilNextRender:d}=(0,t.a_)(),c=e=>{const n=e.currentTarget,l=s.indexOf(n),r=a[l].value;r!==i&&(d(n),o(r))},h=e=>{let n=null;switch(e.key){case"Enter":c(e);break;case"ArrowRight":{const l=s.indexOf(e.currentTarget)+1;n=s[l]??s[0];break}case"ArrowLeft":{const l=s.indexOf(e.currentTarget)-1;n=s[l]??s[s.length-1];break}}n?.focus()};return(0,b.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,r.A)("tabs",{"tabs--block":l},n),children:a.map((e=>{let{value:n,label:l,attributes:t}=e;return(0,b.jsx)("li",{role:"tab",tabIndex:i===n?0:-1,"aria-selected":i===n,ref:e=>s.push(e),onKeyDown:h,onClick:c,...t,className:(0,r.A)("tabs__item",g.tabItem,t?.className,{"tabs__item--active":i===n}),children:l??n},n)}))})}function _(e){let{lazy:n,children:l,selectedValue:r}=e;const t=(Array.isArray(l)?l:[l]).filter(Boolean);if(n){const e=t.find((e=>e.props.value===r));return e?(0,i.cloneElement)(e,{className:"margin-top--md"}):null}return(0,b.jsx)("div",{className:"margin-top--md",children:t.map(((e,n)=>(0,i.cloneElement)(e,{key:n,hidden:e.props.value!==r})))})}function T(e){const n=x(e);return(0,b.jsxs)("div",{className:(0,r.A)("tabs-container",g.tabList),children:[(0,b.jsx)(f,{...n,...e}),(0,b.jsx)(_,{...n,...e})]})}function y(e){const n=(0,j.A)();return(0,b.jsx)(T,{...e,children:h(e.children)},String(n))}},7324:(e,n,l)=>{l.d(n,{$E:()=>j,A3:()=>b,CW:()=>g,Dx:()=>c,F4:()=>u,Fi:()=>d,J_:()=>y,LQ:()=>f,Lf:()=>k,OO:()=>r,Q7:()=>_,b:()=>a,cy:()=>s,gg:()=>m,kl:()=>p,os:()=>h,pW:()=>t,ux:()=>x,vf:()=>i,xj:()=>o,xt:()=>T});const i="shell",r="database",t="application",o="bash",a="pwsh",s="zsh",d="maria",c="mysql",h="postgres",u="sqlite",p="application",m="bash",x="pwsh",j="zsh",g="MariaDB",b="MySQL",f="PostgreSQL",_="SQLite",T="tinyorm.org",y="$HOME/Code/c/",k="$env:USERPROFILE\\Code\\c\\"},6362:(e,n,l)=>{l.d(n,{A:()=>t});var i=l(6540),r=l(1838);function t(){const e=(0,i.useContext)(r.A);if(null!=e)return e;throw new Error("useRootFolderContext is used outside of Layout component.")}},6694:(e,n,l)=>{l.d(n,{OZ:()=>s,Sn:()=>o,T3:()=>c,bw:()=>d,nC:()=>h,np:()=>a});var i=l(6362),r=l(2303),t=l(7324);const o=function(e,n){return void 0===n&&(n=!0),u((0,i.A)().rootFolder[e]??d(e),e,n)},a=()=>(0,i.A)().rootFolder[t.pW]??d(t.pW),s=function(e,n){if(void 0===n&&(n=!0),null==e)throw new Error("The groupId in the applicationFolderPath() can not be empty.");const l=n||e!==t.b?"/":"\\";return u(o(e)+l+a(),e,n)};function d(e){if(null==e)throw new Error("The groupId in the folderDefaultValue() can not be empty.");if(!(0,r.A)())return"";switch(e){case t.b:return t.Lf;case t.xj:return t.J_;case t.pW:return t.xt;default:throw new Error(`No default value for '${e}' groupId in the folderDefaultValue().`)}}function c(e){return e===t.pW}function h(e,n){if(null==n||""===n)return n;const l="$ENV{$1}$2";switch(e){case t.b:return m(n).replace(/\$env:(.+?)(\/.*)/,l);case t.xj:return n.replace(/\$(.+?)(\/.*)/,l);default:throw new Error(`Unsupported shell type '${e}' in the convertToCmakeEnvVariable().`)}}function u(e,n,l){if(void 0===l&&(l=!0),null==e||""===e)return e;if(n!==t.b)return p(e);const i=p(e);return l?m(i):function(e){return null==e||""===e?e:e.replaceAll(/\/+/g,"\\")}(i)}function p(e){return null==e||""===e?e:e.replace(/[/\\]+$/,"")}function m(e){return null==e||""===e?e:e.replaceAll(/\\+(?! )/g,"/")}},7028:(e,n,l)=>{l.d(n,{A:()=>i});const i=l.p+"assets/images/qmake-build_settings-ebdc6c0c056d11462096ff10cba682a1.png"},3180:(e,n,l)=>{l.d(n,{A:()=>i});const i=l.p+"assets/images/qmake-configure_project-8caf87e6af4452f0c28bd15c85c392fc.png"}}]); \ No newline at end of file diff --git a/assets/js/runtime~main.7897363c.js b/assets/js/runtime~main.b7a1387b.js similarity index 78% rename from assets/js/runtime~main.7897363c.js rename to assets/js/runtime~main.b7a1387b.js index dd8d1e853..ea5bdd27f 100644 --- a/assets/js/runtime~main.7897363c.js +++ b/assets/js/runtime~main.b7a1387b.js @@ -1 +1 @@ -(()=>{"use strict";var e,a,t,r,o,n={},f={};function c(e){var a=f[e];if(void 0!==a)return a.exports;var t=f[e]={exports:{}};return n[e].call(t.exports,t,t.exports,c),t.exports}c.m=n,e=[],c.O=(a,t,r,o)=>{if(!t){var n=1/0;for(i=0;i=o)&&Object.keys(c.O).every((e=>c.O[e](t[d])))?t.splice(d--,1):(f=!1,o0&&e[i-1][2]>o;i--)e[i]=e[i-1];e[i]=[t,r,o]},c.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return c.d(a,{a:a}),a},t=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,c.t=function(e,r){if(1&r&&(e=this(e)),8&r)return e;if("object"==typeof e&&e){if(4&r&&e.__esModule)return e;if(16&r&&"function"==typeof e.then)return e}var o=Object.create(null);c.r(o);var n={};a=a||[null,t({}),t([]),t(t)];for(var f=2&r&&e;"object"==typeof f&&!~a.indexOf(f);f=t(f))Object.getOwnPropertyNames(f).forEach((a=>n[a]=()=>e[a]));return n.default=()=>e,c.d(o,n),o},c.d=(e,a)=>{for(var t in a)c.o(a,t)&&!c.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:a[t]})},c.f={},c.e=e=>Promise.all(Object.keys(c.f).reduce(((a,t)=>(c.f[t](e,a),a)),[])),c.u=e=>"assets/js/"+({27:"d459b1c4",48:"a94703ab",69:"e19c288b",82:"5b254f70",98:"a7bd4aaa",117:"3dd307b5",129:"8a8faf8d",138:"1a4e3797",153:"1222ea4e",170:"ba3d4959",258:"cb1e72f9",295:"21dc2778",304:"62a1276f",395:"0ab078a9",401:"17896441",467:"e3ac21cb",485:"59b1a96c",638:"7333c691",647:"5e95c892",742:"aba21aa0",755:"a4d3e054",820:"6629c45f",871:"fb313d4e",957:"c141421f",983:"feaee7f3",995:"cbe663fe"}[e]||e)+"."+{27:"8b2acd7f",48:"29c38115",69:"cae4e49f",82:"dec04c5b",98:"80cc43c0",117:"7d5f3256",129:"488a21d5",138:"0583fddb",153:"2cd8af81",170:"0c16349a",237:"d109f2ba",258:"f05e497e",295:"95e24d3c",304:"87749e65",395:"4772f861",401:"6473f609",416:"a3ad28f7",446:"d7af1da2",462:"0011555c",467:"482bbcbf",485:"35b999b1",638:"02799d7f",647:"7024aad0",742:"cb1d9d7d",755:"fedc061b",820:"77316fdc",871:"1478a8fb",913:"3fa60236",957:"2356f0d5",983:"0f0c7251",995:"160e49aa"}[e]+".js",c.miniCssF=e=>{},c.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),c.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),r={},o="tinyorm.org:",c.l=(e,a,t,n)=>{if(r[e])r[e].push(a);else{var f,d;if(void 0!==t)for(var b=document.getElementsByTagName("script"),i=0;i{f.onerror=f.onload=null,clearTimeout(s);var o=r[e];if(delete r[e],f.parentNode&&f.parentNode.removeChild(f),o&&o.forEach((e=>e(t))),a)return a(t)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:f}),12e4);f.onerror=l.bind(null,f.onerror),f.onload=l.bind(null,f.onload),d&&document.head.appendChild(f)}},c.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},c.p="/",c.gca=function(e){return e={17896441:"401",d459b1c4:"27",a94703ab:"48",e19c288b:"69","5b254f70":"82",a7bd4aaa:"98","3dd307b5":"117","8a8faf8d":"129","1a4e3797":"138","1222ea4e":"153",ba3d4959:"170",cb1e72f9:"258","21dc2778":"295","62a1276f":"304","0ab078a9":"395",e3ac21cb:"467","59b1a96c":"485","7333c691":"638","5e95c892":"647",aba21aa0:"742",a4d3e054:"755","6629c45f":"820",fb313d4e:"871",c141421f:"957",feaee7f3:"983",cbe663fe:"995"}[e]||e,c.p+c.u(e)},(()=>{var e={354:0,869:0};c.f.j=(a,t)=>{var r=c.o(e,a)?e[a]:void 0;if(0!==r)if(r)t.push(r[2]);else if(/^(354|869)$/.test(a))e[a]=0;else{var o=new Promise(((t,o)=>r=e[a]=[t,o]));t.push(r[2]=o);var n=c.p+c.u(a),f=new Error;c.l(n,(t=>{if(c.o(e,a)&&(0!==(r=e[a])&&(e[a]=void 0),r)){var o=t&&("load"===t.type?"missing":t.type),n=t&&t.target&&t.target.src;f.message="Loading chunk "+a+" failed.\n("+o+": "+n+")",f.name="ChunkLoadError",f.type=o,f.request=n,r[1](f)}}),"chunk-"+a,a)}},c.O.j=a=>0===e[a];var a=(a,t)=>{var r,o,n=t[0],f=t[1],d=t[2],b=0;if(n.some((a=>0!==e[a]))){for(r in f)c.o(f,r)&&(c.m[r]=f[r]);if(d)var i=d(c)}for(a&&a(t);b{"use strict";var e,a,t,r,o,n={},f={};function c(e){var a=f[e];if(void 0!==a)return a.exports;var t=f[e]={exports:{}};return n[e].call(t.exports,t,t.exports,c),t.exports}c.m=n,e=[],c.O=(a,t,r,o)=>{if(!t){var n=1/0;for(i=0;i=o)&&Object.keys(c.O).every((e=>c.O[e](t[b])))?t.splice(b--,1):(f=!1,o0&&e[i-1][2]>o;i--)e[i]=e[i-1];e[i]=[t,r,o]},c.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return c.d(a,{a:a}),a},t=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,c.t=function(e,r){if(1&r&&(e=this(e)),8&r)return e;if("object"==typeof e&&e){if(4&r&&e.__esModule)return e;if(16&r&&"function"==typeof e.then)return e}var o=Object.create(null);c.r(o);var n={};a=a||[null,t({}),t([]),t(t)];for(var f=2&r&&e;"object"==typeof f&&!~a.indexOf(f);f=t(f))Object.getOwnPropertyNames(f).forEach((a=>n[a]=()=>e[a]));return n.default=()=>e,c.d(o,n),o},c.d=(e,a)=>{for(var t in a)c.o(a,t)&&!c.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:a[t]})},c.f={},c.e=e=>Promise.all(Object.keys(c.f).reduce(((a,t)=>(c.f[t](e,a),a)),[])),c.u=e=>"assets/js/"+({27:"d459b1c4",48:"a94703ab",69:"e19c288b",82:"5b254f70",98:"a7bd4aaa",117:"3dd307b5",129:"8a8faf8d",138:"1a4e3797",153:"1222ea4e",170:"ba3d4959",258:"cb1e72f9",295:"21dc2778",304:"62a1276f",395:"0ab078a9",401:"17896441",467:"e3ac21cb",485:"59b1a96c",638:"7333c691",647:"5e95c892",742:"aba21aa0",755:"a4d3e054",820:"6629c45f",871:"fb313d4e",957:"c141421f",983:"feaee7f3",995:"cbe663fe"}[e]||e)+"."+{27:"8b2acd7f",48:"29c38115",69:"cae4e49f",82:"dec04c5b",98:"80cc43c0",117:"7d5f3256",129:"2e50ae37",138:"0583fddb",153:"2cd8af81",170:"0c16349a",237:"d109f2ba",258:"f05e497e",295:"95e24d3c",304:"87749e65",395:"3d783b04",401:"6473f609",416:"a3ad28f7",446:"d7af1da2",462:"0011555c",467:"482bbcbf",485:"35b999b1",638:"02799d7f",647:"7024aad0",742:"cb1d9d7d",755:"fedc061b",820:"77316fdc",871:"1478a8fb",913:"3fa60236",957:"2356f0d5",983:"956a0aab",995:"160e49aa"}[e]+".js",c.miniCssF=e=>{},c.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),c.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),r={},o="tinyorm.org:",c.l=(e,a,t,n)=>{if(r[e])r[e].push(a);else{var f,b;if(void 0!==t)for(var d=document.getElementsByTagName("script"),i=0;i{f.onerror=f.onload=null,clearTimeout(s);var o=r[e];if(delete r[e],f.parentNode&&f.parentNode.removeChild(f),o&&o.forEach((e=>e(t))),a)return a(t)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:f}),12e4);f.onerror=l.bind(null,f.onerror),f.onload=l.bind(null,f.onload),b&&document.head.appendChild(f)}},c.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},c.p="/",c.gca=function(e){return e={17896441:"401",d459b1c4:"27",a94703ab:"48",e19c288b:"69","5b254f70":"82",a7bd4aaa:"98","3dd307b5":"117","8a8faf8d":"129","1a4e3797":"138","1222ea4e":"153",ba3d4959:"170",cb1e72f9:"258","21dc2778":"295","62a1276f":"304","0ab078a9":"395",e3ac21cb:"467","59b1a96c":"485","7333c691":"638","5e95c892":"647",aba21aa0:"742",a4d3e054:"755","6629c45f":"820",fb313d4e:"871",c141421f:"957",feaee7f3:"983",cbe663fe:"995"}[e]||e,c.p+c.u(e)},(()=>{var e={354:0,869:0};c.f.j=(a,t)=>{var r=c.o(e,a)?e[a]:void 0;if(0!==r)if(r)t.push(r[2]);else if(/^(354|869)$/.test(a))e[a]=0;else{var o=new Promise(((t,o)=>r=e[a]=[t,o]));t.push(r[2]=o);var n=c.p+c.u(a),f=new Error;c.l(n,(t=>{if(c.o(e,a)&&(0!==(r=e[a])&&(e[a]=void 0),r)){var o=t&&("load"===t.type?"missing":t.type),n=t&&t.target&&t.target.src;f.message="Loading chunk "+a+" failed.\n("+o+": "+n+")",f.name="ChunkLoadError",f.type=o,f.request=n,r[1](f)}}),"chunk-"+a,a)}},c.O.j=a=>0===e[a];var a=(a,t)=>{var r,o,n=t[0],f=t[1],b=t[2],d=0;if(n.some((a=>0!==e[a]))){for(r in f)c.o(f,r)&&(c.m[r]=f[r]);if(b)var i=b(c)}for(a&&a(t);dgtag("config","AW-989655383"),gtag("event","conversion",{send_to:"AW-989655383/vDYzCM--ks4DENfi89cD"}) - + @@ -121,7 +121,7 @@

.qmake.conf
# Path to the PARENT folder of the TinyORM source folder
TINY_MAIN_DIR = $$clean_path($$PWD/../../TinyORM/)
# To find .env and .env.$$QMAKE_PLATFORM files
TINY_DOTENV_ROOT = $$PWD
# Path to the current build tree (used to guess the TinyORM build tree)
#TINY_BUILD_TREE = $$shadowed($$PWD)

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

Then, create a .env.(win32|unix|mingw) file in the HelloWorld project root folder with the following content.

-
# Names and values of these qmake variables are crucial, they are used in HelloWorld.pro
# Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!

# Path to the TinyORM build folder
TINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_0_MSVC2022_64bit-Debug/)

# Path to the vcpkg - range-v3
# Will use the TINY_VCPKG_ROOT or VCPKG_ROOT environment variable if is empty
TINY_VCPKG_ROOT = $$clean_path($$PWD/../../../vcpkg/)
TINY_VCPKG_TRIPLET = x64-windows

# Enable ccache wrapper
#CONFIG *= tiny_ccache_win32
+
# Names and values of these qmake variables are crucial, they are used in HelloWorld.pro
# Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!

# Path to the TinyORM build folder
TINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_1_MSVC2022_64bit-Debug/)

# Path to the vcpkg - range-v3
# Will use the TINY_VCPKG_ROOT or VCPKG_ROOT environment variable if is empty
TINY_VCPKG_ROOT = $$clean_path($$PWD/../../../vcpkg/)
TINY_VCPKG_TRIPLET = x64-windows

# Enable ccache wrapper
#CONFIG *= tiny_ccache_win32

Don't forget to update the TINYORM_BUILD_TREE and TINY_VCPKG_ROOT folder paths to your needs if you are not using the recommended Folders structure.

You can use the Partial guessing of the TINYORM_BUILD_TREE if you don't like to specify it manually. Just comment out the TINYORM_BUILD_TREE and uncomment the TINY_BUILD_TREE = $$shadowed($$PWD) in the .qmake.conf file.

tip

You can entirely avoid the .env files, just move the TINYORM_BUILD_TREE to the .qmake.conf or remove it by help of Partial guessing of the TINYORM_BUILD_TREE and set the VCPKG_ROOT environment variable at system level as is described in Set up vcpkg environment.

diff --git a/building/migrations.html b/building/migrations.html index 1c02b0bd5..90876744b 100644 --- a/building/migrations.html +++ b/building/migrations.html @@ -14,7 +14,7 @@ - + @@ -142,7 +142,7 @@

.qmake.conf
# Path to the PARENT folder of the TinyORM source folder
TINY_MAIN_DIR = $$clean_path($$PWD/../../TinyORM/)
# To find .env and .env.$$QMAKE_PLATFORM files
TINY_DOTENV_ROOT = $$PWD
# Path to the current build tree (used to guess the TinyORM build tree)
#TINY_BUILD_TREE = $$shadowed($$PWD)

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

Then, create a .env.(win32|unix|mingw) file in the tom application root folder with the following content.

-
# Names and values of these qmake variables are crucial, they are used in the tom.pro
# Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!

# Path to the TinyORM build folder
TINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_0_MSVC2022_64bit-Debug/)

# Path to the vcpkg - range-v3 and tabulate
# Will use the TINY_VCPKG_ROOT or VCPKG_ROOT environment variable if is empty
TINY_VCPKG_ROOT = $$clean_path($$PWD/../../../vcpkg/)
TINY_VCPKG_TRIPLET = x64-windows

# Enable ccache wrapper
#CONFIG *= tiny_ccache_win32
+
# Names and values of these qmake variables are crucial, they are used in the tom.pro
# Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!

# Path to the TinyORM build folder
TINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_1_MSVC2022_64bit-Debug/)

# Path to the vcpkg - range-v3 and tabulate
# Will use the TINY_VCPKG_ROOT or VCPKG_ROOT environment variable if is empty
TINY_VCPKG_ROOT = $$clean_path($$PWD/../../../vcpkg/)
TINY_VCPKG_TRIPLET = x64-windows

# Enable ccache wrapper
#CONFIG *= tiny_ccache_win32

Don't forget to update the TINYORM_BUILD_TREE and TINY_VCPKG_ROOT folder paths to your needs if you are not using the recommended Folders structure.

You can use the Partial guessing of the TINYORM_BUILD_TREE if you don't like to specify it manually. Just comment out the TINYORM_BUILD_TREE and uncomment the TINY_BUILD_TREE = $$shadowed($$PWD) in the .qmake.conf file.

tip

You can entirely avoid the .env files, just move the TINYORM_BUILD_TREE to the .qmake.conf or remove it by help of Partial guessing of the TINYORM_BUILD_TREE and set the VCPKG_ROOT environment variable at system level as is described in Set up vcpkg environment.

diff --git a/building/tinyorm.html b/building/tinyorm.html index a862d82a4..c19df3df5 100644 --- a/building/tinyorm.html +++ b/building/tinyorm.html @@ -14,7 +14,7 @@ - + @@ -64,9 +64,9 @@

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.

-
#!/usr/bin/env pwsh

Set-StrictMode -Version 3.0

Write-Host 'Setting up environment for Qt 6.7.0 usage...' -ForegroundColor Magenta
Write-Host

$Script:QtRoot = $env:TINY_QT_ROOT ?? 'C:\Qt'

$env:Path = "$Script:QtRoot\6.7.0\msvc2019_64\bin;" + $env:Path

. vcvars64.ps1
+
#!/usr/bin/env pwsh

Set-StrictMode -Version 3.0

Write-Host 'Setting up environment for Qt 6.7.1 usage...' -ForegroundColor Magenta
Write-Host

$Script:QtRoot = $env:TINY_QT_ROOT ?? 'C:\Qt'

$env:Path = "$Script:QtRoot\6.7.1\msvc2019_64\bin;" + $env:Path

. vcvars64.ps1

And here for Linux.

-
#!/usr/bin/env sh

echo 'Setting up environment for Qt 6.7.0 usage...'

QtRoot="${TINY_QT_ROOT:-/opt/Qt}"

export PATH="$QtRoot/6.7.0/gcc_64/bin"${PATH:+:}$PATH
export LD_LIBRARY_PATH="$QtRoot/6.7.0/gcc_64/lib"${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH
+
#!/usr/bin/env sh

echo 'Setting up environment for Qt 6.7.1 usage...'

QtRoot="${TINY_QT_ROOT:-/opt/Qt}"

export PATH="$QtRoot/6.7.1/gcc_64/bin"${PATH:+:}$PATH
export LD_LIBRARY_PATH="$QtRoot/6.7.1/gcc_64/lib"${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH
info

These scripts consider the TINY_QT_ROOT environment variable that should point to the Qt installation folder, you can define this environment variable globally in your OS.

info

You can't execute these qtenvX scripts, they have to be sourced like source qtenvX or . qtenvX.

@@ -75,15 +75,15 @@

Fold

All tinyorm.org examples are based on the following folders structure. The tom folder will contain a migrations console application.

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.

Current pwsh path 




├──
│ ├── 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_7_0_MSVC2019_64bit-Debug/
│ └── tom-builds-qmake/
│ ├── build-TinyORM-Desktop_Qt_5_15_3_MSYS2_UCRT64_64bit-Release/
│ └── build-TinyORM-Desktop_Qt_6_7_0_MSVC2019_64bit-Debug/
├── tmp/
└── vcpkg/
+This folder name is common for all shells (eg. pwsh, bash, ...)">



├──
│ ├── 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_7_1_MSVC2019_64bit-Debug/
│ └── tom-builds-qmake/
│ ├── build-TinyORM-Desktop_Qt_5_15_3_MSYS2_UCRT64_64bit-Release/
│ └── build-TinyORM-Desktop_Qt_6_7_1_MSVC2019_64bit-Debug/
├── tmp/
└── vcpkg/
danger

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

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:
../%{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.

-
mkdir 
cd
$env:Path = 'C:\Qt\6.7.0\msvc2019_64\bin;' + $env:Path
vcvars64.ps1
+
mkdir 
cd
$env:Path = 'C:\Qt\6.7.1\msvc2019_64\bin;' + $env:Path
vcvars64.ps1
tip

You can also use the tools/Add-FolderOnPath.ps1 pwsh script to fastly prepend a path or pwd on the system PATH.

vcpkg

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

@@ -208,7 +208,7 @@

Requireme

Let's explain one by one.

QMAKEFEATURES

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

-
.qmake.conf
# 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_7_0_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)
+
.qmake.conf
# 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_7_1_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 feature by default.

You can look at the 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 if you don't like to specify it manually.

@@ -216,14 +216,14 @@
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.

-
# 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_7_0_MSVC2019_64bit-Debug/src$${TINY_BUILD_SUBFOLDER}/)
LIBS += -lTinyOrm
+
# 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_7_1_MSVC2019_64bit-Debug/src$${TINY_BUILD_SUBFOLDER}/)
LIBS += -lTinyOrm

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.

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

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

@@ -257,7 +257,7 @@

.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_7_0_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_7_0_MSVC2022_64bit-Debug.

+

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_7_1_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_7_1_MSVC2022_64bit-Debug.

warning

This will only work if you follow the recommended 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.

diff --git a/database/getting-started.html b/database/getting-started.html index 2de51beed..e2367fe4a 100644 --- a/database/getting-started.html +++ b/database/getting-started.html @@ -14,7 +14,7 @@ - + diff --git a/database/migrations.html b/database/migrations.html index 8ebb783bc..475b89b37 100644 --- a/database/migrations.html +++ b/database/migrations.html @@ -14,7 +14,7 @@ - + diff --git a/database/query-builder.html b/database/query-builder.html index 12afd175c..5e89e1f82 100644 --- a/database/query-builder.html +++ b/database/query-builder.html @@ -14,7 +14,7 @@ - + diff --git a/database/seeding.html b/database/seeding.html index 0312c19dd..e5c4eced1 100644 --- a/database/seeding.html +++ b/database/seeding.html @@ -14,7 +14,7 @@ - + diff --git a/dependencies.html b/dependencies.html index dfc8493da..21adfbd81 100644 --- a/dependencies.html +++ b/dependencies.html @@ -14,7 +14,7 @@ - + diff --git a/features-summary.html b/features-summary.html index 96c76dd34..364ed3ae7 100644 --- a/features-summary.html +++ b/features-summary.html @@ -14,7 +14,7 @@ - + diff --git a/index.html b/index.html index 127d99a9f..81e1068c4 100644 --- a/index.html +++ b/index.html @@ -14,7 +14,7 @@ - + diff --git a/search.html b/search.html index 79cd523ba..141c6cf9d 100644 --- a/search.html +++ b/search.html @@ -14,7 +14,7 @@ - + diff --git a/sponsors.html b/sponsors.html index b060066e4..de95a21c6 100644 --- a/sponsors.html +++ b/sponsors.html @@ -14,7 +14,7 @@ - + diff --git a/supported-compilers.html b/supported-compilers.html index 646024ec7..4482d972d 100644 --- a/supported-compilers.html +++ b/supported-compilers.html @@ -14,7 +14,7 @@ - + diff --git a/tinydrivers/getting-started.html b/tinydrivers/getting-started.html index b78559838..7fe7c4e74 100644 --- a/tinydrivers/getting-started.html +++ b/tinydrivers/getting-started.html @@ -14,7 +14,7 @@ - + diff --git a/tinyorm/casts.html b/tinyorm/casts.html index 3da65b58f..dd92b810f 100644 --- a/tinyorm/casts.html +++ b/tinyorm/casts.html @@ -14,7 +14,7 @@ - + diff --git a/tinyorm/collections.html b/tinyorm/collections.html index fe2d5f229..b69f54add 100644 --- a/tinyorm/collections.html +++ b/tinyorm/collections.html @@ -14,7 +14,7 @@ - + diff --git a/tinyorm/getting-started.html b/tinyorm/getting-started.html index a817f9d99..9b9e6f22f 100644 --- a/tinyorm/getting-started.html +++ b/tinyorm/getting-started.html @@ -14,7 +14,7 @@ - + diff --git a/tinyorm/relationships.html b/tinyorm/relationships.html index ba87c1957..22266a6d7 100644 --- a/tinyorm/relationships.html +++ b/tinyorm/relationships.html @@ -14,7 +14,7 @@ - + diff --git a/tinyorm/serialization.html b/tinyorm/serialization.html index 48d55dda5..f68619999 100644 --- a/tinyorm/serialization.html +++ b/tinyorm/serialization.html @@ -14,7 +14,7 @@ - +