aboutsummaryrefslogtreecommitdiffstats
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/appendix/json-api.qdoc7
-rw-r--r--doc/config/macros.qdocconf2
-rw-r--r--doc/doc.qbs1
-rw-r--r--doc/howtos.qdoc12
-rw-r--r--doc/qbs.qdoc23
-rw-r--r--doc/reference/cli/builtin/cli-build.qdoc2
-rw-r--r--doc/reference/cli/builtin/cli-resolve.qdoc1
-rw-r--r--doc/reference/items/convenience/appleapplicationdiskimage.qdoc7
-rw-r--r--doc/reference/items/language/depends.qdoc9
-rw-r--r--doc/reference/items/language/group.qdoc28
-rw-r--r--doc/reference/items/language/moduleprovider.qdoc24
-rw-r--r--doc/reference/items/language/parameters.qdoc4
-rw-r--r--doc/reference/items/probe/binary-probe.qdoc5
-rw-r--r--doc/reference/items/probe/pkgconfig-probe.qdoc11
-rw-r--r--doc/reference/module-providers/conan-module-provider.qdoc101
-rw-r--r--doc/reference/module-providers/qbspkgconfig-module-provider.qdoc37
-rw-r--r--doc/reference/modules/capnprotocpp-module.qdoc4
-rw-r--r--doc/reference/modules/cpp-module.qdoc5
-rw-r--r--doc/reference/modules/exporter-cmake.qdoc135
-rw-r--r--doc/reference/modules/flatbuf-c-module.qdoc83
-rw-r--r--doc/reference/modules/flatbuf-cpp-module.qdoc144
-rw-r--r--doc/reference/modules/protobufcpp-module.qdoc43
-rw-r--r--doc/reference/modules/qt-core-module.qdoc50
-rw-r--r--doc/tutorial.qdoc647
24 files changed, 1282 insertions, 103 deletions
diff --git a/doc/appendix/json-api.qdoc b/doc/appendix/json-api.qdoc
index b555825f9..7b093bc4e 100644
--- a/doc/appendix/json-api.qdoc
+++ b/doc/appendix/json-api.qdoc
@@ -94,6 +94,7 @@
\header \li Property \li Type
\row \li api-level \li int
\row \li api-compat-level \li int
+ \row \li lsp-socket \li string
\endtable
The value of \c api-level is increased whenever the API is extended, for instance
@@ -108,6 +109,10 @@
The value of \c api-compat-level is always less than or equal to the
value of \c api-level.
+ The value of \c lsp-socket is a path to a local domain socket (on Unix) or
+ a named pipe (on Windows). It provides a server implementing the
+ \l{https://microsoft.github.io/language-server-protocol}{Language Server Protocol}.
+
\section1 Resolving a Project
To instruct \QBS to load a project from disk, a request of type
@@ -121,10 +126,10 @@
\row \li dry-run \li bool \li no
\row \li environment \li \l Environment \li no
\row \li error-handling-mode \li string \li no
- \row \li fallback-provider-enabled \li bool \li no
\row \li force-probe-execution \li bool \li no
\row \li log-time \li bool \li no
\row \li log-level \li \l LogLevel \li no
+ \row \li max-job-count \li int \li no
\row \li module-properties \li list of strings \li no
\row \li overridden-properties \li object \li no
\row \li project-file-path \li FilePath \li if resolving from scratch
diff --git a/doc/config/macros.qdocconf b/doc/config/macros.qdocconf
index 6811215c0..31b9b9a8d 100644
--- a/doc/config/macros.qdocconf
+++ b/doc/config/macros.qdocconf
@@ -51,6 +51,8 @@ macro.endfloat.HTML = "</div>"
macro.clearfloat.HTML = "<br style=\"clear: both\" />"
macro.emptyspan.HTML = "<span></span>"
+macro.CMAKE = "CMake"
+
# Embed YouTube content by video ID - Example: \youtube dQw4w9WgXcQ
# Also requires a <ID>.jpg thumbnail for offline docs. In .qdocconf, add:
#
diff --git a/doc/doc.qbs b/doc/doc.qbs
index 03c82e18c..0dfc5f474 100644
--- a/doc/doc.qbs
+++ b/doc/doc.qbs
@@ -30,6 +30,7 @@ Project {
"fixnavi.pl",
"howtos.qdoc",
"qbs.qdoc",
+ "tutorial.qdoc",
"qbs-online.qdocconf",
"config/*.qdocconf",
"config/style/qt5-sidebar.html",
diff --git a/doc/howtos.qdoc b/doc/howtos.qdoc
index 268bee7c0..9a81318ee 100644
--- a/doc/howtos.qdoc
+++ b/doc/howtos.qdoc
@@ -25,7 +25,7 @@
**
****************************************************************************/
/*!
- \previouspage custom-modules.html
+ \previouspage tutorial-8.html
\nextpage reference.html
\page howtos.html
@@ -467,15 +467,17 @@
\section1 How do I build against libraries that provide pkg-config files?
- Just add a \l Depends item that matches the name of the pkg-config module, and \QBS
- will automatically employ \l{https://www.freedesktop.org/wiki/Software/pkg-config}{pkg-config}
+ Just add a \l Depends item that matches the name of the pkg-config module,
+ set the \l Product::qbsModuleProviders property to \c "qbspkgconfig",
+ and \QBS will employ
+ \l{https://www.freedesktop.org/wiki/Software/pkg-config}{pkg-config}
to find the headers and libraries if no matching \QBS module can be found. For instance,
to build against the OpenSSL library, you would write this:
\code
+ qbsModuleProviders: "qbspkgconfig"
Depends { name: "openssl" }
\endcode
- That's it. The pkg-config behavior can be fine-tuned via the \l pkgconfig module,
- but normally you will not need to pull it in explicitly.
+ That's it. The pkg-config behavior can be fine-tuned via the \l qbspkgconfig provider.
Internally, this functionality is implemented via \l {Module Providers}
diff --git a/doc/qbs.qdoc b/doc/qbs.qdoc
index c77dae824..83e461f29 100644
--- a/doc/qbs.qdoc
+++ b/doc/qbs.qdoc
@@ -70,6 +70,18 @@
\li \l{Special Property Values}
\li \l{Module Providers}
\endlist
+ \li \l{Tutorial}
+ \list
+ \li \l{tutorial-1.html}{Console Application}
+ \li \l{tutorial-2.html}{Static Library}
+ \li \l{tutorial-3.html}{Dynamic Library}
+ \li \l{tutorial-4.html}{Convenience Items}
+ \li \l{tutorial-5.html}{Autotest}
+ \li \l{tutorial-6.html}{Project Properties}
+ \li \l{tutorial-7.html}{Buildconfig Module}
+ \li \l{tutorial-8.html}{Configurable Library}
+ \li \l{tutorial-9.html}{Version Header}
+ \endlist
\li \l{How-tos}
\li \l{Reference}
\list
@@ -462,7 +474,7 @@
To build \QBS from the source, you need:
\list
- \li Qt 5.14, or later
+ \li Qt 5.15, or later
\li Windows: MinGW with GCC 4.9 or Microsoft Visual Studio 2015,
or later
\li Linux: GCC 4.9, or later, or Clang 3.9.0, or later
@@ -1068,7 +1080,6 @@
*/
-
/*!
\previouspage usage.html
\page language-introduction.html
@@ -1881,7 +1892,7 @@
/*!
\previouspage special-property-values.html
\page module-providers.html
- \nextpage howtos.html
+ \nextpage tutorial.html
\title Module Providers
@@ -1916,12 +1927,6 @@
a second attempt will be made to locate the dependency using the new paths.
The search for a matching module provider ends as soon as one was found, regardless
of whether it created any modules or not.
- \li If no matching module provider was found in any of the search paths, \QBS will fall back
- to a generic module provider, which creates a module that attempts to locate the
- dependency via \c pkg-config.
- This fallback mechanism can be disabled in the respective
- \l{Depends::enableFallback}{Depends} item or globally via the
- \l{no-fallback-module-provider}{--no-fallback-module-provider} option.
\endlist
\section1 Selecting Module Providers
diff --git a/doc/reference/cli/builtin/cli-build.qdoc b/doc/reference/cli/builtin/cli-build.qdoc
index 683b1ebb8..8547a78d2 100644
--- a/doc/reference/cli/builtin/cli-build.qdoc
+++ b/doc/reference/cli/builtin/cli-build.qdoc
@@ -78,8 +78,6 @@
\include cli-options.qdocinc products-specified
\include cli-options.qdocinc settings-dir
\include cli-options.qdocinc show-progress
- \target no-fallback-module-provider
- \include cli-options.qdocinc no-fallback-module-provider
\include cli-options.qdocinc wait-lock
\section1 Parameters
diff --git a/doc/reference/cli/builtin/cli-resolve.qdoc b/doc/reference/cli/builtin/cli-resolve.qdoc
index 4569980bd..99f1658ea 100644
--- a/doc/reference/cli/builtin/cli-resolve.qdoc
+++ b/doc/reference/cli/builtin/cli-resolve.qdoc
@@ -55,7 +55,6 @@
\include cli-options.qdocinc more-verbose
\include cli-options.qdocinc settings-dir
\include cli-options.qdocinc show-progress
- \include cli-options.qdocinc no-fallback-module-provider
\include cli-options.qdocinc deprecation-warnings
\section1 Parameters
diff --git a/doc/reference/items/convenience/appleapplicationdiskimage.qdoc b/doc/reference/items/convenience/appleapplicationdiskimage.qdoc
index 8db7bc4db..d1fa15052 100644
--- a/doc/reference/items/convenience/appleapplicationdiskimage.qdoc
+++ b/doc/reference/items/convenience/appleapplicationdiskimage.qdoc
@@ -77,10 +77,11 @@
The base directory from which artifacts installed into the disk image will be copied.
This directory is always considered to be relative to \l{qbs::installRoot}
- {qbs.installRoot}.
+ {qbs.installRoot}/\l{qbs::installPrefix}
+ {qbs.installPrefix}.
For example, if the application Example.app exists at
- \c{qbs.installRoot/Applications/Example.app}, and the value of this property
- is \c{"/Applications"}, the application will be located at\c{/Example.app}
+ \c{qbs.installRoot/qbs.installPrefix/Applications/Example.app}, and the value of this property
+ is \c{"/Applications"}, the application will be located at \c{/Example.app}
relative to the disk image root. Therefore, its full path when the disk
image is mounted would be something like \c{/Volumes/Example-1.0/Example.app}.
diff --git a/doc/reference/items/language/depends.qdoc b/doc/reference/items/language/depends.qdoc
index 7cc270483..937828b8c 100644
--- a/doc/reference/items/language/depends.qdoc
+++ b/doc/reference/items/language/depends.qdoc
@@ -197,12 +197,3 @@
\nodefaultvalue
*/
-
-/*!
- \qmlproperty bool Depends::enableFallback
-
- Whether to fall back to a pkg-config based \l{Module Providers}{module provider}
- if the dependency is not found.
-
- \defaultvalue \c true
-*/
diff --git a/doc/reference/items/language/group.qdoc b/doc/reference/items/language/group.qdoc
index c9b6dd1cf..fa6784ca6 100644
--- a/doc/reference/items/language/group.qdoc
+++ b/doc/reference/items/language/group.qdoc
@@ -74,10 +74,13 @@
}
}
\endcode
- When specifying files, you can use the wildcards "*", "?" and "[]", which have their usual meaning.
- By default, matching files are only picked up directly from the parent directory, but you can tell \QBS to
- consider the whole directory tree. It is also possible to exclude certain files from the list.
- The pattern ** used in a pathname expansion context will match all files and zero or more
+ When specifying files, you can use the wildcards \c "*", \c "?" and \c "[]", which
+ have their
+ \l{https://en.wikipedia.org/wiki/Wildcard_character#File_and_directory_patterns}{usual meaning}
+ as in Unix Shell. By default, matching files are only picked up directly from the
+ parent directory, but you can tell \QBS to consider the whole directory tree.
+ It is also possible to exclude certain files from the list.
+ The pattern \c "**" used in a pathname expansion context will match all files and zero or more
directories and subdirectories.
For example:
\snippet reference/items/language/group.qbs 0
@@ -114,13 +117,15 @@
*/
/*!
- \qmlproperty list Group::files
+ \qmlproperty pathList Group::files
The files in the group. Mutually exclusive with \l{fileTagsFilter}.
Relative paths are resolved using the parent directory of the file
that contains the Group item. However, if the \l{prefix} property is set to
an absolute path, then that one becomes the base directory.
+ The values can contain wildcards.
+
\defaultvalue An empty list
*/
@@ -146,7 +151,7 @@
*/
/*!
- \qmlproperty list Group::fileTagsFilter
+ \qmlproperty stringList Group::fileTagsFilter
List of \l{Artifact::fileTags}{artifact.fileTags} to match. Any properties
set in this group will be applied to the product's artifacts whose file tags
@@ -170,7 +175,7 @@
*/
/*!
- \qmlproperty list Group::fileTags
+ \qmlproperty stringList Group::fileTags
A list of file tags to attach to the group's files. These can then be
matched by a \l{Rule}{rule}.
@@ -196,10 +201,13 @@
*/
/*!
- \qmlproperty list Group::excludeFiles
+ \qmlproperty pathList Group::excludeFiles
+
+ A list of files that are \e subtracted from the \l{files} list.
- A list of files that are \e subtracted from the files list. Useful when
- using wildcards.
+ The values can contain wildcards.
+
+ This property is ignored if \l{fileTagsFilter} is set.
\defaultvalue An empty list
*/
diff --git a/doc/reference/items/language/moduleprovider.qdoc b/doc/reference/items/language/moduleprovider.qdoc
index 81a09a66b..09cabb39b 100644
--- a/doc/reference/items/language/moduleprovider.qdoc
+++ b/doc/reference/items/language/moduleprovider.qdoc
@@ -67,6 +67,19 @@
*/
/*!
+ \qmlproperty bool ModuleProvider::isEager
+
+ Holds whether provider is eager.
+
+ Eager provider is executed only once and should create multiple modules at once when executed).
+ A non-eager provider is executed multiple times, one time for each module \QBS tries to
+ instantiate.
+
+ \sa ModuleProvider::moduleName
+ \default true
+*/
+
+/*!
\qmlproperty string ModuleProvider::name
The name of the module provider.
@@ -83,6 +96,17 @@
*/
/*!
+ \qmlproperty string ModuleProvider::moduleName
+
+ This property is set by QBS for non-eager providers and contains the name of the module
+ that is currently being instantiated by the provider.
+
+ For eager providers, the value of this property is \c undefined.
+
+ \sa ModuleProvider::isEager
+*/
+
+/*!
\qmlproperty string ModuleProvider::outputBaseDir
The path under which the new modules should be created when \l relativeSearchPaths
diff --git a/doc/reference/items/language/parameters.qdoc b/doc/reference/items/language/parameters.qdoc
index 325f1680e..fb7653528 100644
--- a/doc/reference/items/language/parameters.qdoc
+++ b/doc/reference/items/language/parameters.qdoc
@@ -32,10 +32,10 @@
\ingroup list-of-items
\keyword QML.Parameters
- \brief Defines default values for dependency parameters within Export items.
+ \brief Defines default values for dependency parameters within Module and Export items.
The Parameters item defines default values for dependency parameters within
- \l{Export} items.
+ \l{Module} and \l{Export} items.
Example:
\code
diff --git a/doc/reference/items/probe/binary-probe.qdoc b/doc/reference/items/probe/binary-probe.qdoc
index 7c8cd2f42..919d0b89e 100644
--- a/doc/reference/items/probe/binary-probe.qdoc
+++ b/doc/reference/items/probe/binary-probe.qdoc
@@ -50,6 +50,7 @@
For example, BinaryProbe can be used to search for a protobuf compiler executable as follows:
\code
+ // Assuming module is called "myproto"
import qbs.File
import qbs.Probes
@@ -70,10 +71,10 @@
Rule {
// rule input/outputs here...
- // run executable
+ // run executable for the module called "myproto":
prepare: {
var args = // initialize arguments...
- var cmd = new Command(executableFilePath, args);
+ var cmd = new Command(input.myproto.executableFilePath, args);
cmd.highlight = "codegen";
cmd.description = "generating protobuf files for " + input.fileName;
return [cmd];
diff --git a/doc/reference/items/probe/pkgconfig-probe.qdoc b/doc/reference/items/probe/pkgconfig-probe.qdoc
index 22fd510ac..66e008601 100644
--- a/doc/reference/items/probe/pkgconfig-probe.qdoc
+++ b/doc/reference/items/probe/pkgconfig-probe.qdoc
@@ -51,8 +51,12 @@
maxVersion: '5.99.99'
}
files: 'main.cpp'
- cpp.cxxFlags: pkgConfig.cflags
- cpp.linkerFlags: pkgConfig.libs
+ cpp.defines : pkgConfig.defines
+ cpp.includePaths: pkgConfig.includePaths
+ cpp.dynamicLibraries: pkgConfig.libraries
+ cpp.libraryPaths: pkgConfig.libraryPaths
+ cpp.commonCompilerFlags: pkgConfig.compilerFlags
+ cpp.linkerFlags: pkgConfig.linkerFlags
}
\endcode
*/
@@ -194,9 +198,6 @@
This output property contains the list of library paths that should be passed to a linker when
using requested package.
- This property sets the value of the PKG_CONFIG_LIBDIR environment variable passed to
- the \c pkg-config binary.
-
\nodefaultvalue
*/
diff --git a/doc/reference/module-providers/conan-module-provider.qdoc b/doc/reference/module-providers/conan-module-provider.qdoc
new file mode 100644
index 000000000..4edba94d8
--- /dev/null
+++ b/doc/reference/module-providers/conan-module-provider.qdoc
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2024 Ivan Komissarov (abbapoh@gmail.com)
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qbs.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \qmltype conan
+ \inqmlmodule QbsModuleProviders
+ \since 2.4
+
+ \brief Module provider for the Conan package manager.
+
+ This module provider allows integration with the \l{https://conan.io}{Conan} package manager.
+
+ \section1 Prerequisites
+ In order to use this provider, you will need to install the
+ \l{https://github.com/qbs/qbs/blob/master/src/conan/extensions/generators/qbsdeps.py}{QbsDeps generator}
+ first. In order to do so, clone the \QBS repository and run the following command from the \QBS
+ source directory:
+ \code
+ $ conan config install src/conan/
+ \endcode
+ This will copy the generator to \c .conan2/extensions/generators/qbsdeps.py in the user's home
+ directory.
+ Alternatively, you can use \c curl to download the file:
+ \code
+ $ curl 'https://github.com/qbs/qbs/raw/master/src/conan/extensions/generators/qbsdeps.py' -o ~/.conan2/extensions/generators/qbsdeps.py
+ \endcode
+
+ \section1 Example
+ For details on how to setup a project to use with Conan, see the \
+ l{https://github.com/qbs/qbs/blob/master/examples/protobuf/addressbook_conan}{addressbook_conan}
+ folder in examples.
+ First, you will need a \l{https://docs.conan.io/2/reference/conanfile_txt.html}{conanfile} as
+ shown below.
+ \code
+ [requires]
+ protobuf/3.21.12
+ [tool_requires]
+ protobuf/3.21.12
+ [generators]
+ QbsDeps
+ \endcode
+ We use the text version for simplicity, but you can use the Python conanfile as well.
+
+ Next, set the \l{Product::qbsModuleProviders}{qbsModuleProviders} property to \c "conan":
+ \snippet ../examples/protobuf/addressbook_conan/addressbook_conan.qbs 0
+
+ Install Conan dependencies and run the QbsDeps generator from the \c addressbook_conan dir:
+ \code
+ $ conan install . -g=QbsDeps --output-folder=build --build missing
+ \endcode
+ This will create the \c{./build/qbs-deps} directory contaning files for provider. Now you can
+ pass the conan install directory to the provider:
+ \code
+ $ qbs moduleProviders.conan.installDirectory:build
+ \endcode
+ You should see the following output if everything is correct:
+ \code
+ Build graph does not yet exist for configuration 'default'. Starting from scratch.
+ Resolving project for configuration default
+ Setting up Conan module 'protobuflib'
+ Setting up Conan module 'zlib'
+ ...
+ Build done for configuration default.
+ \endcode
+*/
+
+/*!
+ \qmlproperty string conan::installDirectory
+
+ The path to the conan install installDirectory.
+
+ \QBS searches for files created by the QbsDeps generator in that directory.
+
+ If not set, the provider will not be run.
+
+ \defaultvalue undefined
+*/
diff --git a/doc/reference/module-providers/qbspkgconfig-module-provider.qdoc b/doc/reference/module-providers/qbspkgconfig-module-provider.qdoc
index f9c4e9ade..a7f6fe6b7 100644
--- a/doc/reference/module-providers/qbspkgconfig-module-provider.qdoc
+++ b/doc/reference/module-providers/qbspkgconfig-module-provider.qdoc
@@ -87,6 +87,29 @@
*/
/*!
+ \qmlproperty bool qbspkgconfig::definePrefix
+
+ If this property is \c true, then \QBS will override the ${prefix} variable in the packages
+ with a value that is guessed based on the location of the .pc file.
+
+ This option corresponds to the \c --define-prefix / \c --dont-define-prefix command line
+ options of the \c pkg-config tool.
+
+ \defaultvalue \c true on Windows, \c false otherwise
+*/
+
+/*!
+ \qmlproperty stringList qbspkgconfig::executableNames
+
+ The names of the \c pkg-config executable to search for.
+
+ Note that since newer distributions use \l{http://pkgconf.org}{pkgconf} by default, it has
+ higher priority over \c pkg-config.
+
+ \defaultvalue \c{["pkgconf", "pkg-config"]}
+*/
+
+/*!
\qmlproperty path qbspkgconfig::sysroot
Set this property if you need to overwrite the default search sysroot path used by
@@ -100,7 +123,7 @@
Setting this property to \c undefined or empty (\c "") value will use pkg-config's default
search paths:
\code
- qbs build module-providers.pkgconfig.sysroot:undefined
+ qbs resolve moduleProviders.qbspkgconfig.sysroot:undefined
\endcode
This property is the equivalent of the \c{PKG_CONFIG_SYSROOT_DIR} variable for the
@@ -108,15 +131,3 @@
\defaultvalue \c "" on macOS, \c qbs.sysroot on other platforms
*/
-
-/*!
- \qmlproperty bool qbspkgconfig::mergeDependencies
-
- Holds whether dependencies should be merged by pkg-config or \QBS.
-
- If set to true, dependencies are merged by pkg-config meaning each generated module
- is self-contained and does not depend on other modules. If set to false, generated modules
- may depend on other modules and property merging is done by \QBS.
-
- \defaultvalue \c false
-*/
diff --git a/doc/reference/modules/capnprotocpp-module.qdoc b/doc/reference/modules/capnprotocpp-module.qdoc
index c3c8660c9..7635edd9e 100644
--- a/doc/reference/modules/capnprotocpp-module.qdoc
+++ b/doc/reference/modules/capnprotocpp-module.qdoc
@@ -104,12 +104,10 @@
/*!
\qmlproperty string capnproto.cpp::outputDir
- \readonly
The directory where the \c capnpc compiler generated files are placed.
- The value of this property is automatically set by \QBS and cannot be
- changed by the user.
+ \defaultvalue \c product.buildDirectory + "/capnp"
*/
/*!
diff --git a/doc/reference/modules/cpp-module.qdoc b/doc/reference/modules/cpp-module.qdoc
index f0b6de063..2b344aac2 100644
--- a/doc/reference/modules/cpp-module.qdoc
+++ b/doc/reference/modules/cpp-module.qdoc
@@ -80,6 +80,7 @@
May contain the values: "weak", "lazy", "reexport", and "upward"; refer to the Apple
ld64 man page for full details. \c{undefined} uses normal linking.
Currently only applies when linking for Apple platforms.
+ Note that \c "lazy" mode is deprecated and doesn't work with Xcode 15 and above.
\endtable
\section2 Relevant File Tags
@@ -1402,8 +1403,8 @@
will result in the \c {-fuse-ld} option being emitted when linking with \c gcc,
\c clang or \c clang-cl. Other toolchains do not support this property.
- The possible values for \c clang and \c gcc are \c "bfd", \c "gold" and \c "lld",
- the possible values for \c clang-cl are \c "link" and \c "lld".
+ The possible values for \c clang and \c gcc are \c "bfd", \c "gold", \c "lld"
+ and \c "mold", the possible values for \c clang-cl are \c "link" and \c "lld".
The following example demonstrates how to change the linker for different toolchains:
diff --git a/doc/reference/modules/exporter-cmake.qdoc b/doc/reference/modules/exporter-cmake.qdoc
new file mode 100644
index 000000000..2f4191a76
--- /dev/null
+++ b/doc/reference/modules/exporter-cmake.qdoc
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2024 Raphael Cotty (raphael.cotty@gmail.com)
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qbs.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \qmltype Exporter.cmake
+ \inqmlmodule QbsModules
+ \since Qbs 2.3
+
+ \brief Provides support for generating \CMAKE packages from dynamic, static and header library
+ products.
+
+ The Exporter.cmake module contains the properties and rules to create a \CMAKE config
+ \l{https://cmake.org/cmake/help/v3.29/manual/cmake-packages.7.html#config-file-packages}{files}
+ from the \l Export item of a \l Product.
+
+ For instance, suppose you are creating a library. To allow exporting to \CMAKE, you would write
+ something like the following:
+ \code
+ DynamicLibrary {
+ name: "mylibrary"
+ qbs.installPrefix: "/opt/mylibrary"
+ Depends { name: "Exporter.cmake" }
+ Exporter.cmake.packageName: "MyLibrary"
+ property string headersInstallDir: "include"
+ // ...
+ Group {
+ name: "API headers"
+ files: ["mylib.h"]
+ qbs.install: true
+ qbs.installDir: headersInstallDir
+ }
+ Group {
+ fileTagsFilter: ["Exporter.cmake.package"]
+ qbs.installDir: "lib/cmake/MyLibrary"
+ }
+ Export {
+ Depends { name: "cpp" }
+ cpp.includePaths: FileInfo.joinPaths(
+ exportingProduct.qbs.installRoot,
+ exportingProduct.qbs.installPrefix,
+ exportingProduct.headersInstallDir)
+ }
+ }
+ \endcode
+ To build against this library, from within your \CMAKE project, you simply
+ use \l{https://cmake.org/cmake/help/v3.29/command/find_package.html}{find_package}:
+ \code
+ find_package(MyLibrary PATHS REQUIRED)
+ add_executable(Consumer main.cpp)
+ target_link_libraries(Consumer MyLibrary)
+ \endcode
+
+ \section2 Relevant File Tags
+ \target filetags-exporter-qbs
+
+ \table
+ \header
+ \li Tag
+ \li Since
+ \li Description
+ \row
+ \li \c{"Exporter.cmake.package"}
+ \li 2.3.0
+ \li This tag is attached to all generated module files.
+ \row
+ \li \c{"Exporter.cmake.configFile"}
+ \li 2.3.0
+ \li This tag is attached to the generated config file.
+ \row
+ \li \c{"Exporter.cmake.versionFile"}
+ \li 2.3.0
+ \li This tag is attached to the generated version file.
+ \endtable
+*/
+
+/*!
+ \qmlproperty string Exporter.cmake::configFileName
+
+ The name of the generated config file.
+
+ \defaultvalue \c{packageName + "Config.cmake"}
+*/
+
+/*!
+ \qmlproperty string Exporter.cmake::versionFileName
+
+ The name of the generated version file.
+
+ \defaultvalue \c{packageName + "ConfigVersion.cmake"}
+*/
+
+/*!
+ \qmlproperty string Exporter.cmake::packageName
+
+ The name of the \CMAKE package.
+
+ \defaultvalue \l{Product::targetName}{Product.targetName}
+*/
+
diff --git a/doc/reference/modules/flatbuf-c-module.qdoc b/doc/reference/modules/flatbuf-c-module.qdoc
new file mode 100644
index 000000000..d486ab3bf
--- /dev/null
+++ b/doc/reference/modules/flatbuf-c-module.qdoc
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2024 Ivan Komissarov (abbapoh@gmail.com)
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qbs.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \qmltype flatbuf.c
+ \inqmlmodule QbsModules
+ \since Qbs 2.4
+
+ \brief Provides support for \l{https://google.github.io/flatbuffers/}{FlatBuffers} for the
+ C language.
+
+ The \c flatbuf.c module provides support for generating C headers
+ and sources from flatbuffers definition files using the \c flatcc tool.
+
+ \section2 Relevant File Tags
+
+ \table
+ \header
+ \li Tag
+ \li Auto-tagged File Names
+ \li Since
+ \li Description
+ \row
+ \li \c{"flatbuffers.input"}
+ \li \c{*.fbs}
+ \li 2.4.0
+ \li Source files with this tag are considered inputs to the \c flatcc compiler.
+ \endtable
+
+ \section2 Dependencies
+ This module depends on the \c flatcc module which can be created via the \l{conan}{Conan}
+ module provider.
+*/
+
+/*!
+ \qmlproperty string flatbuf.c::compilerName
+
+ The name of the \c flatcc binary.
+
+ \defaultvalue \c "flatcc"
+*/
+
+/*!
+ \qmlproperty string flatbuf.c::compilerPath
+
+ The path to the \c flatcc binary.
+
+ Use this property to override the auto-detected location.
+
+ \defaultvalue \c auto-detected
+*/
+
+/*!
+ \qmlproperty pathList flatbuf.c::importPaths
+
+ The list of import paths that are passed to the \c flatcc tool via the \c -I option.
+
+ \defaultvalue \c []
+*/
diff --git a/doc/reference/modules/flatbuf-cpp-module.qdoc b/doc/reference/modules/flatbuf-cpp-module.qdoc
new file mode 100644
index 000000000..a4b6915ab
--- /dev/null
+++ b/doc/reference/modules/flatbuf-cpp-module.qdoc
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** Copyright (C) 2024 Ivan Komissarov (abbapoh@gmail.com)
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qbs.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \qmltype flatbuf.cpp
+ \inqmlmodule QbsModules
+ \since Qbs 2.4
+
+ \brief Provides support for \l{https://google.github.io/flatbuf/}{flatbuf} for the
+ C++ language.
+
+ The \c flatbuf.cpp module provides support for generating C++ headers
+ and sources from flatbuf definition files using the \c flatc tool.
+
+ A simple qbs file that uses flatbuf can be written as follows:
+ \code
+ CppApplication {
+ Depends { name: "flatbuf.cpp" }
+ files: ["foo.fbs", "main.cpp"]
+ }
+ \endcode
+ A generated header now can be included in the C++ sources:
+ \code
+ #include <foo_generated.h>
+
+ int main(int argc, char* argv[]) {
+ flatbuf::FlatBufferBuilder builder;
+
+ auto foo = QbsTest::CreateFoo(builder, 42);
+ return 0;
+ }
+ \endcode
+
+ \section2 Relevant File Tags
+
+ \table
+ \header
+ \li Tag
+ \li Auto-tagged File Names
+ \li Since
+ \li Description
+ \row
+ \li \c{"flatbuf.input"}
+ \li \c{*.fbs}
+ \li 2.4.0
+ \li Source files with this tag are considered inputs to the \c flatc compiler.
+ \endtable
+
+ \section2 Dependencies
+ This module depends on the \c flatbuffers module which can be created via the \l{conan}{Conan}
+ module provider.
+*/
+
+/*!
+ \qmlproperty string flatbuf.cpp::compilerName
+
+ The name of the \c flatc binary.
+
+ \defaultvalue \c "flatc"
+*/
+
+/*!
+ \qmlproperty string flatbuf.cpp::compilerPath
+
+ The path to the \c flatc binary.
+
+ Use this property to override the auto-detected location.
+
+ \defaultvalue \c auto-detected
+*/
+
+/*!
+ \qmlproperty string flatbuf.cpp::filenameExtension
+
+ The extension appended to the generated file names. If not specified, the default extension
+ (\c ".h") is used.
+
+ This property corresponds to the \c --filename-ext option of the \c flatc tool.
+
+ \nodefaultvalue
+*/
+
+/*!
+ \qmlproperty string flatbuf.cpp::filenameSuffix
+
+ The suffix appended to the generated file names. If not specified, the default suffix
+ (\c "_generated") is used.
+
+ This property corresponds to the \c --filename-suffix option of the \c flatc tool.
+
+ \nodefaultvalue
+*/
+
+/*!
+ \qmlproperty pathList flatbuf.cpp::importPaths
+
+ The list of import paths that are passed to the \c flatc tool via the \c -I option.
+
+ \defaultvalue \c []
+*/
+
+/*!
+ \qmlproperty string flatbuf.cpp::includePrefix
+
+ Prefix path prepended to any generated include statements.
+
+ This property corresponds to the \c --include-prefix option of the \c flatc tool.
+
+ \nodefaultvalue
+*/
+
+/*!
+ \qmlproperty bool flatbuf.cpp::keepPrefix
+
+ Whether to keep original prefix of schema include statement.
+
+ This property corresponds to the \c --keep-prefix option of the \c flatc tool.
+
+ \defaultvalue \c false
+*/
diff --git a/doc/reference/modules/protobufcpp-module.qdoc b/doc/reference/modules/protobufcpp-module.qdoc
index 85851c4ae..2c96eaeef 100644
--- a/doc/reference/modules/protobufcpp-module.qdoc
+++ b/doc/reference/modules/protobufcpp-module.qdoc
@@ -78,6 +78,13 @@
\li 1.18.0
\li This tag is attached to the header files generated by \c protoc compiler.
\endtable
+
+ \section2 Dependencies
+
+ The \l protobuf.cpp module requires runtime libraries to be operational. It depends on the
+ \c "protobuflib" module which can be created by the \l qbspkgconfig or fallback module
+ providers (the corresponding packages are \c protobuf or \c protobuf-lite). If \l useGrpc is
+ set to true, the \l protobuf.cpp module also depends on the \c "grpc++" module.
*/
/*!
@@ -101,24 +108,6 @@
*/
/*!
- \qmlproperty string protobuf.cpp::grpcIncludePath
-
- The path where grpc++ headers are located. Set this property to override the
- default location.
-
- \defaultvalue \c auto-detected
-*/
-
-/*!
- \qmlproperty string protobuf.cpp::grpcLibraryPath
-
- The path where the grpc++ library is located. Set this property to override the
- default location.
-
- \defaultvalue \c auto-detected
-*/
-
-/*!
\qmlproperty pathList protobuf.cpp::importPaths
The list of imports that are passed to the \c protoc tool via the \c --proto_path option.
@@ -131,24 +120,6 @@
*/
/*!
- \qmlproperty string protobuf.cpp::includePath
-
- The path where protobuf C++ headers are located. Set this property to override the
- default location.
-
- \defaultvalue \c auto-detected
-*/
-
-/*!
- \qmlproperty string protobuf.cpp::libraryPath
-
- The path where the protobuf C++ library is located. Set this property to override the
- default location.
-
- \defaultvalue \c auto-detected
-*/
-
-/*!
\qmlproperty string protobuf.cpp::outputDir
\readonly
diff --git a/doc/reference/modules/qt-core-module.qdoc b/doc/reference/modules/qt-core-module.qdoc
index afc4a0f11..6aedf2a69 100644
--- a/doc/reference/modules/qt-core-module.qdoc
+++ b/doc/reference/modules/qt-core-module.qdoc
@@ -211,6 +211,32 @@
*/
/*!
+ \qmlproperty string Qt.core::generatedHeadersDir
+
+ The directory where tools that generate headers (such as \c moc or \c uic) put resulting
+ files.
+
+ Normally, you don't need to change this property. The one use-case is when there are several
+ files with the same file name in the Product. The file name produced by \c moc is based
+ only on the source file's base file name (without the directory path) which leads to a conflict
+ in the mentioned case. You can resolve the conflict by setting this property to a non-default
+ value for one of the files. For example:
+
+ \code
+ QtApplication {
+ files: ["my_cool_header.h", "main.cpp"]
+ Group {
+ name: "legacy"
+ files: "legacy/my_cool_header.h"
+ Qt.core.generatedHeadersDir: "qt.legacy.headers"
+ }
+ }
+ \endcode
+
+ \defaultvalue \c product.buildDirectory + "/qt.headers"
+*/
+
+/*!
\qmlproperty bool Qt.core::metaTypesInstallDir
The directory to install the metatypes file into. If this property is empty or undefined,
@@ -352,6 +378,14 @@
*/
/*!
+ \qmlproperty string Qt.core::qdocOutputDir
+
+ The directory name where the \c qdoc tool writes its output.
+
+ \defaultvalue \c{product.buildDirectory + "/qdoc_html"}
+*/
+
+/*!
\qmlproperty string Qt.core::qmBaseName
The base name of the \c .qm file to be built from the \c .ts files in the
@@ -363,6 +397,14 @@
*/
/*!
+ \qmlproperty string Qt.core::qmDir
+
+ The directory name where to put the \c .qm file to be built.
+
+ \defaultvalue \l{Product::destinationDirectory}{product.destinationDirectory}
+*/
+
+/*!
\qmlproperty string Qt.core::qtBuildVariant
Specifies the type of Qt libraries to build against: \c "debug" or
@@ -468,3 +510,11 @@
\defaultvalue \c{versionParts[2]}
*/
+
+/*!
+ \qmlproperty bool Qt.core::useRPaths
+
+ Whether to add \l{Qt.core::libPath}{Qt.core.libPath} to \l{cpp::rpaths}{cpp.rpaths}.
+
+ \defaultvalue \c true on Linux, \c false everywhere else.
+*/
diff --git a/doc/tutorial.qdoc b/doc/tutorial.qdoc
new file mode 100644
index 000000000..b17cf4faf
--- /dev/null
+++ b/doc/tutorial.qdoc
@@ -0,0 +1,647 @@
+/****************************************************************************
+**
+** Copyright (C) 2024 Ivan Komissarov (abbapoh@gmail.com).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qbs.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \previouspage module-providers.html
+ \page tutorial.html
+ \nextpage tutorial-1.html
+
+ \title Tutorial
+
+ The tutorial describes the process of creating a typical \QBS project and explains core
+ concepts.
+
+ \list
+ \li \l{tutorial-1.html}{Console Application}
+ \li \l{tutorial-2.html}{Static Library}
+ \li \l{tutorial-3.html}{Dynamic Library}
+ \li \l{tutorial-4.html}{Convenience Items}
+ \li \l{tutorial-5.html}{Autotest}
+ \li \l{tutorial-6.html}{Project Properties}
+ \li \l{tutorial-7.html}{Buildconfig Module}
+ \li \l{tutorial-8.html}{Configurable Library}
+ \li \l{tutorial-9.html}{Version Header}
+ \endlist
+*/
+
+/*!
+ \previouspage tutorial.html
+ \page tutorial-1.html
+ \nextpage tutorial-2.html
+
+ \title Console Application
+
+ Let's start with a mandatory Hello World example. There is a Hello World example in the
+ \l{overview.html#well-defined-language}{overview section}, but this time we will create a
+ real-world project.
+
+ We will start with a simple \QBS project file:
+ \snippet ../tutorial/chapter-1/myproject.qbs 0
+
+ Here, we set the \l{Project::name}{name} of the project to \c "My Project" - it is mainly
+ used for IDEs but can also be used to reference a project when setting properties from
+ command-line. We also set the \l{Project::minimumQbsVersion}{minimumQbsVersion} - this property
+ can be useful if the project depends on features that are not present in earlier \QBS
+ versions.
+
+ The \l{Project::references}{references} property contains the path to a file
+ that describes our application. This file is located in a separate \c app directory -
+ typically, projects tend to have quite a complicated structure but \QBS does not enforce any
+ specific layout, so we will simply put each product in a separate directory.
+
+ The application file sets several properties:
+ \snippet ../tutorial/chapter-1/app/app.qbs 0
+
+ The \l{Product::name}{name} property identifies the product.
+ The \l{Product::targetName}{targetName} property sets the name of the resulting binary
+ (without the \c .exe extension on Windows, which is appended automatically). By default,
+ \l{Product::targetName}{targetName} defaults to \l{Product::name}{name}. The
+ \l{Product::files}{files} property contains a single \c main.c file which is a trivial
+ \e{hello world} application:
+ \snippet ../tutorial/chapter-1/app/main.c 0
+
+ We set \l{Product::consoleApplication}{consoleApplication} to \c true to indicate that our
+ application is going to be used from a terminal. For example, on Windows, this will spawn a
+ new console window if you double-click the resulting binary, while on macOS it will create a
+ standalone binary file instead of an
+ \l{https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFBundles/BundleTypes/BundleTypes.html}{application bundle}.
+
+ By default, the \l{Application::install}{CppApplication.install} property is \c false and thus
+ \QBS does not install the binary. If the \l{Application::install}{install} property is
+ \c true, when building a project, \QBS will also install it into an \e{installation root}
+ folder which by default is named \c install-root and located under the build directory. This
+ folder will contain only resulting artifacts without the build leftovers and files will have
+ the same layout as in the target system. The \l{Application::install}{install} property should
+ be set to \c true for all products that are to be distributed.
+ See the \l{installing-files.html}{Installing Files} section for more details.
+
+ We can now build and run our application from the project directory:
+ \code
+ chapter-1 $ qbs build
+ ...
+ Building for configuration default
+ compiling main.c [My Application]
+ ...
+ linking myapp [My Application]
+ ...
+ Build done for configuration default.
+
+ chapter-1 $ qbs run
+ ...
+ Starting target. Full command line: .../default/install-root/usr/local/bin/myapp
+ Hello, world
+ \endcode
+
+ The \QBS output to console and default installation location may vary between different
+ platforms.
+
+ In most cases, \QBS should be able to find the default compiler (for example, GCC or
+ Clang on Linux, Visual Studio on Windows, or Xcode on macOS), but if that's not the
+ case, see the \l{configuring.html}{configuring} section.
+
+ In the following chapters, we will continue to improve our project: we will add a library and
+ make it configurable.
+*/
+
+/*!
+ \previouspage tutorial-1.html
+ \page tutorial-2.html
+ \nextpage tutorial-3.html
+
+ \title Static Library
+
+ Let's add a static library to our project so we can reuse some code. Analogous to what we did
+ for the application, we put the file into the \c{lib} directory and add it to the
+ \l{Project::references}{references} property in our project. The modified project may look
+ like this:
+
+ \snippet ../tutorial/chapter-2/myproject.qbs 0
+
+ Let's take a look at the the library file now:
+
+ \snippet ../tutorial/chapter-2/lib/lib.qbs 0
+ It contains the \l{StaticLibrary} item which sets the \l{Product::type}{type} of the product
+ to \c "staticlibrary" and sets some defaults like where to install that library.
+ As before, we set the \l{Product::files}{files} property with a header:
+ \snippet ../tutorial/chapter-2/lib/lib.h 0
+ And we set the implementation file of our library:
+ \snippet ../tutorial/chapter-2/lib/lib.c 0
+
+ We will keep our library really simple - it only contains one function, which we will later use
+ in our application. The source file requires a \c "CRUCIAL_DEFINE" to be
+ passed to a preprocessor. That is why we set the \l{cpp::defines}{cpp.defines} property:
+ \snippet ../tutorial/chapter-2/lib/lib.qbs 1
+
+ Note that unlike the \l{CppApplication} item, the \l{StaticLibrary} does not pull in the
+ dependency on the \l{cpp} module automatically - that is why we have to pull it in manually
+ using the \l{Depends} item. Without the \l{cpp} module, \QBS would not know how to turn a
+ \c{.c} file into an object file and the object file into a library. See
+ \l{Rules and Product Types} for details.
+
+ Next, we need to tell \QBS where to look for public headers of our library when building
+ products that depend on it. By default, \QBS knows nothing about the layout of our
+ library, so we tell it to look for headers in the library's source directory using the
+ \l{Export} item:
+
+ \snippet ../tutorial/chapter-2/lib/lib.qbs 2
+ You can export any \l{Module} property within the \l{Export} item - it will be merged in the
+ depending product with other properties. For example, you can export
+ \l{cpp::defines}{cpp.defines} or specific \l{cpp::commonCompilerFlags}{compiler flags} that
+ are required to use this product.
+
+ We depend on the \l{cpp} module twice - once within the \l{StaticLibrary}
+ item and once in the \l{Export} item. This is because by default \QBS does not export anything
+ when depending on this product and the dependencies in this item (as well as
+ properties set in this item) are private to this product while dependencies and properties
+ set in the \l{Export} item are for export only.
+
+ Finally, we have some Apple-specific settings. You can skip this part of the tutorial if you
+ are using some other platform. We depend on the \l{bundle} module and set the
+ \l{bundle::isBundle}{bundle.isBundle} to false:
+ \snippet ../tutorial/chapter-2/lib/lib.qbs 3
+ By default, \QBS builds static and dynamic libraries as
+ \l{https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/WhatAreFrameworks.html}{Frameworks}
+ on macOS. So, to keep things simple, we disable the framework build and build a plain old
+ static library file here.
+*/
+
+/*!
+ \previouspage tutorial-2.html
+ \page tutorial-3.html
+ \nextpage tutorial-4.html
+
+ \title Dynamic Library
+
+ Let's now turn our static library into a dynamic library. It is a bit trickier with dynamic
+ libraries since several things should be tweaked. First, we need to be able to mark methods
+ (or classes) in our library as exported. Second, we need to tell our application where to look
+ for our library at run time using \l{https://en.wikipedia.org/wiki/Rpath}{rpaths}.
+
+ Some compilers, like MSVC, require us to mark which symbols we want to export or import. The
+ \l{https://stackoverflow.com/a/6840659}{canonical} way would be to define some helper macros.
+ Let's start with a header that defines those helper macros:
+ \snippet ../tutorial/chapter-3/lib/lib_global.h 0
+
+ This header defines the \c MYLIB_EXPORT macro that expands either to an "export" or to an
+ "import" directive based on the presence of the \c MYLIB_LIBRARY macro. We can use this macro
+ to mark a function as follows:
+ \snippet ../tutorial/chapter-3/lib/lib.h 0
+
+ The modified library product may look like this:
+
+ \snippet ../tutorial/chapter-3/lib/lib.qbs 0
+
+ The most important change is that we changed the item type from \l{StaticLibrary} to
+ \l{DynamicLibrary}. We also added the \c MYLIB_LIBRARY to the list of
+ \l{cpp::defines}{defines}. We do this only when building the library but we are not exporting
+ it - that way the users of our library will have methods marked for import rather than export.
+
+ Finally, we set \l{cpp::sonamePrefix}{cpp.sonamePrefix} to \c "@rpath". This is required only
+ for Apple platforms, see
+ \l{https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/RunpathDependentLibraries.html}{Run-Path Dependent Libraries}
+ for details.
+
+ It is also required to set \l{cpp::rpaths}{cpp.rpaths} in our application file. Since the
+ library is installed to the \c{lib} directory and the application is installed to the \c{bin}
+ directory, we need to tell the loader to look in the \c{lib} directory. The
+ \l{jsextension-fileinfo.html#relativePath}{FileInfo.relativePath} method can help us:
+ \snippet ../tutorial/chapter-3/app/app.qbs 0
+
+ On Linux, this expression would be equivalent to this: \c{cpp.rpaths: ["$ORIGIN/../lib"]}.
+ Don't forget to \c{import qbs.FileInfo} in order to be able to use the
+ \l{jsextension-fileinfo.html} extension.
+
+ To make the example complete, here's how the full \c app/app.qbs file should look like:
+ \snippet ../tutorial/chapter-3/app/app.qbs 1
+*/
+
+/*!
+ \previouspage tutorial-3.html
+ \page tutorial-4.html
+ \nextpage tutorial-5.html
+
+ \title Convenience Items
+
+ As you might have noticed, we are repeating ourselves when setting the same properties in our
+ products - we set \l{Product::version}{version}, \l{Application::install}{install},
+ \l{cpp::rpaths}{cpp.rpaths}, and so on. For a single application and a library, that is not a
+ big deal, but what if we have a dozen libraries? Luckily, this can be achieved using item
+ \l{language-introduction.html#reusing-project-file-code}{inheritance} - we move the common code
+ to the base item and in the real product we will only set what is specific to that product (for
+ example, the list of \l{Product::files}{files}).
+
+ First, we need to tell \QBS where to look for our new base items. This can be achieved using
+ the \l{Project::qbsSearchPaths}{qbsSearchPaths} property. We set this property to \c "qbs" so
+ that \QBS will search our items in the \c{qbs} directory located in the project directory:
+ \snippet ../tutorial/chapter-4/myproject.qbs 0
+
+ \note This directory has a pre-defined structure: base items should be located under the
+ \c{imports} subdirectory. See \l{Custom Modules and Items} for details.
+
+ Let's create a base item for all our applications and move common code there:
+ \snippet ../tutorial/chapter-4/qbs/imports/MyApplication.qbs 0
+
+ As you see, we managed to extract most of the code here, and our application file now only
+ contains what's relevant to it:
+ \snippet ../tutorial/chapter-4/app/app.qbs 0
+
+ Now let's do the same for our library:
+ \snippet ../tutorial/chapter-4/qbs/imports/MyLibrary.qbs 0
+
+ Here, we introduce a helper property, \c libraryMacro, with a default value calculated based
+ on the capitalized product name. Since the name of out library product is \c "mylib", this
+ property will expand to \c "MYLIB_LIBRARY". We can also override the default value
+ for the macro in products that inherit our item like this:
+ \code
+ MyLibrary {
+ libraryMacro: "SOME_OTHER_LIBRARY_MACRO"
+ }
+ \endcode
+
+ Let's take a look at the refactored library file:
+ \snippet ../tutorial/chapter-4/lib/lib.qbs 0
+
+ We managed to extract the reusable parts to common base items leaving the actual products clean
+ and simple.
+
+ Unfortunately, item inheritance comes with a price - when both parent and child items set the
+ same property (\l{cpp::defines}{cpp.defines} in our case), the value in the child item wins.
+ To work around this, the special \l{special-property-values.html#base}{base} value
+ exists - it gives access to the base item's value of the current property and makes it possible
+ to extend its value rather than override it. Here, we concatenate the list of defines from the
+ base item \c{["MYLIB_LIBRARY"]} with a new list, specific to this product (namely,
+ \c{['CRUCIAL_DEFINE']}).
+*/
+
+/*!
+ \previouspage tutorial-4.html
+ \page tutorial-5.html
+ \nextpage tutorial-6.html
+
+ \title Autotest
+
+ Now that we can re-use our base items, let's add a simple autotest. We inherit the new item
+ from the \c MyApplication item and add an \c "autotest" type:
+
+ \snippet ../tutorial/chapter-5/qbs/imports/MyAutoTest.qbs 0
+
+ This additional type is required for the helper \l{AutotestRunner} item. This item runs all
+ products with the \c "autotest" type when it is being built. It also implicitly depends on all
+ such products, so they will be built before running as well.
+
+ Let's add this item to our top-level \l{Project} item:
+
+ \code
+ Project {
+ name: "My Project"
+ minimumQbsVersion: "2.0"
+ // ...
+ AutotestRunner {
+ timeout: 60
+ }
+ }
+ \endcode
+ Here we set the \l{AutotestRunner::timeout}{timeout} property to 60 seconds so that our runner
+ kills tests that run way too long.
+
+ Now we need to add our first test. Let's create a new product with the following content:
+
+ \snippet ../tutorial/chapter-5/test/test.qbs 0
+
+ Here we depend on our library (which we are going to test), set the product
+ \l{Product::name}{name}, and specify the source file, which looks like this:
+ \snippet ../tutorial/chapter-5/test/test.c 0
+
+ The test compares the value from the library with the value from the command line.
+
+ Don't forget to add the new test product to the references property in the Project:
+ \snippet ../tutorial/chapter-5/myproject.qbs 0
+
+ Now we can build the autotest product - this will also launch our test:
+ \code
+ $ qbs build -p "autotest-runner"
+ ...
+ running test mytest [autotest-runner]
+ Build done for configuration default.
+ \endcode
+*/
+
+/*!
+ \previouspage tutorial-5.html
+ \page tutorial-6.html
+ \nextpage tutorial-7.html
+
+ \title Project Properties
+
+ It would be nice if our project was configurable. Let's add some properties to our root project
+ file:
+ \snippet ../tutorial/chapter-6/myproject.qbs 0
+
+ Now we can use those properties in our helper items and in products:
+
+ \snippet ../tutorial/chapter-6/qbs/imports/MyApplication.qbs 0
+
+ Here, we access the project file using the special
+ \l{special-property-values.html#project}{project} value. If the nearest project in the project
+ tree does not have the desired property, \QBS looks it up in the parent project, potentially
+ all the way up to the top-level project.
+ We also use the \l{Application::installDebugInformation}{installDebugInformation}
+ property here. By default, it has the same value as \l{Application::install}{install} but we
+ want to make the debug information install optional.
+
+ Let's now disable the tests if \c project.withTests is \c false:
+
+ \snippet ../tutorial/chapter-6/myproject.qbs 1
+
+ Here we use the \l{Properties} item within the \l{SubProject} item. This item allows to
+ override a subproject's properties which can be useful when adding some other \QBS project as a
+ Git submodule. Of course, it is not very useful in our particular case since we only set the
+ \l{Project::condition}{Project.condition} property. We could achieve the same effect by
+ setting the \l{SubProject::condition}{condition} property of the \l{SubProject} item:
+ \code
+ SubProject {
+ filePath: "test/test.qbs"
+ condition: parent.withTests
+ }
+ \endcode
+ Another way would be to disable the test product. That way, an IDE would still show the whole
+ project tree including disabled tests:
+ \code
+ // qbs/imports/MyAutoTest.qbs
+ MyApplication {
+ condition: project.withTests
+ type: base.concat(["autotest"])
+ }
+ \endcode
+
+ Let's finally make our \l{AutotestRunner} configurable too:
+ \snippet ../tutorial/chapter-6/myproject.qbs 2
+
+ There are several ways to override project properties from the command line. First, the special
+ \c project variable can be used to set the properties of the top-level project:
+ \code
+ $ qbs resolve project.withTests:false
+ \endcode
+
+ You can also refer to properties using project's \l{Project::name}{name}:
+
+ \code
+ $ qbs resolve "projects.My Project.withTests:false"
+ \endcode
+
+ This can again be useful for accessing the properties of external sub-projects. Note that since
+ the project name contains spaces, we use quotes here.
+*/
+
+/*!
+ \previouspage tutorial-6.html
+ \page tutorial-7.html
+ \nextpage tutorial-8.html
+
+ \title Buildconfig Module
+
+ In the previous chapter, we added some properties to our main \l{Project} file. While this is a
+ perfect approach for \e public properties of the project, sometimes we want
+ to add some \e private properties for better tuning. Of course, we could put everything
+ in the \l{Project} file, but that would make it very convoluted. Also, accessing the top-level
+ project all the way from products makes things strongly tied.
+
+ You can also use a \l{Module} that \l{Product}{products} may depend on. That way, a
+ \l{Product} only uses properties of the module it depends on without the need to know about
+ the top-level project.
+
+ Let's create a file named \c{mybuildconfig.qbs} and put it into the
+ \c{qbs/modules/mybuildconfig} directory, near the \c{qbs/imports} directory:
+ \code
+ // qbs/modules/mybuildconfig.qbs
+ Module {
+ }
+ \endcode
+
+ So far, this is just an empty \l{Module} so let's add some properties to it:
+ \snippet ../tutorial/chapter-7/qbs/modules/mybuildconfig/mybuildconfig.qbs 0
+
+ We added the \c appInstallDir and \c libInstallDir properties that will allow us to configure
+ the installation location of the our application and library, respectively.
+
+ Now we can use our module in the \c{MyApplication.qbs} item:
+ \snippet ../tutorial/chapter-7/qbs/imports/MyApplication.qbs 0
+
+ We pull in the new module using the \l{Depends} item, similar to how we pulled in
+ the \l{cpp} module dependency earlier. We also set the \l{Application::installDir}{installDir}
+ property to the corresponding module property, namely to \c{mybuildconfig.appInstallDir}.
+
+ \QBS \l{Module}{modules} have the feature to automatically export properties of other modules.
+ Those exported properties are merged in the resulting product. We can use this feature to set
+ the \l{cpp::rpaths}{cpp.rpaths} in our module rather than in products:
+
+ \snippet ../tutorial/chapter-7/qbs/modules/mybuildconfig/mybuildconfig.qbs 1
+
+ Here, we inject the dependency on the \l{cpp} module and calculate the \c{libRPaths} property.
+ This is a relative path from the \c{product.installDir} (which is either \c{"bin"}
+ or \c{"lib"}, depending on product type to \c{libInstallDir}). Finally, we set
+ \l{cpp::rpaths}{cpp.rpaths} to this property. This way, those \c rpaths will be automatically
+ exported to all products that depend on the \c{mybuildconfig} module.
+
+ Now, we can also use our new module in the library item:
+ \snippet ../tutorial/chapter-7/qbs/imports/MyLibrary.qbs 0
+
+ Let's change the library folder name from \c{"lib"} to \c{"lib64"} when building our project:
+ \code
+ $ qbs modules.mybuildconfig.libDirName:lib64
+ ...
+ $ ls default/install-root/usr/local/
+ bin lib64
+ \endcode
+*/
+
+/*!
+ \previouspage tutorial-7.html
+ \page tutorial-8.html
+ \nextpage tutorial-9.html
+
+ \title Configurable Library
+
+ In this chapter, we will make our library more configurable. We will add configuration options
+ to be able to choose between static and dynamic builds.
+
+ We start with some new properties in the \c mybuildconfig module:
+ \code
+ Module {
+ ...
+ property bool staticBuild: false
+ property bool installStaticLib: true
+ ...
+ }
+ \endcode
+
+ We need to do some modifications to export macros in the \c lib/lib_global.h header:
+ \snippet ../tutorial/chapter-8/lib/lib_global.h 0
+
+ Here' we added a new branch when \c MYLIB_STATIC_LIBRARY is defined. In that case, we make
+ the \c MY_LIB_EXPORT macro empty.
+
+ Now, let's modify the \c qbs/imports/MyLibrary.qbs file as follows:
+ \snippet ../tutorial/chapter-8/qbs/imports/MyLibrary.qbs 0
+
+ First thing to notice is that we changed the type of the item from \l{DynamicLibrary} to the
+ \l{Library} item which is a common base item for dynamic and static libraries.
+
+ Second, we change the \l{Product::type}{type} of the product so it depends on the \c staticBuild
+ property:
+ \code
+ type: mybuildconfig.staticBuild ? "staticlibrary" : "dynamiclibrary"
+ \endcode
+
+ Third, we change our \e{export macro} to be different in the static and dynamic builds to
+ correspond with the changes we made to the \c lib_global.h:
+ \code
+ readonly property string _nameUpper : name.replace(" ", "_").toUpperCase()
+ property string libraryMacro: _nameUpper + "_LIBRARY"
+ property string staticLibraryMacro: _nameUpper + "_STATIC_LIBRARY"
+ cpp.defines: mybuildconfig.staticBuild ? [staticLibraryMacro] : [libraryMacro]
+ \endcode
+
+ Note that in a static build we export the \c MYLIB_STATIC_LIBRARY macro so that the dependent
+ products will know whether they link to a static or dynamic library:
+ \code
+ Export {
+ ...
+ cpp.defines: exportingProduct.mybuildconfig.staticBuild
+ ? [exportingProduct.staticLibraryMacro] : []
+ }
+ \endcode
+
+ Now we can build our project in dynamic or static mode:
+ \code
+ $ qbs resolve modules.mybuildconfig.staticBuild:false && qbs build
+ ...
+ $ ls default/install-root/usr/local/lib/
+ libmylib.1.0.0.so
+ libmylib.1.0.so
+ libmylib.1.so
+ libmylib.so
+ $ rm -r default
+ $ qbs resolve modules.mybuildconfig.staticBuild:true && qbs build
+ ...
+ $ $ ls default/install-root/usr/local/lib/
+ libmylib.a
+ \endcode
+*/
+
+/*!
+ \previouspage tutorial-8.html
+ \page tutorial-9.html
+ \nextpage howtos.html
+
+ \title Version Header
+
+ To create new files, such as version headers, during the build, use \l{Rules}. Every command
+ \QBS executes, such as compile or linker commands, is described by a corresponding Rule in a
+ Module or a Product.
+
+ In this section, we will create a simple header with a string constant based on the variable
+ in our project.
+
+ First, we add this variable to our \c mybuildconfig module:
+ \snippet ../tutorial/chapter-9/qbs/modules/mybuildconfig/mybuildconfig.qbs 0
+
+ Next, we create a new file, \c{version.h.in}, located in the \c{version-header} directory. This
+ file contains the template for our header:
+ \snippet ../tutorial/chapter-9/version-header/version.h.in 0
+
+ Now we create a file called \c{version-header.qbs} in the same directory. This file contains
+ a \l{Product} with a \l{Rule} that turns the \c{version.h.in} into a real header.
+ Let's go through the contents of the file:
+ \snippet ../tutorial/chapter-9/version-header/version-header.qbs 0
+
+ First, we import \l{TextFile Service}{TextFile}. We will need this class to read the template
+ and write the resulting header. Second, we declare a new \l{Product} named \c{"version_header"}
+ and with the \c{"hpp"} type. This is the type of the artifact we will create in the Rule.
+ Third, we add the dependency on the \c mybuildconfig module to use the new
+ \c mybuildconfig.productVersion variable.
+
+ We also add a \l{Group} with the template file and assign the \c{version_h_in} tag to the file:
+ \snippet ../tutorial/chapter-9/version-header/version-header.qbs 1
+
+ \QBS Rules work with file tags, instead of working with files directly, which makes
+ it easy to reuse rules. The name of the tag is chosen arbitrarily here. We could use the name
+ of the file as a tag, but to avoid confusion between file name and file tag, we use underscores
+ in the tag instead of dots.
+
+ Now we can create a Rule itself:
+ \snippet ../tutorial/chapter-9/version-header/version-header.qbs 2
+ Here, we specify that our Rule takes files tagged as \c "version_h_in" and produces an
+ \l{Artifact} with the name \c "version.h" and tagged \c "hpp". By default, files are created in
+ the \l{Product::destinationDirectory}{Product.destinationDirectory} folder. We add the \c "hpp"
+ tag for the header as this is the tag the \l{cpp}{cpp module} uses for headers. That way, \QBS
+ can track changes and process our generated file the same way it treats all other
+ headers. Note that earlier we set the product type to \c "hpp" as well. \QBS requires that
+ artifact type should match the product type directly or be accessible via the chain of Rules.
+ Otherwise, the Rule won't be executed. For details, see the \l{Rules and Product Types}
+ section.
+
+ The actual code generation happens in the \l{Rule::prepare}{Rule.prepare} script:
+ \snippet ../tutorial/chapter-9/version-header/version-header.qbs 3
+
+ In this script, we create a \l {JavaScriptCommand} object and set some meta properties, such as
+ the description and highlight. For details about Commands, see
+ \l{Command and JavaScriptCommand}. In the sourceCode variable, we create a JavaScript
+ function that opens the \l{The inputs and outputs Variables}{input file}, reads its content
+ using the \l{TextFile Service}{TextFile} object, replaces the \c "${PRODUCT_VERSION}"
+ placeholder with the actual value in the \c product.mybuildconfig.productVersion variable, and
+ writes the resulting content into the \l{The inputs and outputs Variables}{output file}.
+
+ Finally, we export the \l{Product::buildDirectory}{exportingProduct.buildDirectory} so that
+ products that depend on this product can include our generated header:
+
+ \snippet ../tutorial/chapter-9/version-header/version-header.qbs 4
+
+ The full content of the file should look like this:
+
+ \snippet ../tutorial/chapter-9/version-header/version-header.qbs 5
+
+ Let's now add our Product into the root project so \QBS will be aware of it:
+ \snippet ../tutorial/chapter-9/myproject.qbs 0
+
+ We also need to add the dependency on the \c "version_header" to our application:
+ \snippet ../tutorial/chapter-9/app/app.qbs 0
+
+ Now we can include the header in the \c main.c file and print the contents of the string
+ constant:
+
+ \snippet ../tutorial/chapter-9/app/main.c 0
+
+ Let's try and run our application. You should see something like this:
+ \code
+ $ qbs run -p "My Application"
+ Starting target. Full command line: .../default/install-root/usr/local/bin/myapp
+ Hello, world
+ Hello from library
+ ProductVersion = 1.0.0
+ \endcode
+*/