gbuild introduction – LibreOffice build system part 1

LibreOffice uses a build system called gbuild which uses GNU Make. Migrating from the old build system to gbuild started in the OpenOffice days, but the migration took a while and a lot of effort, finishing around LibreOffice 4.1.

This LibreOffice build system uses GNU Make, Perl and Python, so you need to have these prerequisites in order to be able to build LibreOffice. However, LibreOffice bundled Python can be used.

To get a nice description, just try this inside the LibreOffice core source folder:

make help

Structure of gbuild

You can find gbuild in solvenv/gbuild folder of the LibreOffice core source code. There are many macros available in gbuild that are useful when doing the actual build. Let’s start from a simple one that creates a nice output.

If you look at the build output, you see many three letter outputs. They are short forms denoting the category of what is being built, for example, [BIN] means binary, [MOD] means module, and [ALL] is what it is! There are other short names like [CXX] for compiling C++ files, [C ] for compiling C files, and [LNK] for the linking.

...
[BIN] postprocess
[MOD] postprocess
[MOD] libreoffice
[BIN] top level modules: libreoffice
[ALL] top level modules: build-non-l10n-only build-l10n-only
...

These are the outputs, generated by a macro named gb_Output_announce. This macro does the printing, and its code is available in “solenv/gbuild/Output.mk”

define gb_Output_announce
$(info $(call gb_Output_announce_str,$(1),$(2),$(3),$(4)))
endef

Then, it calls this macro:

$(call gb_Output_announce,$*.cxx,$(true),CXX,3)

And, you will see the nice result in the output which contains [CXX]. You can see that another macro, gb_Output_announce_str is called here, that creates the output.

Other gbuild Macro Examples

There are many other macros available for developers. You find the makefiles with the .mk extensions, and you see a lot of them for the executables, libraries, and tests.

For example, let’s take a look at the xmlscript folder. Here are the .mk files:

1) xmlscript/CppunitTest_xmlscript_cppunit.mk
2) xmlscript/Module_xmlscript.mk
3) xmlscript/Library_xmlscript.mk
4) xmlscript/Package_dtd.mk

The makefile #1 is the CppunitTest_xmlscript_cppunit, which is used for adding a test, which can be run by:

make CppunitTest_xmlscript_cppunit

The makefile #2 is the main makefile for the module, which in turn, invokes makefile #3, which builds the xmlscript library, and #4, which creates the xmlscript dtd package, and also makefile #1 which contains the tests. This code does the job:

$(eval $(call gb_Module_Module,xmlscript))

$(eval $(call gb_Module_add_targets,xmlscript,\
Library_xmlscript \
Package_dtd \
))

$(eval $(call gb_Module_add_check_targets,xmlscript,\
CppunitTest_xmlscript_cppunit \
))

As you can see, gb_Module_Module, gb_Module_add_targets and gb_Module_add_check_targets are the macros that are invoked to make this happen. All of these macros are defined in solenv/gbuild/Module.mk. In this file, you get this overview:

# Overview of dependencies and tasks of Module
#
# target                      task                         depends on
# Module                      build the product            all product targets
#                              excluding tests             recursive Modules
# Module/unitcheck            run unit tests               all unit tests
#                                                          recursive Module/checks
# Module/slowcheck            run all slow unit tests
# Module/screenshot           create all screenshots
# Module/subsequentcheck      run system tests             all system tests
# Module/uicheck              run uitests                  all uitests
#                                                          recursive Module/subsequentchecks
# build (global)              build the product            top-level Module
# unitcheck (global)          run unit tests               top-level Module/unitcheck
# slowcheck (global)          run slow unit tests          top-level Module/slowcheck
# screenshot (global)         create all screenshots       top-level Module/screenshot
# subsequentcheck (global)    run system tests             top-level Module/subsequentcheck
# perfcheck (global)          run performance unit tests   top-level Module/perfcheck
# uicheck (global)            run the uitests              run all uitests

For the start, you may not need to know all the details of gbuild. You may only need to modify a makefile, add a C/C++ file, or a test. In many cases, even for the new makefiles, you can find examples from several LibreOffice modules. Try to find similar sub-projects and use them as the templates, while applying some changes to match your needs.

Further Reading

I will try to write more about the LibreOffice build system in the future. But for now, if you refer to the previous presentations in LibOCon/FOSDEM, you will find nice related presentations, including these: