Patch: .NOTINTERMEDIATE flag

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Patch: .NOTINTERMEDIATE flag

Paul Draper-2
Let me know if there is preferred route for this patch; Savannah restricts
patch submissions to project members.

Problem: Intermediate targets can have surprising and undesirable behavior.
A search for "make deleting files" yield many results. They are also
challenging to implement well. For example, they can have vastly inferior
performance ( https://savannah.gnu.org/bugs/?51454 ).

Needing a target to be intermediate is more unusal than needing a target to
not be intermediate. Thus many places on the web recommend no-prereqs
.SECONDARY as a blanket fix. But it was two downsides

(1) It makes everything not deleted, with no possibility for exception.
(2) It makes the target secondary and intermediate which is not quite the
same as a regular target (e.g. bug 51454).

There is currently no possible way for an unmentioned target to not be
intermediate.

Solution: I propose the no-prereqs .NOTINTERMEDIATE flag. If present, it
will not automatically make targets intermediate. .SECONDARY or
.INTERMEDIATE can still seletively make targets intermediate.

I think this is a very safe and desirable behavior for many makefiles.

diff --git a/doc/make.texi b/doc/make.texi
index 8810f2b..8f8442c 100644
--- a/doc/make.texi
+++ b/doc/make.texi
@@ -2857,6 +2857,18 @@ The targets which @code{.INTERMEDIATE} depends on
are treated as
 intermediate files.  @xref{Chained Rules, ,Chains of Implicit Rules}.
 @code{.INTERMEDIATE} with no prerequisites has no effect.

+@findex .NOTINTERMEDIATE
+@item .NOTINTERMEDIATE
+@cindex automatic intermediate targets
+
+If @code{.NOTINTERMEDIATE} is mentioned as a target anywhere in the
+makefile, then @code{make} will not automatically treat unmentioned
+files as intermediate files.
+@xref{Chained Rules, ,Chains of Implicit Rules}.
+
+@code{.INTERMEDIATE}
+and @code{.SECONDARY} can still mark files as intermediate.
+
 @findex .SECONDARY
 @item .SECONDARY
 @cindex secondary targets
diff --git a/file.c b/file.c
index fe58eba..b90b103 100644
--- a/file.c
+++ b/file.c
@@ -62,6 +62,9 @@ static struct hash_table files;
 /* Whether or not .SECONDARY with no prerequisites was given.  */
 static int all_secondary = 0;

+/** Whether or not implicit chains are automatically marked as
intermediate. */
+static int auto_intermediate = 1;
+
 /* Access the hash table of all file records.
    lookup_file  given a name, return the struct file * for that name,
                 or nil if there is none.
@@ -706,6 +709,9 @@ snap_deps (void)

   /* Now manage all the special targets.  */

+  for (f = lookup_file (".NOTINTERMEDIATE"); f != 0; f = f->prev)
+    auto_intermediate = 1;
+
   for (f = lookup_file (".PRECIOUS"); f != 0; f = f->prev)
     for (d = f->deps; d != 0; d = d->next)
       for (f2 = d->file; f2 != 0; f2 = f2->prev)
diff --git a/filedef.h b/filedef.h
index 7de6ac0..f849340 100644
--- a/filedef.h
+++ b/filedef.h
@@ -105,6 +105,7 @@ struct file

 extern struct file *default_file;

+extern int auto_intermediate;

 struct file *lookup_file (const char *name);
 struct file *enter_file (const char *name);
diff --git a/implicit.c b/implicit.c
index e5046a4..01c6eb1 100644
--- a/implicit.c
+++ b/implicit.c
@@ -878,7 +878,9 @@ pattern_search (struct file *file, int archive,
           f->pat_searched = imf->pat_searched;
           f->also_make = imf->also_make;
           f->is_target = 1;
-          f->intermediate = 1;
+          if (!auto_intermediate)
+            f->intermediate = 1;
+
           f->tried_implicit = 1;

           imf = lookup_file (pat->pattern);
_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Patch: .NOTINTERMEDIATE flag

Paul Draper-2
Er, that should be

diff --git a/doc/make.texi b/doc/make.texi
index 8810f2b..09da034 100644
--- a/doc/make.texi
+++ b/doc/make.texi
@@ -2857,6 +2857,18 @@ The targets which @code{.INTERMEDIATE} depends on
are treated as
 intermediate files.  @xref{Chained Rules, ,Chains of Implicit Rules}.
 @code{.INTERMEDIATE} with no prerequisites has no effect.

+@findex .NOTINTERMEDIATE
+@item .NOTINTERMEDIATE
+@cindex automatic intermediate targets
+
+If @code{.NOTINTERMEDIATE} is mentioned as a target anywhere in the
+makefile, then @code{make} will not automatically treat unmentioned
+files as intermediate files.
+@xref{Chained Rules, ,Chains of Implicit Rules}.
+
+@code{.INTERMEDIATE}
+and @code{.SECONDARY} can still mark files as intermediate.
+
 @findex .SECONDARY
 @item .SECONDARY
 @cindex secondary targets
diff --git a/file.c b/file.c
index fe58eba..a5e73e5 100644
--- a/file.c
+++ b/file.c
@@ -62,6 +62,9 @@ static struct hash_table files;
 /* Whether or not .SECONDARY with no prerequisites was given.  */
 static int all_secondary = 0;

+/** Whether or not implicit chains are automatically marked as
intermediate. */
+int auto_intermediate;
+
 /* Access the hash table of all file records.
    lookup_file  given a name, return the struct file * for that name,
                 or nil if there is none.
@@ -706,6 +709,10 @@ snap_deps (void)

   /* Now manage all the special targets.  */

+  auto_intermediate = 1;
+  for (f = lookup_file (".NOTINTERMEDIATE"); f != 0; f = f->prev)
+    auto_intermediate = 0;
+
   for (f = lookup_file (".PRECIOUS"); f != 0; f = f->prev)
     for (d = f->deps; d != 0; d = d->next)
       for (f2 = d->file; f2 != 0; f2 = f2->prev)
diff --git a/filedef.h b/filedef.h
index 7de6ac0..f849340 100644
--- a/filedef.h
+++ b/filedef.h
@@ -105,6 +105,7 @@ struct file

 extern struct file *default_file;

+extern int auto_intermediate;

 struct file *lookup_file (const char *name);
 struct file *enter_file (const char *name);
diff --git a/implicit.c b/implicit.c
index e5046a4..0cbf715 100644
--- a/implicit.c
+++ b/implicit.c
@@ -878,7 +878,8 @@ pattern_search (struct file *file, int archive,
           f->pat_searched = imf->pat_searched;
           f->also_make = imf->also_make;
           f->is_target = 1;
-          f->intermediate = 1;
+          if (auto_intermediate)
+            f->intermediate = 1;
           f->tried_implicit = 1;

           imf = lookup_file (pat->pattern);


On Wed, Jul 12, 2017 at 10:41 PM, Paul Draper <[hidden email]> wrote:

> Let me know if there is preferred route for this patch; Savannah restricts
> patch submissions to project members.
>
> Problem: Intermediate targets can have surprising and undesirable
> behavior. A search for "make deleting files" yield many results. They are
> also challenging to implement well. For example, they can have vastly
> inferior performance ( https://savannah.gnu.org/bugs/?51454 ).
>
> Needing a target to be intermediate is more unusal than needing a target
> to not be intermediate. Thus many places on the web recommend no-prereqs
> .SECONDARY as a blanket fix. But it was two downsides
>
> (1) It makes everything not deleted, with no possibility for exception.
> (2) It makes the target secondary and intermediate which is not quite the
> same as a regular target (e.g. bug 51454).
>
> There is currently no possible way for an unmentioned target to not be
> intermediate.
>
> Solution: I propose the no-prereqs .NOTINTERMEDIATE flag. If present, it
> will not automatically make targets intermediate. .SECONDARY or
> .INTERMEDIATE can still seletively make targets intermediate.
>
> I think this is a very safe and desirable behavior for many makefiles.
>
> diff --git a/doc/make.texi b/doc/make.texi
> index 8810f2b..8f8442c 100644
> --- a/doc/make.texi
> +++ b/doc/make.texi
> @@ -2857,6 +2857,18 @@ The targets which @code{.INTERMEDIATE} depends on
> are treated as
>  intermediate files.  @xref{Chained Rules, ,Chains of Implicit Rules}.
>  @code{.INTERMEDIATE} with no prerequisites has no effect.
>
> +@findex .NOTINTERMEDIATE
> +@item .NOTINTERMEDIATE
> +@cindex automatic intermediate targets
> +
> +If @code{.NOTINTERMEDIATE} is mentioned as a target anywhere in the
> +makefile, then @code{make} will not automatically treat unmentioned
> +files as intermediate files.
> +@xref{Chained Rules, ,Chains of Implicit Rules}.
> +
> +@code{.INTERMEDIATE}
> +and @code{.SECONDARY} can still mark files as intermediate.
> +
>  @findex .SECONDARY
>  @item .SECONDARY
>  @cindex secondary targets
> diff --git a/file.c b/file.c
> index fe58eba..b90b103 100644
> --- a/file.c
> +++ b/file.c
> @@ -62,6 +62,9 @@ static struct hash_table files;
>  /* Whether or not .SECONDARY with no prerequisites was given.  */
>  static int all_secondary = 0;
>
> +/** Whether or not implicit chains are automatically marked as
> intermediate. */
> +static int auto_intermediate = 1;
> +
>  /* Access the hash table of all file records.
>     lookup_file  given a name, return the struct file * for that name,
>                  or nil if there is none.
> @@ -706,6 +709,9 @@ snap_deps (void)
>
>    /* Now manage all the special targets.  */
>
> +  for (f = lookup_file (".NOTINTERMEDIATE"); f != 0; f = f->prev)
> +    auto_intermediate = 1;
> +
>    for (f = lookup_file (".PRECIOUS"); f != 0; f = f->prev)
>      for (d = f->deps; d != 0; d = d->next)
>        for (f2 = d->file; f2 != 0; f2 = f2->prev)
> diff --git a/filedef.h b/filedef.h
> index 7de6ac0..f849340 100644
> --- a/filedef.h
> +++ b/filedef.h
> @@ -105,6 +105,7 @@ struct file
>
>  extern struct file *default_file;
>
> +extern int auto_intermediate;
>
>  struct file *lookup_file (const char *name);
>  struct file *enter_file (const char *name);
> diff --git a/implicit.c b/implicit.c
> index e5046a4..01c6eb1 100644
> --- a/implicit.c
> +++ b/implicit.c
> @@ -878,7 +878,9 @@ pattern_search (struct file *file, int archive,
>            f->pat_searched = imf->pat_searched;
>            f->also_make = imf->also_make;
>            f->is_target = 1;
> -          f->intermediate = 1;
> +          if (!auto_intermediate)
> +            f->intermediate = 1;
> +
>            f->tried_implicit = 1;
>
>            imf = lookup_file (pat->pattern);
>
>
>
_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make
Loading...