diff options
author | Jan Tojnar <jtojnar@gmail.com> | 2022-12-15 20:25:32 +0100 |
---|---|---|
committer | Jan Tojnar <jtojnar@gmail.com> | 2022-12-19 17:17:32 +0100 |
commit | 35d24b51f536cf3ead96b284e862ef8d9fe47edc (patch) | |
tree | 63f6dfcf86ba9ee843d3263302cfd99da779a87d /pkgs/build-support/make-hardcode-gsettings-patch | |
parent | 04f574a1c0fde90b51bf68198e2297ca4e7cccf4 (diff) |
makeHardcodeGsettingsPatch: Rename from glib.mkHardcodeGsettingsPatch
glib expression is messy enough as is. Also rename the `glib-schema-to-var` argument to `schemaIdToVariableMapping` to better match Nixpkgs coding style.
Diffstat (limited to 'pkgs/build-support/make-hardcode-gsettings-patch')
-rw-r--r-- | pkgs/build-support/make-hardcode-gsettings-patch/default.nix | 60 | ||||
-rw-r--r-- | pkgs/build-support/make-hardcode-gsettings-patch/hardcode-gsettings.cocci | 70 |
2 files changed, 130 insertions, 0 deletions
diff --git a/pkgs/build-support/make-hardcode-gsettings-patch/default.nix b/pkgs/build-support/make-hardcode-gsettings-patch/default.nix new file mode 100644 index 0000000000000..a1d2de21c4cb3 --- /dev/null +++ b/pkgs/build-support/make-hardcode-gsettings-patch/default.nix @@ -0,0 +1,60 @@ +{ + runCommand, + git, + coccinelle, + python3, +}: + +/* + Can be used as part of an update script to automatically create a patch + hardcoding the path of all GSettings schemas in C code. + For example: + passthru = { + hardcodeGsettingsPatch = makeHardcodeGsettingsPatch { + inherit src; + schemaIdToVariableMapping = { + ... + }; + }; + + updateScript = + let + updateSource = ...; + updatePatch = _experimental-update-script-combinators.copyAttrOutputToFile "evolution-ews.hardcodeGsettingsPatch" ./hardcode-gsettings.patch; + in + _experimental-update-script-combinators.sequence [ + updateSource + updatePatch + ]; + }; + } + takes as input a mapping from schema path to variable name. + For example `{ "org.gnome.evolution" = "EVOLUTION_SCHEMA_PATH"; }` + hardcodes looking for `org.gnome.evolution` into `@EVOLUTION_SCHEMA_PATH@`. + All schemas must be listed. +*/ +{ + src, + schemaIdToVariableMapping, +}: + +runCommand + "hardcode-gsettings.patch" + { + inherit src; + nativeBuildInputs = [ + git + coccinelle + python3 # For patch script + ]; + } + '' + unpackPhase + cd "''${sourceRoot:-.}" + set -x + cp ${builtins.toFile "glib-schema-to-var.json" (builtins.toJSON schemaIdToVariableMapping)} ./glib-schema-to-var.json + git init + git add -A + spatch --sp-file "${./hardcode-gsettings.cocci}" --dir . --in-place + git diff > "$out" + '' diff --git a/pkgs/build-support/make-hardcode-gsettings-patch/hardcode-gsettings.cocci b/pkgs/build-support/make-hardcode-gsettings-patch/hardcode-gsettings.cocci new file mode 100644 index 0000000000000..bedacf846bc49 --- /dev/null +++ b/pkgs/build-support/make-hardcode-gsettings-patch/hardcode-gsettings.cocci @@ -0,0 +1,70 @@ +/** + * 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. + * For executables, we handle this using wrappers but this is not an option for libraries like e-d-s. + * Instead, we hardcode the schema path when creating the settings. + * A schema path (ie org.gnome.evolution) can be replaced by @EVOLUTION_SCHEMA_PATH@ + * which is then replaced at build time by substituteAll. + * The mapping is provided in a json file ./glib-schema-to-var.json + */ + +@initialize:python@ +@@ +import json + +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) + +with open("./glib-schema-to-var.json") as mapping_file: + schema_to_var = json.load(mapping_file); + +def get_schema_directory(schema_path): + # Sometimes the schema id is referenced using C preprocessor #define constant in the same file + # let’s try to resolve it first. + schema_path = resolve_cpp_constant(schema_path.strip()).strip('"') + if schema_path in schema_to_var: + return f'"@{schema_to_var[schema_path]}@"' + raise Exception(f"Unknown schema path {schema_path!r}, please add it to ./glib-schema-to-var.json") + + +@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. +expression SCHEMA_PATH; +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"; +fresh identifier SCHEMA_DIRECTORY = script:python(SCHEMA_PATH) { get_schema_directory(SCHEMA_PATH) }; +@@ +-settings = g_settings_new(SCHEMA_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_PATH, FALSE); ++ settings = g_settings_new_full(schema, NULL, NULL); ++} |