resources: compiler: Add dependency generator
authorChristian Persch <chpe@gnome.org>
Mon, 23 Jan 2012 19:42:20 +0000 (20:42 +0100)
committerChristian Persch <chpe@gnome.org>
Wed, 25 Jan 2012 13:47:37 +0000 (14:47 +0100)
Bug #668532.

docs/reference/gio/glib-compile-resources.xml
gio/glib-compile-resources.c
gio/tests/Makefile.am

index c3f6466..9c791f9 100644 (file)
@@ -75,6 +75,23 @@ Generate a header file for use with C code generated by <option>--generate-sourc
 </varlistentry>
 
 <varlistentry>
+<term><option>--generate-dependencies</option></term>
+<listitem><para>
+Prints the list of files that the resource bundle references to standard output.
+This can be used to track dependencies in the build system. For example, the following
+make rule would mark <replaceable>test.gresource</replaceable> as depending on all the
+files that <replaceable>test.gresource.xm</replaceable> includes, so that is is automatically
+rebuilt if any of them change:
+  <literal>
+    test.gresource: test.gresource.xml $(shell $(GLIB_COMPILE_RESOURCES) --generate-dependencies test.gresource.xml)
+  </literal>
+Note that this may or may not be portable to non-GNU <command>make</command>.
+</para>
+<para>For example i
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
 <term><option>--c-name</option></term>
 <listitem><para>
 Specify the prefix used for the C identifiers in the code generated by
index 4709bf5..cce80e8 100644 (file)
@@ -47,6 +47,7 @@
 
 typedef struct
 {
+  char *filename;
   char *content;
   gsize content_size;
   gsize size;
@@ -57,6 +58,8 @@ typedef struct
 {
   GHashTable *table; /* resource path -> FileData */
 
+  gboolean collect_data;
+
   /* per gresource */
   char *prefix;
 
@@ -74,6 +77,7 @@ static gchar *xmllint = NULL;
 static void
 file_data_free (FileData *data)
 {
+  g_free (data->filename);
   g_free (data->content);
   g_free (data);
 }
@@ -187,7 +191,7 @@ end_element (GMarkupParseContext  *context,
       gchar *file, *real_file;
       gchar *key;
       FileData *data;
-      char *tmp_file;
+      char *tmp_file = NULL;
 
       file = state->string->str;
       key = file;
@@ -214,7 +218,10 @@ end_element (GMarkupParseContext  *context,
       else
        real_file = g_strdup (file);
 
-      tmp_file = NULL;
+      data->filename = g_strdup (real_file);
+      if (!state->collect_data)
+        goto done;
+
       if (state->preproc_options)
         {
           gchar **options;
@@ -328,6 +335,8 @@ end_element (GMarkupParseContext  *context,
          data->flags |= G_RESOURCE_FLAGS_COMPRESSED;
        }
 
+    done:
+
       g_hash_table_insert (state->table, key, data);
 
     cleanup:
@@ -375,7 +384,8 @@ text (GMarkupParseContext  *context,
 }
 
 static GHashTable *
-parse_resource_file (const gchar *filename)
+parse_resource_file (const gchar *filename,
+                     gboolean collect_data)
 {
   GMarkupParser parser = { start_element, end_element, text };
   ParseState state = { 0, };
@@ -393,6 +403,7 @@ parse_resource_file (const gchar *filename)
     }
 
   state.table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)file_data_free);
+  state.collect_data = collect_data;
 
   context = g_markup_parse_context_new (&parser,
                                        G_MARKUP_TREAT_CDATA_AS_TEXT |
@@ -405,7 +416,7 @@ parse_resource_file (const gchar *filename)
       g_printerr ("%s: %s.\n", filename, error->message);
       g_clear_error (&error);
     }
-  else
+  else if (collect_data)
     {
       GHashTableIter iter;
       const char *key;
@@ -445,8 +456,12 @@ parse_resource_file (const gchar *filename)
                               g_variant_builder_end (&builder));
        }
     }
+  else
+    {
+      table = g_hash_table_ref (state.table);
+    }
 
-  g_hash_table_destroy (state.table);
+  g_hash_table_unref (state.table);
   g_markup_parse_context_free (context);
   g_free (contents);
 
@@ -474,10 +489,11 @@ main (int argc, char **argv)
   GHashTable *table;
   gchar *srcfile;
   gchar *target = NULL;
-  gchar *binary_target;
+  gchar *binary_target = NULL;
   gboolean generate_source = FALSE;
   gboolean generate_header = FALSE;
   gboolean manual_register = FALSE;
+  gboolean generate_dependencies = FALSE;
   char *c_name = NULL;
   char *c_name_no_underscores;
   GOptionContext *context;
@@ -486,6 +502,7 @@ main (int argc, char **argv)
     { "sourcedir", 0, 0, G_OPTION_ARG_FILENAME, &sourcedir, N_("The directory where files are to be read from (default to current directory)"), N_("DIRECTORY") },
     { "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 },
     { "manual-register", 0, 0, G_OPTION_ARG_NONE, &manual_register, N_("Don't automatically create and register resource"), NULL },
     { "c-name", 0, 0, G_OPTION_ARG_STRING, &c_name, N_("C identifier name used for the generated source code"), NULL },
     { NULL }
@@ -575,13 +592,26 @@ main (int argc, char **argv)
       g_free (base);
     }
 
-  if ((table = parse_resource_file (srcfile)) == NULL)
+  if ((table = parse_resource_file (srcfile, !generate_dependencies)) == NULL)
     {
       g_free (target);
       return 1;
     }
 
-  if (generate_source || generate_header)
+  if (generate_dependencies)
+    {
+      GHashTableIter iter;
+      gpointer key, data;
+      FileData *file_data;
+
+      g_hash_table_iter_init (&iter, table);
+      while (g_hash_table_iter_next (&iter, &key, &data))
+        {
+          file_data = data;
+          g_print ("%s\n",file_data->filename);
+        }
+    }
+  else if (generate_source || generate_header)
     {
       if (generate_source)
        {
@@ -593,8 +623,6 @@ main (int argc, char **argv)
            }
          close (fd);
        }
-      else
-       binary_target = NULL;
 
       if (c_name == NULL)
        {
index 1c65099..34adebe 100644 (file)
@@ -395,6 +395,7 @@ appinfo_SOURCES = appinfo.c
 appinfo_LDADD   = $(progs_ldadd)
 
 resources_SOURCES = resources.c test_resources.c test_resources2.c test_resources2.h
+resources_DEPENDENCIES = test.gresource
 resources_LDADD   = $(progs_ldadd)
 
 appinfo_test_SOURCES = appinfo-test.c
@@ -588,19 +589,19 @@ else
 endif
 
 BUILT_SOURCES += test_resources.c test_resources2.c test_resources2.h
-test_resources.c: test2.gresource.xml test1.txt
+test_resources.c: test2.gresource.xml Makefile $(shell $(glib_compile_resources) --generate-dependencies test2.gresource.xml)
        $(glib_compile_resources) --target=$@ --sourcedir=$(srcdir) --generate-source --c-name _g_test1 $(srcdir)/test2.gresource.xml
 
-test_resources2.c: test3.gresource.xml test1.txt
+test_resources2.c: test3.gresource.xml Makefile $(shell $(glib_compile_resources) --generate-dependencies test3.gresource.xml)
        $(glib_compile_resources) --target=$@ --sourcedir=$(srcdir) --generate-source --c-name _g_test2 --manual-register $(srcdir)/test3.gresource.xml
 
-test_resources2.h: test3.gresource.xml
+test_resources2.h: test3.gresource.xml Makefile $(shell $(glib_compile_resources) --generate-dependencies test3.gresource.xml)
        $(glib_compile_resources) --target=$@ --sourcedir=$(srcdir) --generate-header --c-name _g_test2 --manual-register $(srcdir)/test3.gresource.xml
 
-plugin_resources.c: test4.gresource.xml test1.txt
+plugin_resources.c: test4.gresource.xml Makefile $(shell $(glib_compile_resources) --generate-dependencies test4.gresource.xml)
        $(glib_compile_resources) --target=$@ --sourcedir=$(srcdir) --generate-source --c-name _g_plugin $(srcdir)/test4.gresource.xml
 
-test.gresource: test.gresource.xml test1.txt test2.txt test3.txt
+test.gresource: test.gresource.xml Makefile $(shell $(glib_compile_resources) --generate-dependencies test.gresource.xml)
        $(glib_compile_resources) --target=$@ --sourcedir=$(srcdir) $(srcdir)/test.gresource.xml
 
 noinst_LTLIBRARIES = libresourceplugin.la