[TOC]
GIBS - Generally In-source Build System
Note: This branch contains gibs written in pure C++ and is a WORK IN PROGRESS
If you look for something that can be used, check out master_qt branch, although it is heavily outdated!
GIBS (in-source build system) is a build tool that makes it easier to build C++ projects by using the information from source code to compile it.
In short, to compile a project it is enough to run:
gibs main.cppInstead of "the old way":
qmake project.pro
makePrecompiled gibs releases can be found on releases page
Alternatively, get the source code and compile gibs using cmake. C++14 is required.
Apart from this README here, full doxygen documentation... is not available at this time.
A typical usage of gibs would be to call it on your main source file (of your app or libary):
gibs main.cppTo clean the project, run:
gibs --clean main.cppSpecifying the source file is not necessary - it will be extracted from gibs cache file generated during compilation, or default to main.cpp when the cache is empty.
To see all available flags, type:
gibs --helpOptions:
-h, --help Displays this help information and
exits.
-v, --version Displays gibs version info and exits.
-r, --run Run the executable immediately after
building.
-d, --debug Compile in debug mode. By default,
gibs compiles release binaries.
-q, --quick 'Convention over configuration' mode
- parse files only up to first line of
'concrete code'. Do not check file checksums
when doing incremental builds.
--verbose Sets log level to 'Verbose'. If more
than one log level is specified, or log
level is combined with --verbose, only
the last flag is taken nto account
-l, --log-level Sets log level to one of: silent,
error, warning, information, debug,
verbose. Logs are printed for selected
level and all levels above it. For example,
when information is set, all error,
warning and information logs will be
printed, but no debug or verbose ones.
'silent' setting will not print any logs
at all. Log level parser is case-sensitive,
please make sure to provide log levels
in lower case. If more than one log
level is specified, or log level is
combined with --verbose, only the last
flag is taken into account.
--log-file-path Duplicates all console logs into this
file. If the file does not exist, it will
be created. If the file does exist, it
will be cleared and written to. If a path
to a directory is provided, a log file
called 'gibs-<datetime>.log will be
created.
--no-color Disables color in log messages.
--dry-run Does not actually run any compilation
or linking commands. Commands are only
printed out but not executed.
--log-process-output Prints standard and error outputs
from spawned processes (compiler, linker
etc.).
-c, --compiler, --compiler-set Selects the compiler set to use: gcc,
clang, apple-clang. Defaults to apple-clang
on macOS and gcc elsewhere.
input Path to the input file or directory
to build. If a directory is provided,
gibs will look for files with supported
extensions in it and its subdirectories.
If a file is provided, gibs will try to
build it. If no input is provided, gibs
will try to build a file called 'main'
with a supported extension in the current
directory.
-- Other, user-defined arguments passed
to the program should be placed after
this separator. For example: 'gibs
--main.cpp -- --my-flag' will enable feature
'my-flag', and 'gibs --main.cpp --
--my-flag=OFF' will disable it when compiling
main.cpp.
Gibs builds in release mode by default. If you want to compile a debug build,
use --debug or -d.
To save you typing, gibs will remember paths between runs, so you need to specify them only once.
Remembered paths are:
- Qt dir
- deployer path
- sysroot path
- toolchain path
- Android NDK path
- Android NDK API level
- Android NDK ABI level
- Android SDK path
- Android SDK API level
- jdk (Java) path
Paths precedence is:
- Paths passed on command line.
- Paths saved in current directory.
- Paths saved in $HOME/.config/gibs
To get additional functionality and specify external libraries, sources etc. you can use gibs commands inside comments of your C++ code.
You can use one-line command syntax:
//i some command
Or comment scope:
/*i
some command
other command
*/
You can specify an extra source file to compile like this:
//i source my_source_file.cpp
This is especially useful for cases where gibs cannot guess the source file for given header.
Targets are applications or libraries that gibs is compiling and linking.
- to create an executable or library with a given name:
//i executable name MyAwesomeApp
//i library name MyAwesomeLibrary
If no other information is provided, gibs will assume it is compiling an executable and it will be named the same as parent directory name.
- libraries can additionally be marked as static or dynamic. Libraries are dynamic by default
//i library MyAwesomeLib type static
//i library MyAwesomeLib type dynamic
To pass custom defines to the compiler, use the following command:
//i define MY_DEFINE
Include paths are specified using include command:
//i include some/path
If a path to a directory is provided, it will be added to C++ include paths (-I).
If a path to gibs project file is provided, the file will be loaded and parsed.
If a path to a C++ header file is provided, it will be parsed by gibs and potentially the corresponding source file will be compiled.
To include and link to an external library, you need to specify both the include and gibs commands.
//i include library some/path
//i include library -Lsome/path -llibrary1 -llibrary2
This command allows to generate an output file (which can be compiled if necessary) based on an input schema - with predefined variables replacing templates with real values.
This is a very similar concept to CMake's configure_file().
//i configure file input something.h.in output something.h
//i replace "some-text" with target.main.name()
The first line above specifies the input file and the generated file path. The following lines (read until the end of comment block, or first empty line) specify which text should be replaced with which values.
Built-in gibs values and functions are matched and replaced automatically, so there is no need to write for example:
//i replace ${gibs.main.name()} with gibs.main.name()
because the value will be replaced automatically.
Gibs makes it easier to build other Qt projects.
In order to compile a Qt application or library, you need to specify Qt
directory by running gibs with --qt-dir flag:
gibs --qt-dir /home/qt/6.8.1/gcc_64 main.cppThis will tell gibs which Qt version should it use. Then, in the source code of your application or library, you need to specify Qt modules which should be loaded.
//i qt core network
To run Qt tools, use the tools command:
//i tool rcc myResource.qrc myOtherResource.qrc
You do not need to run MOC manually, gibs will run it automatically when needed.
Gibs can run external tools, applications and processes. To do this, use the tool
command, followed by executable path and any necessary arguments.
There are some tools which are pre-configured (like Qt's tools: rcc and uic)
and you don't need to specify their paths.
//i tool myexecutable.exe --some -a -r -g -s
Ibs can compile collections of projects in one go. This is especially useful in bigger projects, where you - for example - might have an application and a library used by that app.
If a subproject is a library, it will be automatically linked with your main app. There is no need to manually specify include paths or lgibs in that case.
(not implemented) If a subproject is another application, it will not be connected to the "main" app. The executables will be placed in the same directory.
(not implemented) If a subproject is a plugin, gibs will create the plugin and copy it to the same directory as the main app. No further linking will be preformed.
Specifying a subproject is extremely easy:
//i subproject path/to/subproject.h
Ibs will not synchronise until it is absolutely necessary: main app and the subproject will be compiled in parallel. Only when linking, gibs will wait for the library to be ready before linking the app.
See: Features.
Feature (also called Option) is a compile-time piece of functionality that can be turned on or off.
A feature can be easily turned on or off via a command line flag (during
compilation). Internally, feature always adds a compiler define when it is turned
on. For example, if feature named tts-support is added, your C++ code will see
TTS_SUPPORT ifdef as being true. You can use this in code to respond to the
feature being active or not.
A feature can come with it's own set of C++ files. These are pointed to by feature definition.
TODO: how to define which files belong to a feature?
To define a feature, use this syntax:
//i feature tts-support [default on|off]
Or:
//i option tts-support [default on|off]
Then you can select the feature next time you build your project, like this:
gibs main.cpp -- --tts-supportOr unselect it using:
gibs main.cpp -- --no-tts-supportOn / off syntax is also supported:
gibs main.cpp -- --tts-support=OFF
gibs main.cpp -- --tts-support=ONIt's best to put gibs commands early in .cpp or .h file, so that they can be parsed before the rest of includes. Otherwise it may happen that you define include folder after it was needed.