Ruby bindings for Xmlb, libxmlb, querying the binary XML blobs AppStream metadata is compiled into.
require "libxmlb"
Xmlb.constants.size # the whole namespace, from the typeliblibxmlb.lib ships a GObject Introspection typelib that describes every class,
method, property and signal it has. Xmlb::Loader — twenty lines — hands that
typelib to ruby-gnome's GObjectIntrospection::Loader, which defines the Ruby
classes from it at require time.
So this gem is pure Ruby: no extension of its own, no Cargo workspace, no per-platform binary. You get the whole library rather than the subset somebody got round to wrapping by hand, and it does not drift when libxmlb.lib gains API.
It is worth being precise about what that does and does not buy you at install
time. gem install libxmlb still compiles C, because gobject-introspection and
glib2 are themselves native extensions built against glib — so a compiler and
glib's development headers are needed. What this gem adds on top of that is
nothing: those two are what every ruby-gnome application already has, since
gtk4 depends on them. If you are writing a Ruby GTK app, libxmlb costs you no
build step you were not already paying.
This is how ruby-gnome itself ships gtksourceview5, libsecret and the rest.
The typelib is in the package's lib output, not its default one -- pkgs.libxmlb.lib.
The typelib is a C-library artefact, so it belongs to your distribution and this gem cannot install it:
| Debian / Ubuntu | gir1.2-xmlb-2.0 |
| Fedora | libxmlb |
| Arch | libxmlb |
| nix | pkgs.libxmlb.lib |
If it is not in the default search path, point GI_TYPELIB_PATH at the
directory holding Xmlb-2.0.typelib. The dev shell in flake.nix does this.
One trap worth knowing. The typelib must come from the same glib build as
the gobject-introspection gem. Mixing two registers GIO twice in one process
and fails with cannot register existing type 'GTlsCertificate'. Under nix,
take both from one nixpkgs — and note that glib's typelibs are in its out
output, not the default bin one.
The gem needs Xmlb-2.0.typelib and everything that typelib declares, resolved
transitively by the loader at require time. A missing one surfaces as
Typelib file for namespace 'X' not found, one at a time, so the whole chain
is listed here rather than discovered by repeated failure:
pkgs.libxmlb.lib— its typelib, which is whereXmlb-2.0.typeliblivespkgs.glib— GLib-2.0, GObject-2.0 and Gio-2.0, which nearly every GNOME typelib declares
Note the .out: a package's default output is often bin, which carries no
typelibs. makeSearchPath takes the first output, so it has to be asked for
out explicitly — this is the single most common way to get a search path that
looks right and finds nothing.
{
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
outputs = { nixpkgs, ... }:
let
system = "x86_64-linux";
pkgs = nixpkgs.legacyPackages.${system};
typelibPath = pkgs.lib.makeSearchPath "lib/girepository-1.0"
(map (drv: drv.out or drv) [ pkgs.libxmlb.lib pkgs.glib ]);
in
{
devShells.${system}.default = pkgs.mkShell {
packages = [ pkgs.ruby_3_4 pkgs.bundler ] ++ [ pkgs.libxmlb.lib pkgs.glib ];
shellHook = ''
export GI_TYPELIB_PATH="${typelibPath}''${GI_TYPELIB_PATH:+:$GI_TYPELIB_PATH}"
'';
};
};
}Everything must come from one nixpkgs. A typelib built against a different
glib than the gobject-introspection gem registers GIO twice in the process
and fails with cannot register existing type 'GTlsCertificate'.
If you are packaging an application rather than entering a shell, the same
typelibPath goes on the wrapper:
makeWrapper ${ruby}/bin/ruby $out/bin/my-app \
--set GI_TYPELIB_PATH "${typelibPath}"nix develop
bin/testgem kit releaseThat is the whole thing. It gates on the changelog having an entry for this version, on no deprecation deadline coming due, and on a clean working tree; then builds, pushes and tags.
There is nothing to wait for in CI. This gem is pure Ruby, so gem build
produces one libxmlb-X.Y.Z.gem that is the same artefact wherever it is built —
no extension, no per-platform gems, nothing for a workflow to hand back.
Apache-2.0. libxmlb.lib itself is LGPL-2.1-or-later; this gem links nothing and copies no libxmlb.lib code — it reads a description of it at runtime.