Compile GSettings Schemas Safely with glib-compile-schemas
You will compile a directory of GSettings XML schemas into gschemas.compiled, check the input without writing, and keep vendor overrides in the order you expect. The examples match GLib 2.86.4, provided here by the Debian package libglib2.0-bin version 2.80.0-6ubuntu3.9. The program version and package version can differ, so use the command's own output when documenting another host.
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 and a directory containing readable .gschema.xml files. Compilation is normally an unprivileged build or packaging step. Installing the resulting file under /usr/share usually needs sudo, but this guide first uses a temporary directory and changes no system files.
1. Check the installed compiler
Confirm the executable and its version before relying on an option in a build script:
$ command -v glib-compile-schemas
/usr/bin/glib-compile-schemas
$ glib-compile-schemas --version
2.86.4
$ dpkg-query -W -f='${Package} ${Version}\n' libglib2.0-bin
libglib2.0-bin 2.80.0-6ubuntu3.9
Your paths or package version may differ. The important contract is that the command takes one schema directory, and the XML files it considers have names ending in .gschema.xml.
2. Put schemas in a dedicated directory
Keep the XML source and its compiled output together unless your packaging layout requires a separate target. This small schema is enough to test the workflow:
<schemalist>
<schema id="com.example.Dixon" path="/com/example/Dixon/">
<key name="enabled" type="b">
<default>true</default>
<summary>Enable the example feature</summary>
<description>Whether the example feature is enabled.</description>
</key>
</schema>
</schemalist>
Save it as com.example.Dixon.gschema.xml. The schema ID and key name are part of the configuration API, so changing them later can leave applications looking for a different setting. The path is also part of the schema declaration; use the path required by the application rather than copying this example blindly.
Checkpoint: list the directory and check that the filename ends exactly in .gschema.xml:
$ find /path/to/schemas -maxdepth 1 -type f -printf '%f\n'
com.example.Dixon.gschema.xml
3. Validate without creating a binary
Run a dry run before writing output. Add --strict so an error cannot be hidden by silently omitting a faulty schema:
$ glib-compile-schemas --strict --dry-run /path/to/schemas
$ printf 'exit status: %s\n' "$?"
exit status: 0
A quiet return to the prompt and status 0 mean the installed compiler accepted the input. --dry-run does not write gschemas.compiled. If validation fails, read the reported filename and XML error, fix the source, then repeat this step. Do not treat a successful dry run as proof that the application will find the schema at runtime; lookup also depends on the installation directory and environment.
The --strict warning is easy to miss. Without it, the compiler can omit faulty schema files from its result. That may produce a binary which exists but is incomplete. Strict mode is the safer default for CI and package builds.
4. Add an ordered vendor override
A vendor override is a key file whose group name is the schema ID and whose values use serialised GVariant syntax. Give it the .gschema.override suffix:
[com.example.Dixon]
enabled=false
Save it as 10_example.gschema.override in the same directory. Override filenames conventionally start with a two-digit number. A higher number wins when two files set the same key, so a later package can use 20_example.gschema.override to take precedence over 10_example.gschema.override. This changes the default supplied to applications; it does not change a user's stored setting.
Keep overrides under review. A misplaced group name, a value with invalid GVariant syntax, or an unexpected numeric prefix can make a package appear to ignore its intended defaults. Run the strict dry run again after adding or changing an override.
5. Write and verify the compiled file
Once the dry run passes, compile the directory:
$ glib-compile-schemas --strict /path/to/schemas
$ test -s /path/to/schemas/gschemas.compiled
$ printf 'compiled schema is present\n'
compiled schema is present
The normal output filename is always gschemas.compiled. The command may replace an existing file, so treat this as a state-changing step: choose the correct directory and keep a package or build-system copy of the source. If a rebuild leaves a result you do not want, remove only that generated file and rerun the build from the XML sources. Do not delete the XML files to clean up the binary.
6. Use a separate target directory when packaging
Use --targetdir when the source directory is read-only or your staging tree has a different layout:
$ mkdir -p /tmp/schema-stage
$ glib-compile-schemas --strict --targetdir /tmp/schema-stage /path/to/schemas
$ test -s /tmp/schema-stage/gschemas.compiled
$ printf 'staged compiled schema is present\n'
staged compiled schema is present
The target directory must already exist. The source directory still supplies the XML and override files, while the generated binary is written to the target. In a package build, install the XML files and the compiled file in the same runtime schema directory, normally /usr/share/glib-2.0/schemas. Writing there is an administrative operation:
$ sudo install -m 0644 /tmp/schema-stage/gschemas.compiled /usr/share/glib-2.0/schemas/
Do not use sudo for compilation in a working tree. If the install command fails, inspect ownership and package policy rather than making the whole schema directory writable.
7. Remember how applications find schemas
At runtime, GSettings searches the glib-2.0/schemas subdirectory of each directory named by XDG_DATA_DIRS. The usual system location is /usr/share/glib-2.0/schemas. A compiled file in an arbitrary build directory will not automatically be visible to an installed application.
For a local test, put a staging tree in the expected shape and point XDG_DATA_DIRS at its parent. This is an environment change for the process you launch, not a system-wide configuration change:
$ find /tmp/schema-stage -maxdepth 3 -type f -name gschemas.compiled -print
/tmp/schema-stage/share/glib-2.0/schemas/gschemas.compiled
$ XDG_DATA_DIRS=/tmp/schema-stage/share:/usr/local/share:/usr/share your-gsettings-client
Replace your-gsettings-client with the program you are testing. If it still reports a missing schema, check the schema ID, the directory shape, and the process environment before recompiling.
Done means
glib-compile-schemas --strict --dry-run DIRECTORYreturns status 0.- Schema files use the
.gschema.xmlsuffix and overrides use.gschema.override. - The generated
gschemas.compiledis in the directory the application or package will actually read. - Any elevated install was limited to the intended file, and the XML sources remain available for recovery.