F-i-f/meson-gse
Common code library for Gnome Shell Extensions (meson & related build scripts)
meson-gse
A Gnome Shell Extension library
Overview
meson-gse contains various files needed when using meson for building
Gnome Shell extensions.
This repository is supposed to be included in the meson-gse
top-level directory of your extension (with git-submodule).
Gnome Shell Extensions using meson-gse
Usage
Expected layout
meson-gse expects your project to have a certain layout:
-
po/- Internationalization files go here.
-
schemas/-
Any GSettings schema go here, they are expected to be of the form:
-
schemas/org.gnome.shell.extensions.your project
name.gschema.xml[auto-included]
-
-
src/-
JavaScript and CSS goes here
-
src/extension.jsThis file is mandatory for a Gnome-shell
extension. [auto-included] -
src/metadata.json.inMandatory template for the metadata file,
see below. [auto-included] -
src/stylesheet.cssOptional. [auto-included] -
src/pref.jsOptional. [auto-included]
-
Import meson-gse in your git tree
In your extension's top-level directory, run:
git submodule init
git submodule add https://github.com/F-i-f/meson-gseCreate required files
You need to create two files: meson-gse.build and
src/metadata.json.in
The meson-gse.build file
Syntax
# You can put a header here
# But no meson directives can be used
gse_project({extension name}, {extension uuid domain}, {extension version}, {gse assignments, meson code block})
# You can put other comments or meson directives after the gse_project statement-
extension name will be used as the project name in the
meson_project()definition and must conform to its requirements. -
extension uuid domain will be appended to extension name when
generating the extension's UUID. -
extension_version must be a single integer as it will be used in
the Gnome Shell extension'smetadata.jsonfile. -
gse_assignments, meson code block can be any meson code, but you're
expected to fill in some meson-gse variables as described below.
Available meson-gse variables
-
gse_sources
You can add any JavaScript files to this meson variable. Note that
thesrc/extension.jsandsrc/prefs.js(if it exists) files are
automatically included.Example:
gse_sources += files('src/other.js', 'src/foo.js')
The
gse_sourcesfiles are installed in the extension's root
directory by theinstallorextension.zipninjatargets. -
gse_libs
This meson variable is intended for external JavaScript libraries.
The difference betweengse_sourcesandgse_libsis that the
gse_sourcesJavaScript files will be checked for syntax when
runningninja checkwhile thegse_libsJavaScript files won't.A very basic logging
class
is also provided, and its path is available in thegse_lib_logger
meson variable.Example:
gse_libs += gse_lib_logger gse_libs += files('lib/other-library.js')
The
gse_libsfiles are installed in the extension's root directory
by theinstallorextension.zipninjatargets. -
gse_data
This meson variable can be used for other non-JavaScript data files.
Thesrc/stylesheet.cssfile is automatically included if it
exists.Example:
gse_data += files('icons/blah.png', 'src/datafile.xml')
The
gse_datafiles are installed in the extension's root directory
by theinstallorextension.zipninjatargets. -
gse_schemas
This meson variable can be used for GSettings schemas that need to
be included. If your extension's schema is stored in
schemas/org.gnome.shell.extensions.meson project
name.gschema.xml, it will be automatically included.Example:
gse_schemas += files('schemas/other-schema.xml')
The
gse_schemasfiles are installed in the extension'sschemas
directory by theinstallorextension.zipninjatargets. -
gse_dbus_interfaces
If your extension requires to be shipped with some missing or
private DBus interfaces, you can use this meson variable.Example:
gse_dbus_interfaces += files('dbus-interfaces/private.xml')
The
gse_dbus_interfacesfiles are installed in the extension's
dbus-interfacesdirectory by theinstallorextension.zip
ninjatargets.
The src/metadata.json.in file
This is a template for the extension's metadata.json file. Meson
will fill in some variables automatically. All variables expansions
are surrounded with @ signs, like in @variable@.
Available metadata.json.in expansions
-
@uuid@– fills in your extension's uuid. -
@gettext_domain@– will be replaced by your extension's gettext
domain. This is typically your meson project name / extension name. -
@version@– your extension's version as declared in the
gse_project()statement. -
@VCS_TAG@– will be the current git revision number.
Run the meson-gse/meson-gse tool, meson and ninja
meson-gse/meson-gse
meson setup build
ninja -C build test # Checks syntax of JavaScript files (runs eslint)
ninja -C build prettier # Maintenance only: run prettier on JavaScript files.
ninja -C build install # Install to $HOME/.local/share/gnome-shell/extensions
ninja -C build extension.zip # Builds the extension in build/extension.zip
ninja -C build clean # Default clean target, restart build from scratch
ninja -C build cleaner # Removes backup files, npm_modules. Does not imply 'clean'.Examples
Simple project
I'm working on project simple, version 1 and my extension's domain
is example.com. If your file layout is:
-
meson-gse.buildmeson_gse_project({simple}, {example.com}, {1}) -
src/extension.jsimport {Extension, gettext as _} from 'resource:///org/gnome/shell/extensions/extension.js'; export default class MyExtension extends Extension { enable() { log('Hello world enabled'); } disable() { log('Hello world disabled'); } };
-
src/metadata.json.in{ "description": "Says: hello, world.", "name": "Hello, world!", "shell-version": [ "45", "46" ], "gettext-domain": "@gettext_domain@", "settings-schema": "org.gnome.shell.extensions.hello-world", "url": "http://example.com/", "uuid": "@uuid@", "version": @version@, "vcs_revision": "@VCS_TAG@" }
Create the two above files in a git repository:
mkdir hello-world
cd hello-world
git init
echo "gse_project({simple}, {example.com}, {1})" > meson-gse.build
mkdir src
cat <<-'EOD' > src/extension.js
import {Extension, gettext as _} from 'resource:///org/gnome/shell/extensions/extension.js';
export default class MyExtension extends Extension {
enable() {
console.log('Hello world enabled');
}
disable() {
console.log('Hello world disabled');
}
};
EOD
cat <<-'EOD' > src/metadata.json.in
{
"description": "Says: hello, world.",
"name": "Hello, world!",
"shell-version": [
"45",
"46"
],
"gettext-domain": "@gettext_domain@",
"settings-schema": "org.gnome.shell.extensions.hello-world",
"url": "http://example.com/",
"uuid": "@uuid@",
"version": @version@,
"vcs_revision": "@VCS_TAG@"
}
EOD
git submodule init
git submodule add https://github.com/F-i-f/meson-gse
git add meson-gse.build src
git commit -m "Initial checkin."
meson-gse/meson-gse
meson setup build
ninja -C build test installAnd your extension is installed and ready to be enabled in Tweaks.
More complex examples
Refer to the projects using meson-gse.
Requirements
Recent changes
2026-02-19
- Update NPM modules.
- Update ESLint rules from latest Gnome Shell (50).
- Drop lib/convenience.js. It's been unnecessary since Gnome Shell 3.32.
- Fix ESLint errors in lib/logger.js.
2025-08-30
- Update NPM modules.
- Change prettier configuration from js to yaml.
2024-12-04
- Provide a "Get it on Gnome Extensions" icon/badge.
- Update NPM modules.
- Update ESLint configuration.
2024-06-05
- Replace Mozilla SpiderMonkey by
eslint for linting. - Add prettier.
- Add
cleanerninja target (removes*~backup and npm's
node_modules). - Bump Meson requirement to 1.4.0 for files'
full_path()method and
get rid of a meson warning.
2024-05-25
- Use
git submoduleinstead of subtree. - Updated documentation.
2024-01-10
- Gnome Shell 45 and later compatibility.
2022-12-22
- Support js102 for JavaScript validation.
2022-05-20
- Support js91 for JavaScript validation.
- Support Meson 0.61 and later.
- Fix issue in git-subtree-push.
2021-12-20
- Fix compatibility issue with meson 0.60.
- Require meson 0.50.0 or later for builds.
Credits
-
I've been inspired by the
gnome-shell-extensions
for writing the meson build files. Thanks to Florian
Müllner. -
meson-gse used to include the
convenience.jsfile from Giovanni
Campagna scampa.giovanni@gmail.com.