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 lib directory and add it to the references property in our project. The modified project may look like this:

Project {
   name: "My Project"
   minimumQbsVersion: "2.0"
   references: [
       "app/app.qbs",
       "lib/lib.qbs"
   ]
}

Let's take a look at the the library file now:

StaticLibrary {
    name: "mylib"
    files: [
        "lib.c",
        "lib.h",
    ]
    version: "1.0.0"
    install: true

    Depends { name: 'cpp' }
    cpp.defines: ['CRUCIAL_DEFINE']

    Export {
        Depends { name: "cpp" }
        cpp.includePaths: [exportingProduct.sourceDirectory]
    }

    Depends { name: 'bundle' }
    bundle.isBundle: false
}

It contains the StaticLibrary item which sets the type of the product to "staticlibrary" and sets some defaults like where to install that library. As before, we set the files property with a header:

// lib/lib.h
#ifndef LIB_H
#define LIB_H

const char *get_string();

#endif // LIB_H

And we set the implementation file of our library:

// lib/lib.cpp
#include "lib.h"

#ifndef CRUCIAL_DEFINE
#   error CRUCIAL_DEFINE not defined
#endif

const char *get_string()
{
    return "Hello from library";
}

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 "CRUCIAL_DEFINE" to be passed to a preprocessor. That is why we set the cpp.defines property:

Depends { name: 'cpp' }
cpp.defines: ['CRUCIAL_DEFINE']

Note that unlike the CppApplication item, the StaticLibrary does not pull in the dependency on the cpp module automatically - that is why we have to pull it in manually using the Depends item. Without the cpp module, Qbs would not know how to turn a .c file into an object file and the object file into a library. See 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 Export item:

Export {
    Depends { name: "cpp" }
    cpp.includePaths: [exportingProduct.sourceDirectory]
}

You can export any Module property within the Export item - it will be merged in the depending product with other properties. For example, you can export cpp.defines or specific compiler flags that are required to use this product.

We depend on the cpp module twice - once within the StaticLibrary item and once in the 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 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 bundle module and set the bundle.isBundle to false:

Depends { name: 'bundle' }
bundle.isBundle: false

By default, Qbs builds static and dynamic libraries as Frameworks on macOS. So, to keep things simple, we disable the framework build and build a plain old static library file here.

© 2022 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. 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.