diff options
| author | Paul Smith <psmith@gnu.org> | 2009-06-06 23:16:46 +0000 | 
|---|---|---|
| committer | Paul Smith <psmith@gnu.org> | 2009-06-06 23:16:46 +0000 | 
| commit | b9f831b858761366e0db418e6f226a053ed550af (patch) | |
| tree | c1136963019da597c69848df352510c752a6d4ea | |
| parent | 71385e12250ea56ddb2186f22a3f741684562ac5 (diff) | |
| download | gunmake-b9f831b858761366e0db418e6f226a053ed550af.tar.gz | |
- Work around a bug in glibc glob(3), by avoiding GLOB_NOCHECK.
- Fix issue in very parallel builds found building glibc.
| -rw-r--r-- | ChangeLog | 10 | ||||
| -rw-r--r-- | read.c | 129 | ||||
| -rw-r--r-- | remake.c | 7 | ||||
| -rw-r--r-- | tests/scripts/variables/SHELL | 9 | 
4 files changed, 87 insertions, 68 deletions
| @@ -1,3 +1,13 @@ +2009-06-06  Paul Smith  <psmith@gnu.org> + +	* remake.c (check_dep): Only set the target's state to not-started +	if it's not already running.  Found this while testing -j10 builds +	of glibc: various targets were being rebuilt multiple times. + +	* read.c (multi_glob): Don't pass GLOB_NOCHECK to glob(3); instead +	handle the GLOB_NOMATCH error.  This is to work around Sourceware.org +	Bugzilla bug 10246. +  2009-06-04  Paul Smith  <psmith@gnu.org>  	* read.c (eval): Skip initial whitespace (ffeed, vtab, etc.) @@ -3083,6 +3083,9 @@ multi_glob (struct nameseq *chain, unsigned int size)    for (old = chain; old != 0; old = nexto)      { +      int r; +      const char **nlist = 0; +      int i = 0;        const char *gname;  #ifndef NO_ARCHIVES        char *arname = 0; @@ -3109,76 +3112,78 @@ multi_glob (struct nameseq *chain, unsigned int size)  	}  #endif /* !NO_ARCHIVES */ -      switch (glob (gname, GLOB_NOCHECK|GLOB_ALTDIRFUNC, NULL, &gl)) +      r = glob (gname, GLOB_NOSORT|GLOB_ALTDIRFUNC, NULL, &gl); +      switch (r)  	{ -	case 0:			/* Success.  */ -	  { -	    int i = gl.gl_pathc; -	    while (i-- > 0) -	      { -#ifndef NO_ARCHIVES -		if (memname != 0) -		  { -		    /* Try to glob on MEMNAME within the archive.  */ -		    struct nameseq *found -		      = ar_glob (gl.gl_pathv[i], memname, size); -		    if (! found) -		      { -			/* No matches.  Use MEMNAME as-is.  */ -			unsigned int alen = strlen (gl.gl_pathv[i]); -			unsigned int mlen = strlen (memname); -                        char *name; -			struct nameseq *elt = xmalloc (size); -                        memset (elt, '\0', size); - -                        name = alloca (alen + 1 + mlen + 2); -			memcpy (name, gl.gl_pathv[i], alen); -			name[alen] = '('; -			memcpy (name+alen+1, memname, mlen); -			name[alen + 1 + mlen] = ')'; -			name[alen + 1 + mlen + 1] = '\0'; -                        elt->name = strcache_add (name); -			elt->next = new; -			new = elt; -		      } -		    else -		      { -			/* Find the end of the FOUND chain.  */ -			struct nameseq *f = found; -			while (f->next != 0) -			  f = f->next; - -			/* Attach the chain being built to the end of the FOUND -			   chain, and make FOUND the new NEW chain.  */ -			f->next = new; -			new = found; -		      } -		  } -		else -#endif /* !NO_ARCHIVES */ -		  { -		    struct nameseq *elt = xmalloc (size); -                    memset (elt, '\0', size); -		    elt->name = strcache_add (gl.gl_pathv[i]); -		    elt->next = new; -		    new = elt; -		  } -	      } -	    globfree (&gl); -	    free (old); -	    break; -	  } -  	case GLOB_NOSPACE:  	  fatal (NILF, _("virtual memory exhausted")); -	  break; + +	case 0: +          /* Success.  */ +          i = gl.gl_pathc; +          nlist = (const char **)gl.gl_pathv; +          break;  	default: -	  old->next = new; -	  new = old; +          /* Not a match or another error; keep this name.  */ +          i = 1; +          nlist = &gname;  	  break;  	} +      /* For each matched element, add it to the list.  */ +      while (i-- > 0) +#ifndef NO_ARCHIVES +        if (memname != 0) +          { +            /* Try to glob on MEMNAME within the archive.  */ +            struct nameseq *found +              = ar_glob (nlist[i], memname, size); +            if (! found) +              { +                /* No matches.  Use MEMNAME as-is.  */ +                unsigned int alen = strlen (nlist[i]); +                unsigned int mlen = strlen (memname); +                char *name; +                struct nameseq *elt = xmalloc (size); +                memset (elt, '\0', size); + +                name = alloca (alen + 1 + mlen + 2); +                memcpy (name, nlist[i], alen); +                name[alen] = '('; +                memcpy (name+alen+1, memname, mlen); +                name[alen + 1 + mlen] = ')'; +                name[alen + 1 + mlen + 1] = '\0'; +                elt->name = strcache_add (name); +                elt->next = new; +                new = elt; +              } +            else +              { +                /* Find the end of the FOUND chain.  */ +                struct nameseq *f = found; +                while (f->next != 0) +                  f = f->next; + +                /* Attach the chain being built to the end of the FOUND +                   chain, and make FOUND the new NEW chain.  */ +                f->next = new; +                new = found; +              } +          } +        else +#endif /* !NO_ARCHIVES */ +          { +            struct nameseq *elt = xmalloc (size); +            memset (elt, '\0', size); +            elt->name = strcache_add (nlist[i]); +            elt->next = new; +            new = elt; +          } + +      if (r == 0) +        globfree (&gl); +      free (old);  #ifndef NO_ARCHIVES        if (arname)          free (arname); @@ -984,10 +984,11 @@ check_dep (struct file *file, unsigned int depth,  	  struct dep *lastd;            int deps_running = 0; -          /* Reset this target's state so that we check it fresh.  It could be -             that it's already been checked as part of an order-only +          /* If this target is not running, set it's state so that we check it +             fresh.  It could be it was checked as part of an order-only               prerequisite and so wasn't rebuilt then, but should be now.  */ -          set_command_state (file, cs_not_started); +          if (file->command_state != cs_running) +            set_command_state (file, cs_not_started);  	  lastd = 0;  	  d = file->deps; diff --git a/tests/scripts/variables/SHELL b/tests/scripts/variables/SHELL index acc5903..a303540 100644 --- a/tests/scripts/variables/SHELL +++ b/tests/scripts/variables/SHELL @@ -49,8 +49,11 @@ all:;@echo "$(SHELL) $$SHELL"  $extraENV{SHELL} = $mshell; -run_make_test("all: export SHELL := /./$mshell\n".' -all:;@echo "$(SHELL) $$SHELL" -', '', "/./$mshell /./$mshell"); +run_make_test(" +SHELL := /././$mshell +one: two +two: export SHELL := /./$mshell\n".' +one two:;@echo "$@: $(SHELL) $$SHELL" +', '', "two: /./$mshell /./$mshell\none: /././$mshell $mshell\n");  1; | 
