Build Environment Effort/Gbuild Bootstrapping
How gbuild starts up from a makefile
When gbuild is started with a "make" command the initial makefile in the module or repository root will:
- check if there is an basic environment set
- set the variable GBUILDDIR to the directory where the gbuild system is found
- include gbuild.mk from that directory (see details below)
- all the declarations of targets relative to the current directory (module makefile)
- all the declarations of targets in all repos
- build all target needed for the goal
What gbuild.mk does when it is included in the makefile
- It sets a few global variables: SHELL, true, false, NEWLINE, WHITESPACE, COMMA
- It includes $(GBUILDDIR)/Output.mk for the output helper functions (announce, error ...)
- It includes $(GBUILDDIR)/BuildDirs.mk to setup the variables WORKDIR, OUTDIR, REPODIR
- It set up some global variables: gb_PRODUCT, gb_DEBUGLEVEL, gb_ENABLE_PCH, gb_FULLDEPS
- It includes $(GBUILDDIR)/Helper.mk for the global registries and misc. helper functions
- It includes $(GBUILDDIR)/TargetLocations.mk for the functions that return the filesystem paths for targets
- It sets up the global registries
- It reads all the Repository.mk files in the repository root (from gb_REPOS). This:
- sets up the name for the repository (for example: SRCDIR)
- sets up the group a library or executable belongs to
- It then reads the platform specific part from $(GBUILDDIR)/platform. This:
- sets up the layer a library/executable belongs to by the group of the library
- sets up the filename of the libraries and executables by the group of the library (on windows, this is the lib-file)
- sets up the dll filename of the library (windows only)
- sets up the rpaths for the layers (solaris and linux only - and macosx in its own special way)
- It then reads the RepositoryFixes.mk files in the repository root (from gb_REPOS). This is to keep compatibility with some unwarranted creativity in naming libraries. For example the default filenames created for the platform can be overwritten here.
- It then collects all the libraries that are known from the registries. Linking is only allowed against known libraries.
- It then sets up the global defines for C/C++ compilation
- It then reads $(GBUILDDIR)/Deliver.mk for the copy to OUTDIR commands and the collecting of filenames for the deliver.log
- It then reads all the specific classes with the build rules for the targets: ComponentTarget, AllLangResTarget, LinkTarget, ....
- It then reads any file ending with .mk in $(GBUILDDIR)/extensions
library/executable groups, layers, filename and dll filename registries
- Each library and execuatble is in a group. Valid groups are listed in gb_Library_VALIDGROUPS and gb_Executable_VALIDGROUPS.
- The platform file has to set the layer, the filename and (on windows) the dll filename for a library or executable.
- The layer is stored in a registry in the variables gb_Library_LAYER and gb_Executable_LAYER
- The filename is stored in a registry in the variables gb_Library_FILENAMES and gb_Executable_FILENAMES
- The dll filename is stored in a registry in the variables gb_Library_DLLFILENAMES
The registry is a whitespace separated list of key value pairs. The key and value are again separated by a colon. E.g.
gb_Library_FILENAMES := sw:libswlx.so cppu:libuno_cppu.so jvmfwk:libjvmfwk.so salhelper:libuno_salhelpergcc3.so ...
To get a value for key $(KEY) from a registry $(REGISTRY) the following form is used:
$(patsubst $(KEY):%,%,$(filter $(KEY):%,$(REGISTRY)))
Keys can contain everything but whitespace and colon and must be escaped with $(subst) otherwise. Values can contain everything but whitespace and must be escaped $(subst) otherwise. Example escaping functions:
- Key encode:
NULL := WHITESPACE := $(NULL) $(NULL) $(subst $(WHITESPACE),\WS,$(subst :,\C,$(subst \,\BS,$(1))))
- Key decode:
NULL := WHITESPACE := $(NULL) $(NULL) $(subst \BS,\,$(subst :,\C,$(subst \WS,$(WHITESPACE),$(1))))