2022-07-23 17:44:31 +02:00
|
|
|
|
/**
|
2023-11-13 02:13:02 +01:00
|
|
|
|
* Since Nix does not have a standard location like /usr/share where GSettings system
|
|
|
|
|
* could look for schemas, we need to point the software to a correct location somehow.
|
2022-07-23 17:44:31 +02:00
|
|
|
|
* For executables, we handle this using wrappers but this is not an option for libraries like e-d-s.
|
2023-11-13 02:13:02 +01:00
|
|
|
|
* Instead, we patch the source code to look for the schema in a schema source
|
|
|
|
|
* through a hardcoded path to the schema.
|
|
|
|
|
*
|
|
|
|
|
* For each schema id referenced in the source code (e.g. org.gnome.evolution),
|
|
|
|
|
* a variable name such as `EVOLUTION` must be provided in the ./glib-schema-to-var.json JSON file.
|
|
|
|
|
* It will end up in the resulting patch as `@EVOLUTION@` placeholder, which should be replaced at build time
|
|
|
|
|
* with a path to the directory containing a `gschemas.compiled` file that includes the schema.
|
2022-07-23 17:44:31 +02:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
@initialize:python@
|
|
|
|
|
@@
|
2022-10-13 14:00:00 +02:00
|
|
|
|
import json
|
2022-07-23 17:44:31 +02:00
|
|
|
|
|
|
|
|
|
cpp_constants = {}
|
|
|
|
|
|
|
|
|
|
def register_cpp_constant(const_name, val):
|
|
|
|
|
cpp_constants[const_name] = val.strip()
|
|
|
|
|
|
|
|
|
|
def resolve_cpp_constant(const_name):
|
|
|
|
|
return cpp_constants.get(const_name, const_name)
|
|
|
|
|
|
2022-10-13 14:00:00 +02:00
|
|
|
|
with open("./glib-schema-to-var.json") as mapping_file:
|
|
|
|
|
schema_to_var = json.load(mapping_file);
|
2022-07-23 17:44:31 +02:00
|
|
|
|
|
2022-12-15 21:20:40 +01:00
|
|
|
|
def get_schema_directory(schema_id):
|
2022-07-23 17:44:31 +02:00
|
|
|
|
# Sometimes the schema id is referenced using C preprocessor #define constant in the same file
|
|
|
|
|
# let’s try to resolve it first.
|
2022-12-15 21:20:40 +01:00
|
|
|
|
schema_id = resolve_cpp_constant(schema_id.strip()).strip('"')
|
|
|
|
|
if schema_id in schema_to_var:
|
|
|
|
|
return f'"@{schema_to_var[schema_id]}@"'
|
|
|
|
|
raise Exception(f"Unknown schema path {schema_id!r}, please add it to ./glib-schema-to-var.json")
|
2022-07-23 17:44:31 +02:00
|
|
|
|
|
|
|
|
|
@find_cpp_constants@
|
|
|
|
|
identifier const_name;
|
|
|
|
|
expression val;
|
|
|
|
|
@@
|
|
|
|
|
|
|
|
|
|
#define const_name val
|
|
|
|
|
|
|
|
|
|
@script:python record_cpp_constants depends on find_cpp_constants@
|
|
|
|
|
const_name << find_cpp_constants.const_name;
|
|
|
|
|
val << find_cpp_constants.val;
|
|
|
|
|
@@
|
|
|
|
|
|
|
|
|
|
register_cpp_constant(const_name, val)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@depends on ever record_cpp_constants || never record_cpp_constants@
|
|
|
|
|
// We want to run after #define constants have been collected but even if there are no #defines.
|
2022-12-15 21:20:40 +01:00
|
|
|
|
expression SCHEMA_ID;
|
2022-07-23 17:44:31 +02:00
|
|
|
|
expression settings;
|
|
|
|
|
// Coccinelle does not like autocleanup macros in + sections,
|
|
|
|
|
// let’s use fresh id with concatenation to produce the code as a string.
|
|
|
|
|
fresh identifier schema_source_decl = "g_autoptr(GSettingsSchemaSource) " ## "schema_source";
|
|
|
|
|
fresh identifier schema_decl = "g_autoptr(GSettingsSchema) " ## "schema";
|
2022-12-15 21:20:40 +01:00
|
|
|
|
fresh identifier SCHEMA_DIRECTORY = script:python(SCHEMA_ID) { get_schema_directory(SCHEMA_ID) };
|
2022-07-23 17:44:31 +02:00
|
|
|
|
@@
|
2022-12-15 21:20:40 +01:00
|
|
|
|
-settings = g_settings_new(SCHEMA_ID);
|
2022-07-23 17:44:31 +02:00
|
|
|
|
+{
|
|
|
|
|
+ schema_source_decl;
|
|
|
|
|
+ schema_decl;
|
|
|
|
|
+ schema_source = g_settings_schema_source_new_from_directory(SCHEMA_DIRECTORY,
|
|
|
|
|
+ g_settings_schema_source_get_default(),
|
|
|
|
|
+ TRUE,
|
|
|
|
|
+ NULL);
|
2022-12-15 21:20:40 +01:00
|
|
|
|
+ schema = g_settings_schema_source_lookup(schema_source, SCHEMA_ID, FALSE);
|
2022-07-23 17:44:31 +02:00
|
|
|
|
+ settings = g_settings_new_full(schema, NULL, NULL);
|
|
|
|
|
+}
|
2022-12-15 21:20:40 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@depends on ever record_cpp_constants || never record_cpp_constants@
|
|
|
|
|
// We want to run after #define constants have been collected but even if there are no #defines.
|
|
|
|
|
expression SCHEMA_ID;
|
|
|
|
|
expression settings;
|
|
|
|
|
expression BACKEND;
|
|
|
|
|
// Coccinelle does not like autocleanup macros in + sections,
|
|
|
|
|
// let’s use fresh id with concatenation to produce the code as a string.
|
|
|
|
|
fresh identifier schema_source_decl = "g_autoptr(GSettingsSchemaSource) " ## "schema_source";
|
|
|
|
|
fresh identifier schema_decl = "g_autoptr(GSettingsSchema) " ## "schema";
|
|
|
|
|
fresh identifier SCHEMA_DIRECTORY = script:python(SCHEMA_ID) { get_schema_directory(SCHEMA_ID) };
|
|
|
|
|
@@
|
|
|
|
|
-settings = g_settings_new_with_backend(SCHEMA_ID, BACKEND);
|
|
|
|
|
+{
|
|
|
|
|
+ schema_source_decl;
|
|
|
|
|
+ schema_decl;
|
|
|
|
|
+ schema_source = g_settings_schema_source_new_from_directory(SCHEMA_DIRECTORY,
|
|
|
|
|
+ g_settings_schema_source_get_default(),
|
|
|
|
|
+ TRUE,
|
|
|
|
|
+ NULL);
|
|
|
|
|
+ schema = g_settings_schema_source_lookup(schema_source, SCHEMA_ID, FALSE);
|
|
|
|
|
+ settings = g_settings_new_full(schema, BACKEND, NULL);
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@depends on ever record_cpp_constants || never record_cpp_constants@
|
|
|
|
|
// We want to run after #define constants have been collected but even if there are no #defines.
|
|
|
|
|
expression SCHEMA_ID;
|
|
|
|
|
expression settings;
|
|
|
|
|
expression BACKEND;
|
|
|
|
|
expression PATH;
|
|
|
|
|
// Coccinelle does not like autocleanup macros in + sections,
|
|
|
|
|
// let’s use fresh id with concatenation to produce the code as a string.
|
|
|
|
|
fresh identifier schema_source_decl = "g_autoptr(GSettingsSchemaSource) " ## "schema_source";
|
|
|
|
|
fresh identifier schema_decl = "g_autoptr(GSettingsSchema) " ## "schema";
|
|
|
|
|
fresh identifier SCHEMA_DIRECTORY = script:python(SCHEMA_ID) { get_schema_directory(SCHEMA_ID) };
|
|
|
|
|
@@
|
|
|
|
|
-settings = g_settings_new_with_backend_and_path(SCHEMA_ID, BACKEND, PATH);
|
|
|
|
|
+{
|
|
|
|
|
+ schema_source_decl;
|
|
|
|
|
+ schema_decl;
|
|
|
|
|
+ schema_source = g_settings_schema_source_new_from_directory(SCHEMA_DIRECTORY,
|
|
|
|
|
+ g_settings_schema_source_get_default(),
|
|
|
|
|
+ TRUE,
|
|
|
|
|
+ NULL);
|
|
|
|
|
+ schema = g_settings_schema_source_lookup(schema_source, SCHEMA_ID, FALSE);
|
|
|
|
|
+ settings = g_settings_new_full(schema, BACKEND, PATH);
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@depends on ever record_cpp_constants || never record_cpp_constants@
|
|
|
|
|
// We want to run after #define constants have been collected but even if there are no #defines.
|
|
|
|
|
expression SCHEMA_ID;
|
|
|
|
|
expression settings;
|
|
|
|
|
expression PATH;
|
|
|
|
|
// Coccinelle does not like autocleanup macros in + sections,
|
|
|
|
|
// let’s use fresh id with concatenation to produce the code as a string.
|
|
|
|
|
fresh identifier schema_source_decl = "g_autoptr(GSettingsSchemaSource) " ## "schema_source";
|
|
|
|
|
fresh identifier schema_decl = "g_autoptr(GSettingsSchema) " ## "schema";
|
|
|
|
|
fresh identifier SCHEMA_DIRECTORY = script:python(SCHEMA_ID) { get_schema_directory(SCHEMA_ID) };
|
|
|
|
|
@@
|
|
|
|
|
-settings = g_settings_new_with_path(SCHEMA_ID, PATH);
|
|
|
|
|
+{
|
|
|
|
|
+ schema_source_decl;
|
|
|
|
|
+ schema_decl;
|
|
|
|
|
+ schema_source = g_settings_schema_source_new_from_directory(SCHEMA_DIRECTORY,
|
|
|
|
|
+ g_settings_schema_source_get_default(),
|
|
|
|
|
+ TRUE,
|
|
|
|
|
+ NULL);
|
|
|
|
|
+ schema = g_settings_schema_source_lookup(schema_source, SCHEMA_ID, FALSE);
|
|
|
|
|
+ settings = g_settings_new_full(schema, NULL, PATH);
|
|
|
|
|
+}
|