From e8c8395f0e72f59e37189e94b08052bebb51ac77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 26 Jan 2016 19:21:57 +0000 Subject: [PATCH] glib-compile-resources: generate .d-file style dependency output for build tools MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add --dependency-file=foo.d option to generate a gcc -M -MF style dependency file for other build tools. The current output of --generate-dependencies is only useful for use directly in Makefile rules, but can't be used in other build systems like that. The generated dependency file looks like this: $ glib-compile-resources --sourcedir= test.gresource.xml --dependency-file=- test.gresource.xml: test1.txt test2.txt test2.txt test1.txt: test2.txt: test2.txt: Unlike --generate-dependencies, the --dependency-file option can be used together with other --generate options to create dependencies as side-effect of generating sources. Based on a patch by Tim-Philipp Müller. https://bugzilla.gnome.org/show_bug.cgi?id=745754 --- docs/reference/gio/glib-compile-resources.xml | 14 +++ gio/glib-compile-resources.c | 89 ++++++++++++++----- 2 files changed, 81 insertions(+), 22 deletions(-) diff --git a/docs/reference/gio/glib-compile-resources.xml b/docs/reference/gio/glib-compile-resources.xml index fcce89a1a..c2c1989c3 100644 --- a/docs/reference/gio/glib-compile-resources.xml +++ b/docs/reference/gio/glib-compile-resources.xml @@ -124,6 +124,9 @@ test.gresource: test.gresource.xml $(shell $(GLIB_COMPILE_RESOURCES) --generate- Note that this may or may not be portable to non-GNU make. + +Also see . + @@ -160,6 +163,17 @@ which is what does. + + + +Write dependencies in the same style as gcc -M -MF to the given file. +If is -, the dependencies are written to the standard +output. Unlike , this option can be +combined with other options to generate dependencies +as a side-effect of generating sources. + + + diff --git a/gio/glib-compile-resources.c b/gio/glib-compile-resources.c index 71a0f48a8..7c35bf36f 100644 --- a/gio/glib-compile-resources.c +++ b/gio/glib-compile-resources.c @@ -61,8 +61,6 @@ typedef struct { GHashTable *table; /* resource path -> FileData */ - gboolean collect_data; - /* per gresource */ char *prefix; @@ -242,7 +240,7 @@ end_element (GMarkupParseContext *context, if (sourcedirs != NULL) { real_file = find_file (file); - if (real_file == NULL && state->collect_data) + if (real_file == NULL) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Failed to locate '%s' in any source directory"), file); @@ -253,7 +251,7 @@ end_element (GMarkupParseContext *context, { gboolean exists; exists = g_file_test (file, G_FILE_TEST_EXISTS); - if (!exists && state->collect_data) + if (!exists) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Failed to locate '%s' in current directory"), file); @@ -266,8 +264,6 @@ end_element (GMarkupParseContext *context, data = g_new0 (FileData, 1); data->filename = g_strdup (real_file); - if (!state->collect_data) - goto done; if (state->preproc_options) { @@ -415,8 +411,6 @@ end_element (GMarkupParseContext *context, data->flags |= G_RESOURCE_FLAGS_COMPRESSED; } - done: - g_hash_table_insert (state->table, key, data); data = NULL; @@ -476,7 +470,7 @@ text (GMarkupParseContext *context, static GHashTable * parse_resource_file (const gchar *filename, - gboolean collect_data) + GHashTable *files) { GMarkupParser parser = { start_element, end_element, text }; ParseState state = { 0, }; @@ -493,8 +487,7 @@ parse_resource_file (const gchar *filename, return NULL; } - state.table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)file_data_free); - state.collect_data = collect_data; + state.table = g_hash_table_ref (files); context = g_markup_parse_context_new (&parser, G_MARKUP_TREAT_CDATA_AS_TEXT | @@ -507,7 +500,7 @@ parse_resource_file (const gchar *filename, g_printerr ("%s: %s.\n", filename, error->message); g_clear_error (&error); } - else if (collect_data) + else { GHashTableIter iter; const char *key; @@ -547,10 +540,6 @@ parse_resource_file (const gchar *filename, g_variant_builder_end (&builder)); } } - else - { - table = g_hash_table_ref (state.table); - } g_hash_table_unref (state.table); g_markup_parse_context_free (context); @@ -605,6 +594,7 @@ main (int argc, char **argv) { GError *error; GHashTable *table; + GHashTable *files; gchar *srcfile; gchar *target = NULL; gchar *binary_target = NULL; @@ -614,6 +604,7 @@ main (int argc, char **argv) gboolean manual_register = FALSE; gboolean internal = FALSE; gboolean generate_dependencies = FALSE; + char *dependency_file = NULL; char *c_name = NULL; char *c_name_no_underscores; const char *linkage = "extern"; @@ -625,6 +616,7 @@ main (int argc, char **argv) { "generate-header", 0, 0, G_OPTION_ARG_NONE, &generate_header, N_("Generate source header"), NULL }, { "generate-source", 0, 0, G_OPTION_ARG_NONE, &generate_source, N_("Generate sourcecode used to link in the resource file into your code"), NULL }, { "generate-dependencies", 0, 0, G_OPTION_ARG_NONE, &generate_dependencies, N_("Generate dependency list"), NULL }, + { "dependency-file", 0, 0, G_OPTION_ARG_FILENAME, &dependency_file, N_("name of the dependency file to generate"), N_("FILE") }, { "manual-register", 0, 0, G_OPTION_ARG_NONE, &manual_register, N_("Don't automatically create and register resource"), NULL }, { "internal", 0, 0, G_OPTION_ARG_NONE, &internal, N_("Don't export functions; declare them G_GNUC_INTERNAL"), NULL }, { "c-name", 0, 0, G_OPTION_ARG_STRING, &c_name, N_("C identifier name used for the generated source code"), NULL }, @@ -732,24 +724,77 @@ main (int argc, char **argv) ; } - if ((table = parse_resource_file (srcfile, !generate_dependencies)) == NULL) + files = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)file_data_free); + + if ((table = parse_resource_file (srcfile, files)) == NULL) { g_free (target); g_free (c_name); return 1; } - if (generate_dependencies) + if (generate_dependencies || dependency_file != NULL) { GHashTableIter iter; gpointer key, data; FileData *file_data; - g_hash_table_iter_init (&iter, table); - while (g_hash_table_iter_next (&iter, &key, &data)) + g_hash_table_iter_init (&iter, files); + if (dependency_file == NULL) { - file_data = data; - g_print ("%s\n",file_data->filename); + /* Generate list of files for direct use as dependencies in a Makefile */ + while (g_hash_table_iter_next (&iter, &key, &data)) + { + file_data = data; + g_print ("%s\n", file_data->filename); + } + } + else + { + /* Generate a .d file that describes the dependencies for + * build tools, gcc -M -MF style */ + GString *dep_string; + + dep_string = g_string_new (NULL); + g_string_printf (dep_string, "%s:", srcfile); + + /* First rule: foo.xml: resource1 resource2.. */ + while (g_hash_table_iter_next (&iter, &key, &data)) + { + file_data = data; + if (!g_str_equal (file_data->filename, srcfile)) + g_string_append_printf (dep_string, " %s", file_data->filename); + } + + g_string_append (dep_string, "\n\n"); + + /* One rule for every resource: resourceN: */ + g_hash_table_iter_init (&iter, files); + while (g_hash_table_iter_next (&iter, &key, &data)) + { + file_data = data; + if (!g_str_equal (file_data->filename, srcfile)) + g_string_append_printf (dep_string, "%s:\n\n", file_data->filename); + } + + if (g_str_equal (dependency_file, "-")) + { + g_print ("%s\n", dep_string->str); + } + else + { + if (!g_file_set_contents (dependency_file, dep_string->str, dep_string->len, &error)) + { + g_printerr ("Error writing dependency file: %s\n", error->message); + g_string_free (dep_string, TRUE); + g_free (dependency_file); + g_error_free (error); + return 1; + } + } + + g_string_free (dep_string, TRUE); + g_free (dependency_file); } } else if (generate_source || generate_header)