<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <!-- howtos.qdoc --> <title>How-tos | Qbs Manual</title> <link rel="stylesheet" type="text/css" href="style/offline-simple.css" /> <script type="text/javascript"> document.getElementsByTagName("link").item(0).setAttribute("href", "style/offline.css"); // loading style sheet breaks anchors that were jumped to before // so force jumping to anchor again setTimeout(function() { var anchor = location.hash; // need to jump to different anchor first (e.g. none) location.hash = "#"; setTimeout(function() { location.hash = anchor; }, 0); }, 0); </script> </head> <body> <div class="header" id="qtdocheader"> <div class="main"> <div class="main-rounded"> <div class="navigationbar"> <table><tr> <td ><a href="index.html">Qbs Manual</a></td><td >How-tos</td></tr></table><table class="buildversion"><tr> <td id="buildversion" width="100%" align="right">Qbs 1.12.2</td> </tr></table> </div> </div> <div class="content"> <div class="line"> <div class="content mainContent"> <link rel="prev" href="custom-modules.html" /> <link rel="next" href="reference.html" /> <p class="naviNextPrevious headerNavi"> <a class="prevPage" href="custom-modules.html">Custom Modules and Items</a> <span class="naviSeparator"> ◦ </span> <a class="nextPage" href="reference.html">Reference</a> </p><p/> <div class="sidebar"> <div class="toc"> <h3><a name="toc">Contents</a></h3> <ul> <li class="level1"><a href="#how-do-i-build-a-qt-based-project">How do I build a Qt-based project?</a></li> <li class="level1"><a href="#how-do-i-make-my-app-build-against-my-library">How do I make my app build against my library?</a></li> <li class="level1"><a href="#how-do-i-use-precompiled-headers">How do I use precompiled headers?</a></li> <li class="level1"><a href="#how-do-i-run-my-autotests">How do I run my autotests?</a></li> <li class="level1"><a href="#how-do-i-create-a-module-for-a-third-party-library">How do I create a module for a third-party library?</a></li> <li class="level1"><a href="#how-do-i-create-application-bundles-and-frameworks-on-ios-macos-tvos-and-watchos">How do I create application bundles and frameworks on iOS, macOS, tvOS, and watchOS?</a></li> <li class="level1"><a href="#how-do-i-apply-c-c-preprocessor-macros-to-only-a-subset-of-the-files-in-my-product">How do I apply C/C++ preprocessor macros to only a subset of the files in my product?</a></li> <li class="level1"><a href="#how-do-i-make-the-state-of-my-git-repository-available-to-my-source-files">How do I make the state of my Git repository available to my source files?</a></li> </ul> </div> <div class="sidebar-content" id="sidebar-content"></div></div> <h1 class="title">How-tos</h1> <span class="subtitle"></span> <!-- $$$howtos.html-description --> <div class="descr"> <a name="details"></a> <p>This page provides concrete instructions for common scenarios.</p> <ul> <li><a href="howtos.html#how-do-i-build-a-qt-based-project">How do I build a Qt-based project?</a></li> <li><a href="howtos.html#how-do-i-make-my-app-build-against-my-library">How do I make my app build against my library?</a></li> <li><a href="howtos.html#how-do-i-use-precompiled-headers">How do I use precompiled headers?</a></li> <li><a href="howtos.html#how-do-i-run-my-autotests">How do I run my autotests?</a></li> <li><a href="howtos.html#how-do-i-create-a-module-for-a-third-party-library">How do I create a module for a third-party library?</a></li> <li><a href="howtos.html#how-do-i-create-application-bundles-and-frameworks-on-ios-macos-tvos-and-watchos">How do I create application bundles and frameworks on iOS, macOS, tvOS, and watchOS?</a></li> <li><a href="howtos.html#how-do-i-apply-c-c-preprocessor-macros-to-only-a-subset-of-the-files-in-my-product">How do I apply C/C++ preprocessor macros to only a subset of the files in my product?</a></li> <li><a href="howtos.html#how-do-i-make-the-state-of-my-git-repository-available-to-my-source-files">How do I make the state of my Git repository available to my source files?</a></li> </ul> <a name="how-do-i-build-a-qt-based-project"></a> <h2 id="how-do-i-build-a-qt-based-project">How do I build a Qt-based project?</h2> <p>First of all, your project files need to declare <a href="qml-qbslanguageitems-depends.html">dependencies</a> on <a href="porting-to-qbs.html#qt">Qt</a> modules.</p> <p>To build the project, you need a matching <i>profile</i>. The following commands set up and use a Qt-specific profile:</p> <pre class="cpp"> $ qbs setup<span class="operator">-</span>qt <span class="operator">/</span>usr<span class="operator">/</span>bin<span class="operator">/</span>qmake qt $ cd my_project $ qbs profile:qt </pre> <p>If you plan to use this profile a lot, consider making it the default one:</p> <pre class="cpp"> $ qbs config defaultProfile qt $ cd my_project $ qbs </pre> <p>See <a href="qt-versions.html">Managing Qt Versions</a> for more details.</p> <p><b>Note: </b>These instructions are only relevant for building from the command line. If you use Qt Creator, profiles are set up automatically from the information in the Kit.</p><a name="how-do-i-make-my-app-build-against-my-library"></a> <h2 id="how-do-i-make-my-app-build-against-my-library">How do I make my app build against my library?</h2> <p>This is achieved by introducing a <i>dependency</i> between the two products using the <a href="qml-qbslanguageitems-depends.html">Depends</a> item. Here is a simple, but complete example:</p> <pre class="cpp"> import qbs Project { CppApplication { name : <span class="string">"the-app"</span> files : <span class="operator">[</span> <span class="string">"main.cpp"</span> <span class="operator">]</span> Depends { name: <span class="string">"the-lib"</span> } } DynamicLibrary { name: <span class="string">"the-lib"</span> Depends { name: <span class="string">"cpp"</span> } files: <span class="operator">[</span> <span class="string">"lib.cpp"</span><span class="operator">,</span> <span class="string">"lib.h"</span><span class="operator">,</span> <span class="operator">]</span> Export { Depends { name: <span class="string">"cpp"</span> } cpp<span class="operator">.</span>includePaths: <span class="operator">[</span>product<span class="operator">.</span>sourceDirectory<span class="operator">]</span> } } } </pre> <p>The product <code>the-lib</code> is a dynamic library. It expects other products to build against it, and for that purpose, it exports an include path (via an <a href="qml-qbslanguageitems-export.html">Export</a> item), so that the source files in these products can include the library's header file.</p> <p>The product <code>the-app</code> is an application that expresses its intent to link against <code>the-lib</code> by declaring a dependency on it. Now <code>main.cpp</code> can include <code>lib.h</code> (because of the exported include path) and the application binary will link against the library (because the linker <a href="qml-qbslanguageitems-rule.html">rule</a> in the <a href="qml-qbsmodules-cpp.html">cpp</a> module considers library dependencies as inputs).</p> <p><b>Note: </b>In a non-trivial project, the two products would not be defined in the same file. Instead, you would put them into files of their own and use the <a href="qml-qbslanguageitems-project.html#references-prop">Project.references</a> property to pull them into the project. The product definitions would stay exactly the same. In particular, their location in the project tree is irrelevant to the relationship between them.</p><a name="how-do-i-use-precompiled-headers"></a> <h2 id="how-do-i-use-precompiled-headers">How do I use precompiled headers?</h2> <p>If you use a <a href="qml-qbslanguageitems-group.html">Group</a> item to add a precompiled header file to a product and mark it with the <a href="qml-qbsmodules-cpp.html#filetags-cpp">relevant file tag</a> (<code>c_pch_src</code>, <code>cpp_pch_src</code>, <code>objc_pch_src</code>, or <code>objcpp_pch_src</code>), it is used automatically.</p> <p>Only one precompiled header is allowed per product and language.</p> <p>For example:</p> <pre class="cpp"> import qbs CppApplication { name: <span class="string">"the-app"</span> files: <span class="operator">[</span><span class="string">"main.cpp"</span><span class="operator">]</span> Group { files: <span class="operator">[</span><span class="string">"precompiled-header.pch"</span><span class="operator">]</span> fileTags: <span class="operator">[</span><span class="string">"cpp_pch_src"</span><span class="operator">]</span> } } </pre> <a name="how-do-i-run-my-autotests"></a> <h2 id="how-do-i-run-my-autotests">How do I run my autotests?</h2> <p>There are two simple things you need to do in your project. Firstly, you mark your test executables as such. This is done by adding the tag <code>"autotest"</code> to the product type:</p> <pre class="cpp"> CppApplication { name: <span class="string">"test1"</span> type: base<span class="operator">.</span>concat(<span class="string">"autotest"</span>) <span class="comment">// ...</span> } </pre> <p>The second step is to instantiate an <a href="qml-qbsconvenienceitems-autotestrunner.html">AutotestRunner</a> product in your project:</p> <pre class="cpp"> Project { <span class="comment">// ...</span> AutotestRunner { name: <span class="string">"run_my_tests"</span> } } </pre> <p>Building an <a href="qml-qbsconvenienceitems-autotestrunner.html">AutotestRunner</a> product does not produce artifacts, but triggers execution of all applications whose products are tagged as autotests:</p> <pre class="cpp"> $ qbs <span class="operator">-</span>p run_my_tests test1: PASS test2: PASS test3: FAIL <span class="operator">.</span><span class="operator">.</span><span class="operator">.</span> </pre> <p>See the <a href="qml-qbsconvenienceitems-autotestrunner.html">AutotestRunner documentation</a> for how to fine-tune the behavior.</p> <a name="how-do-i-create-a-module-for-a-third-party-library"></a> <h2 id="how-do-i-create-a-module-for-a-third-party-library">How do I create a module for a third-party library?</h2> <p>If you have pre-built binary files in your source tree, you can create modules for them and then introduce dependencies between your project and the modules to pull in the functionality of a third-party library.</p> <p>Create the following folder structure to store the module files:</p> <pre class="cpp"> $projectroot<span class="operator">/</span>modules<span class="operator">/</span>ThirdParty </pre> <p>Then create a file in the directory that specifies the module properties for each supported toolchain. The filename must have the <code>.qbs</code> extension. The module will be pulled in if a product declares a dependency on it.</p> <p>In the following example, <code>lib1.dylib</code> is a multi-architecture library containing both 32-bit and 64-bit code.</p> <pre class="cpp"> <span class="operator">-</span><span class="operator">-</span><span class="operator">-</span>ThirdParty<span class="operator">.</span>qbs<span class="operator">-</span><span class="operator">-</span><span class="operator">-</span> Module { Depends { name: <span class="string">"cpp"</span> } cpp<span class="operator">.</span>includePaths: <span class="operator">[</span><span class="string">"/somewhere/include"</span><span class="operator">]</span> Properties { condition: qbs<span class="operator">.</span>targetOS<span class="operator">.</span>contains(<span class="string">"android"</span>) cpp<span class="operator">.</span>dynamicLibraries: <span class="operator">[</span><span class="string">"/somewhere/android/"</span> <span class="operator">+</span> Android<span class="operator">.</span>ndk<span class="operator">.</span>abi <span class="operator">+</span> <span class="string">"/lib1.so"</span><span class="operator">]</span> } Properties { condition: qbs<span class="operator">.</span>targetOS<span class="operator">.</span>contains(<span class="string">"macos"</span>) cpp<span class="operator">.</span>dynamicLibraries: <span class="operator">[</span><span class="string">"/somewhere/macos/lib1.dylib"</span><span class="operator">]</span> } Properties { condition: qbs<span class="operator">.</span>targetOS<span class="operator">.</span>contains(<span class="string">"windows"</span>) <span class="operator">&</span><span class="operator">&</span> qbs<span class="operator">.</span>architecture <span class="operator">=</span><span class="operator">=</span><span class="operator">=</span> <span class="string">"x86"</span> cpp<span class="operator">.</span>dynamicLibraries: <span class="operator">[</span><span class="string">"/somewhere/windows_x86/lib1.lib"</span><span class="operator">]</span> } Properties { condition: qbs<span class="operator">.</span>targetOS<span class="operator">.</span>contains(<span class="string">"windows"</span>) <span class="operator">&</span><span class="operator">&</span> qbs<span class="operator">.</span>architecture <span class="operator">=</span><span class="operator">=</span><span class="operator">=</span> <span class="string">"x86_64"</span> cpp<span class="operator">.</span>dynamicLibraries: <span class="operator">[</span><span class="string">"/somewhere/windows_x86_64/lib1.lib"</span><span class="operator">]</span> } } </pre> <p>Finally, declare dependencies on <code>ThirdParty</code> in your project:</p> <pre class="cpp"> import qbs CppApplication { name: <span class="string">"the-app"</span> files: <span class="operator">[</span><span class="string">"main.cpp"</span><span class="operator">]</span> Depends { name: <span class="string">"ThirdParty"</span> } } </pre> <a name="how-do-i-create-application-bundles-and-frameworks-on-ios-macos-tvos-and-watchos"></a> <h2 id="how-do-i-create-application-bundles-and-frameworks-on-ios-macos-tvos-and-watchos">How do I create application bundles and frameworks on iOS, macOS, tvOS, and watchOS?</h2> <p>Creating an application bundle or framework is achieved by introducing a dependency on the <a href="qml-qbsmodules-bundle.html">bundle</a> module and setting the <a href="qml-qbsmodules-bundle.html#isBundle-prop">bundle.isBundle</a> property to <code>true</code>.</p> <p>Here is a simple example for an application:</p> <pre class="cpp"> import qbs Application { Depends { name: <span class="string">"cpp"</span> } Depends { name: <span class="string">"bundle"</span> } bundle<span class="operator">.</span>isBundle: <span class="keyword">true</span> name: <span class="string">"the-app"</span> files: <span class="operator">[</span><span class="string">"main.cpp"</span><span class="operator">]</span> } </pre> <p>and for a framework:</p> <pre class="cpp"> import qbs DynamicLibrary { Depends { name: <span class="string">"cpp"</span> } Depends { name: <span class="string">"bundle"</span> } bundle<span class="operator">.</span>isBundle: <span class="keyword">true</span> name: <span class="string">"the-lib"</span> files: <span class="operator">[</span><span class="string">"lib.cpp"</span><span class="operator">,</span> <span class="string">"lib.h"</span><span class="operator">]</span> } </pre> <p>Qbs also supports building static frameworks. You can create one by replacing the <a href="qml-qbsconvenienceitems-dynamiclibrary.html">DynamicLibrary</a> item with a <a href="qml-qbsconvenienceitems-staticlibrary.html">StaticLibrary</a> item in the example above.</p> <p><b>Note: </b>When using the <a href="qml-qbsconvenienceitems-application.html">Application</a> item (or convenience items, such as <a href="qml-qbsconvenienceitems-cppapplication.html">CppApplication</a>, <a href="qml-qbsconvenienceitems-dynamiclibrary.html">DynamicLibrary</a>, and <a href="qml-qbsconvenienceitems-staticlibrary.html">StaticLibrary</a>), your products will be built as bundles on Apple platforms by default (this behavior is subject to change in a future release).</p><p>To explicitly control whether your product is built as a bundle, set the <code>bundle.isBundle</code> property. Setting the <a href="qml-qbslanguageitems-product.html#consoleApplication-prop">consoleApplication</a> property of your product will also influence whether your product is built as a bundle.</p> <p>Building your application against your framework is the same as linking a normal dynamic or static library; see the <a href="howtos.html#how-do-i-make-my-app-build-against-my-library">How do I make my app build against my library?</a> section for an example.</p> <a name="how-do-i-apply-c-c-preprocessor-macros-to-only-a-subset-of-the-files-in-my-product"></a> <h2 id="how-do-i-apply-c-c-preprocessor-macros-to-only-a-subset-of-the-files-in-my-product">How do I apply C/C++ preprocessor macros to only a subset of the files in my product?</h2> <p>Use a <a href="qml-qbslanguageitems-group.html">Group</a> item to define a subset of project files. To add macros within the group, you need to use the <code>outer.concat</code> property, because you are adding macros to those specified in the outer scope.</p> <p>In the following example, <code>MACRO_EVERYWHERE</code> is defined for all files in the <a href="qml-qbslanguageitems-product.html">Product</a> unless a Group overrides the macro, whereas <code>MACRO_GROUP</code> is only defined for <code>groupFile.cpp</code>.</p> <pre class="cpp"> Product { Depends { name: <span class="string">"cpp"</span> } cpp<span class="operator">.</span>defines: <span class="operator">[</span><span class="string">"MACRO_EVERYWHERE"</span><span class="operator">]</span> Group { cpp<span class="operator">.</span>defines: outer<span class="operator">.</span>concat(<span class="string">"MACRO_GROUP"</span>) files: <span class="string">"groupFile.cpp"</span> } } </pre> <p>The <code>cpp.defines</code> statements inside a <code>Group</code> only apply to the files in that <code>Group</code>, and therefore you cannot use a <code>Group</code> to include a bunch of files and globally visible macros. The macros must be specified in a <a href="commands.html#properties">Properties</a> item at the same level as the <code>Group</code> if they need to be visible to files outside the <code>Group</code>:</p> <pre class="cpp"> Product { Depends { name: <span class="string">"cpp"</span> } Group { condition: project<span class="operator">.</span>supportMyFeature files: <span class="string">"myFile.cpp"</span> } property stringList commonDefines: <span class="operator">[</span><span class="string">"ONE"</span><span class="operator">,</span> <span class="string">"TWO"</span><span class="operator">]</span> Properties { condition: project<span class="operator">.</span>supportMyFeature cpp<span class="operator">.</span>defines: commonDefines<span class="operator">.</span>concat(<span class="string">"MYFEATURE_SUPPORTED"</span>) } } </pre> <a name="how-do-i-make-the-state-of-my-git-repository-available-to-my-source-files"></a> <h2 id="how-do-i-make-the-state-of-my-git-repository-available-to-my-source-files">How do I make the state of my Git repository available to my source files?</h2> <p>Add a dependency to the <a href="qml-qbsmodules-vcs.html">vcs</a> module to your product:</p> <pre class="cpp"> CppApplication { <span class="comment">// ...</span> Depends { name: <span class="string">"vcs"</span> } <span class="comment">// ...</span> } </pre> <p>Your source files will now have access to a macro whose value is a string representing the current Git or Subversion HEAD:</p> <pre class="cpp"> <span class="preprocessor">#include <vcs-repo-state.h></span> <span class="preprocessor">#include <iostream></span> <span class="type">int</span> main() { std<span class="operator">::</span>cout <span class="operator"><</span><span class="operator"><</span> <span class="string">"I was built from "</span> <span class="operator"><</span><span class="operator"><</span> VCS_REPO_STATE <span class="operator"><</span><span class="operator"><</span> std<span class="operator">::</span>endl; } </pre> <p>This value is also available via the <a href="qml-qbsmodules-vcs.html#repoState-prop">vcs.repoState</a> property.</p> </div> <!-- @@@howtos.html --> <p class="naviNextPrevious footerNavi"> <a class="prevPage" href="custom-modules.html">Custom Modules and Items</a> <span class="naviSeparator"> ◦ </span> <a class="nextPage" href="reference.html">Reference</a> </p> </div> </div> </div> </div> </div> <div class="footer"> <p> <acronym title="Copyright">©</acronym> 2019 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners.<br/> The documentation provided herein is licensed under the terms of the <a href="http://www.gnu.org/licenses/fdl.html">GNU Free Documentation License version 1.3</a> as published by the Free Software Foundation.<br/> Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners. </p> </div> </body> </html>