Build and Verify a GLib Resource Bundle with glib-compile-resources
You will compile a small GResource XML manifest into a binary .gresource bundle, generate the equivalent C source when a build needs it, and inspect the files that control rebuilds. The examples use glib-compile-resources 2.86.4 from Ubuntu package libglib2.0-dev-bin 2.80.0-6ubuntu3.9.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about fifteen minutes. You need a shell, the command itself, and a directory containing an XML resource description plus the files it names. The normal workflow is unprivileged. Do not use sudo unless your chosen input or output directory is deliberately restricted, and fix its ownership or permissions instead when that is your system to administer.
1. Check the installed command
Confirm which executable is on your path and record its version. This changes nothing:
$ command -v glib-compile-resources
/usr/bin/glib-compile-resources
$ glib-compile-resources --version
2.86.4
$ dpkg-query -W -f='${Package} ${Version}\n' libglib2.0-dev-bin
libglib2.0-dev-bin 2.80.0-6ubuntu3.9
Checkpoint: if the command is missing, stop here and install the development-bin package through your normal package-management process. The rest of this guide assumes that the version and package lookup succeed.
2. Create a resource description
A resource description is XML. Its <file> entries name files that will be placed in the bundle, while the prefix controls the resource path used by the application. Put this manifest and its input file in one working directory:
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/example">
<file>message.txt</file>
</gresource>
</gresources>
Save it as resources.gresource.xml, and create a sibling file called message.txt. The file name is resolved from the current directory unless you supply --sourcedir. This is the first common trap: the XML file's location does not silently make every relative input path valid.
Checkpoint: make sure the exact input exists before compiling:
$ test -r message.txt && echo 'message.txt is readable'
message.txt is readable
$ test -r resources.gresource.xml && echo 'manifest is readable'
manifest is readable
3. Compile a binary bundle
Use --target to choose the output explicitly. With --generate, the target extension selects the output format. A .gresource target is a binary resource bundle:
$ glib-compile-resources \
--generate \
--target=resources.gresource \
resources.gresource.xml
$ file resources.gresource
resources.gresource: GVariant Database file, version 0
The command writes no progress message on success. A zero exit status and a non-empty target are the useful checks. Shell redirection is not involved, but the target is still a state-changing output operation: choose a new name or make a backup before replacing a bundle that another build or application still uses.
If the input files live elsewhere, make that location explicit:
$ glib-compile-resources \
--generate \
--sourcedir=/path/to/resource-files \
--target=/path/to/build/resources.gresource \
/path/to/resource-files/resources.gresource.xml
Both the manifest and the referenced files must be readable. The command does not create missing source directories or invent missing files. If compilation fails, keep the previous target and correct the path or XML before trying again.
4. Generate C source for linking
Some applications compile the resource data into their executable or library instead of installing a separate bundle. Select a .c target with --generate:
$ glib-compile-resources \
--generate \
--target=resources.c \
--c-name=app_resources \
resources.gresource.xml
$ sed -n '1,8p' resources.c
#include <gio/gio.h>
#if defined (__ELF__) && ( __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 6))
# define SECTION ...
The generated file contains the resource bytes and registration code. Keep it as a build artefact rather than editing it by hand. The --c-name value supplies the prefix for generated C identifiers, so use a stable identifier that will not collide with another resource in the same program.
--generate-source is the explicit equivalent when you want C source regardless of the target extension. Add --generate-header when your C build also needs the header for that generated source. On uncommon compilers without constructor support, --manual-register generates functions that application code must call during initialisation and uninitialisation. Do not add that option unless your compiler or integration requires it.
5. Track dependencies in the build
Ask the compiler for the files named by the manifest before wiring them into a build rule:
$ glib-compile-resources \
--generate-dependencies \
--sourcedir=. \
resources.gresource.xml
message.txt
This output is intended for build systems. For a dependency file in the style of gcc -M -MF, combine normal generation with --dependency-file:
$ glib-compile-resources \
--generate \
--target=resources.gresource \
--dependency-file=resources.d \
resources.gresource.xml
$ sed -n '1,4p' resources.d
resources.gresource: resources.gresource.xml message.txt
The exact quoting and line wrapping in a dependency file can vary, so inspect it rather than matching one line byte for byte. --generate-phony-targets adds phony targets when you use --dependency-file and need make-style missing-file handling.
6. Diagnose failures without changing the system
A missing referenced file normally produces an error naming that file and a non-zero exit status. Check the path from the same directory and with the same source directory that the build uses:
$ glib-compile-resources --generate \
--sourcedir=. \
--target=/tmp/check.gresource \
resources.gresource.xml
$ printf 'exit status: %s\n' "$?"
exit status: 0
Use a temporary target for a diagnostic build when you do not want to overwrite the real artefact. If the XML names message.txt but it is elsewhere, either correct the manifest or use the appropriate --sourcedir. Do not solve a path error by running the build as root.
Preprocessing options in the XML can call external tools. The command looks for xmllint through PATH, or uses the full path in XMLLINT; similar lookup rules apply to gdk-pixbuf-pixdata and json-glib-format for their respective preprocessing options. Keep those tools in the build environment and record the chosen paths when reproducibility matters.
Done means
- The installed command and package version are known.
- The XML manifest and every referenced file are readable from the selected source directory.
- A binary
.gresourcetarget was created and checked without overwriting an unverified artefact. - The C output mode, when needed, uses a deliberate identifier prefix and is treated as generated code.
- Dependency output is available for the build system, and missing-file errors can be investigated without elevated privileges.