Skip to content

Implement glib_build_tools::compile_schemas #1721

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

shahradelahi
Copy link

@shahradelahi shahradelahi commented May 19, 2025

This PR adds a build‑time utility, compile_schemas, to the glib_build_tools crate.

It generates the gschemas.compiled file by copying all .gschema.xml files from the specified directories into the glib-2.0/schemas cache directory and then running glib-compile-schemas --strict to compile them.

@sdroege
Copy link
Member

sdroege commented May 20, 2025

Please squash the commits and provide a meaningful commit message (and PR description) for what this is actually doing.

Comment on lines 81 to 93
let prefix = if cfg!(windows) {
PathBuf::from("C:/ProgramData")
} else {
glib::user_data_dir()
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This hardcoding the prefix to use is meh. Either the prefix will have to be passed as a param or this function won't land as is.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You’re right; the prefix can also be /usr/share/.

@shahradelahi shahradelahi force-pushed the glib-compile-schemas branch 3 times, most recently from c2386b2 to d7acbd3 Compare May 20, 2025 14:56
Comment on lines 72 to 78
/// glib_build_tools::compile_schemas(
/// &["schemas"],
/// None
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please document the default target_dir.

Some(base) => PathBuf::from(base),
None => {
let prefix = if cfg!(windows) {
PathBuf::from("C:/ProgramData")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why a hardcoded path on windows?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looked everywhere, but I couldn’t find any information on where the target directory is on Windows. The paths are based on the gtk-rs.org documentation.

https://gtk-rs.org/gtk4-rs/stable/latest/book/settings.html
https://man.archlinux.org/man/core/glib2/glib-compile-schemas.1.en

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should also be g_get_user_data_dir() on Windows too or not?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also there's the extra complication that on Windows IIRC these things are relative to the executable (or library?) path. This needs some further investigation in any case.

@shahradelahi shahradelahi force-pushed the glib-compile-schemas branch from d7acbd3 to 525f2c2 Compare May 22, 2025 12:39
…gs schemas

It generates the `gschemas.compiled` file by copying all `.gschema.xml` files from the specified directories into the `glib-2.0/schemas` cache directory and then running `glib-compile-schemas --strict` to compile them.
@shahradelahi shahradelahi force-pushed the glib-compile-schemas branch from 525f2c2 to 2f29eac Compare May 22, 2025 12:40
@shahradelahi
Copy link
Author

@sdroege a review please

};

// Ensure target_dir exists
std::fs::create_dir_all(&target_dir).expect("Failed to create target directory");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Installing things as part of build.rs is an anti-pattern and unexpected. You should not place (or modify) anything outside of OUT_DIR, see https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts

Comment on lines +79 to +82
println!(
"cargo:rustc-env=GSETTINGS_SCHEMA_DIR={}",
target_dir.to_str().unwrap()
);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://docs.gtk.org/gio/overview.html#running-gio-applications

GSETTINGS_SCHEMA_DIR. This variable can be set to the names of directories to consider when looking for compiled schemas for GSettings, in addition to the glib-2.0/schemas subdirectories of the XDG system data directories. To specify multiple directories, use G_SEARCHPATH_SEPARATOR_S as a separator.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But this is passing the environment variable to rustc, it doesn't make your application run with it

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can run the application this way, but of course, the compiled schema binary must be installed in the glib-2.0/schemas directory within one of the directories listed in XDG_DATA_DIRS.

I'm trying to implement a similar approach to compile_resources. After reading through the GLib source code, I couldn't find anything—unless I'm missing something.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this makes sense really. The correct way for all this is to install the schemas in the right location and the environment variable is meant for uninstalled usage or special setups.

cargo has no mechanism for installing anything but an executable, so the usual solution for this is to put another, proper build system around cargo. E.g. having a Makefile (which hopefully does things correctly enough), or using meson or cmake.

I don't think what you're trying to achieve here (installing schemas) is possible with cargo in its current form but would need more features in cargo first.

@shahradelahi shahradelahi requested a review from sdroege May 23, 2025 12:12

// Ensure target_dir exists
std::fs::create_dir_all(&target_dir).expect("Failed to create target directory");

println!(
"cargo:rustc-env=GSETTINGS_SCHEMA_DIR={}",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How would this be used?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants