|
View:
New views
1 Messages
—
Rating Filter:
Alert me
|
|
|
Avoiding unnecessary rebuilds with AutomakeThe attached patch:
- adds a --no-touch option, which prevents all files (not just the public header) from being touched unless they have changed - while here, checks if a file has changed without cmp(1) - removes the timestamp from .c comment headers It helps avoiding unnecessary rebuilds when GOB is used from Automake, thanks to the following trick (the manual page should be updated): foo_SOURCES = foo.gob foo.gob.stamp foo.c foo.h foo-private.h BUILT_SOURCES = foo.gob.stamp MAINTAINERCLEANFILES = foo.gob.stamp %.gob.stamp: %.gob @GOB2@ --no-touch $< @touch $@ -- Jean-Yves Lefort jylefort@... http://lefort.be.eu.org/ --- src/main.c.orig Tue Dec 6 11:08:37 2005 +++ src/main.c Tue Dec 6 12:30:23 2005 @@ -25,6 +25,7 @@ #include <glib.h> #include <time.h> #include <stdio.h> +#include <errno.h> #include <string.h> #include <unistd.h> #include <stdlib.h> @@ -54,6 +55,9 @@ char *filebase; char *fullfilebase; +static char *outfilebase; +static char *outfilehbase; +static char *outfilephbase; static char *funcbase; static char *pfuncbase; static char *macrobase; @@ -99,6 +103,7 @@ FILE *outph = NULL; FILE *devnull = NULL; +gboolean no_touch = FALSE; gboolean no_touch_headers = FALSE; gboolean for_cpp = FALSE; gboolean no_gnu = FALSE; @@ -3045,14 +3050,11 @@ { char *outfile, *outfileh, *outfileph; - if ( ! for_cpp) - outfile = g_strconcat (fullfilebase, ".c", NULL); - else - outfile = g_strconcat (fullfilebase, ".cc", NULL); - if (no_touch_headers) - outfileh = g_strconcat (fullfilebase, ".h#gob#", NULL); - else - outfileh = g_strconcat (fullfilebase, ".h", NULL); + outfilebase = g_strconcat (fullfilebase, for_cpp ? ".cc" : ".c", NULL); + outfile = g_strconcat(outfilebase, no_touch ? "#gob#" : "", NULL); + + outfilehbase = g_strconcat (fullfilebase, ".h"); + outfileh = g_strconcat(outfilehbase, no_touch_headers ? "#gob#" : "", NULL); if ((privates > 0 || protecteds > 0 || private_header == PRIVATE_HEADER_ALWAYS) && @@ -3060,8 +3062,10 @@ char sep[2] = {0,0}; if (file_sep != 0) sep[0] = file_sep; - outfileph = g_strconcat (fullfilebase, sep, "private.h", NULL); + outfilephbase = g_strconcat (fullfilebase, sep, "private.h", NULL); + outfileph = g_strconcat (outfilephbase, no_touch ? "#gob#" : "", NULL); } else { + outfilephbase = NULL; outfileph = NULL; } @@ -3675,16 +3679,13 @@ static void print_file_comments(void) { - time_t curtime; - time(&curtime); out_printf(outh, "/* Generated by GOB (v%s)" " (do not edit directly) */\n\n", VERSION); if(outph) out_printf(outph, "/* Generated by GOB (v%s)" " (do not edit directly) */\n\n", VERSION); - out_printf(out, "/* Generated by GOB (v%s) on %s" - " (do not edit directly) */\n\n", - VERSION, ctime(&curtime)); + out_printf(out, "/* Generated by GOB (v%s)" + " (do not edit directly) */\n\n", VERSION); out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n"); } @@ -4075,6 +4076,9 @@ "\t--no-extern-c Never print extern \"C\" into the " "header\n" "\t--no-gnu Never use GNU extentions\n" + "\t--no-touch Don't touch output files unless they " + "really\n" + "\t changed (implies --no-touch-headers)\n" "\t--no-touch-headers Don't touch headers unless they " "really changed\n" "\t--always-private-header Always create a private header " @@ -4172,6 +4176,9 @@ exit_on_warn = FALSE; } else if(strcmp(argv[i], "--for-cpp")==0) { for_cpp = TRUE; + } else if(strcmp(argv[i], "--no-touch")==0) { + no_touch = TRUE; + no_touch_headers = TRUE; } else if(strcmp(argv[i], "--no-touch-headers")==0) { no_touch_headers = TRUE; } else if(strcmp(argv[i], "--ondemand-private-header")==0) { @@ -4283,35 +4290,79 @@ #endif } -/* this is a somewhat ugly hack, but it appears to work */ static void -compare_and_move_header(void) +compare_and_move (const char *old_filename) { - char *hfnew = g_strconcat(fullfilebase, ".h#gob#", NULL); - char *hf = g_strconcat(fullfilebase, ".h", NULL); - struct stat s; - if(stat(hf, &s) == 0) { - char *s; - s = g_strdup_printf("cmp '%s' '%s' > /dev/null", hf, hfnew); - if(system(s) == 0) { - if(unlink(hfnew) != 0) - error_printf(GOB_ERROR, 0, - "Can't remove new header file"); - g_free(hfnew); - g_free(hf); - g_free(s); - return; + char *new_filename = g_strconcat (old_filename, "#gob#", NULL); + FILE *old_f; + gboolean equal = FALSE; + + old_f = fopen (old_filename, "r"); + if (old_f) { + FILE *new_f; + gboolean error = FALSE; + + new_f = fopen (new_filename, "r"); + if (new_f) { + char new_buf[1024]; + char old_buf[1024]; + + while (TRUE) { + size_t new_n; + size_t old_n; + + new_n = fread (new_buf, 1, sizeof (new_buf), new_f); + if (ferror (new_f)) { + error = TRUE; + error_printf (GOB_ERROR, 0, + "Can't read %s: %s", + new_filename, + g_strerror (errno)); + break; + } + + old_n = fread (old_buf, 1, sizeof (old_buf), old_f); + if (ferror (old_f) + || feof (new_f) != feof (old_f) + || new_n != old_n + || memcmp (new_buf, old_buf, new_n) != 0) + break; + + if (feof (new_f)) { + equal = TRUE; + break; + } + } + } else + error_printf (GOB_ERROR, 0, "Can't open %s: %s", + new_filename, g_strerror (errno)); + + fclose (old_f); + fclose (new_f); + + if (error) + goto end; + + if (! equal && unlink (old_filename) != 0) { + error_printf (GOB_ERROR, 0, "Can't remove %s: %s", + old_filename, g_strerror (errno)); + goto end; } - g_free(s); - if(unlink(hf) != 0) - error_printf(GOB_ERROR, 0, - "Can't remove old header file"); - } - if(rename(hfnew, hf) != 0) - error_printf(GOB_ERROR, 0, - "Can't rename new header file"); - g_free(hfnew); - g_free(hf); + } + + if (equal) { + if (unlink (new_filename) != 0) + error_printf (GOB_ERROR, 0, "Can't remove %s: %s", + new_filename, g_strerror (errno)); + } else { + if (rename (new_filename, old_filename) != 0) + error_printf (GOB_ERROR, 0, "Can't rename %s to %s: %s", + new_filename, old_filename, + g_strerror (errno)); + } + + end: + g_free (new_filename); } int @@ -4413,9 +4464,15 @@ fclose (outph); } - if (no_touch_headers && - ! no_write) - compare_and_move_header (); + if (! no_write) { + if (no_touch) { + compare_and_move (outfilebase); + if (outfilephbase) + compare_and_move (outfilephbase); + } + if (no_touch_headers) + compare_and_move (outfilehbase); + } return 0; } -- to unsubscribe: send mail to minimalist@... with "unsubscribe gob-list" in the subject |
| Free embeddable forum powered by Nabble | Forum Help |