summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--file.c41
-rw-r--r--file.h13
2 files changed, 50 insertions, 4 deletions
diff --git a/file.c b/file.c
index 82e7442..f81c9b9 100644
--- a/file.c
+++ b/file.c
@@ -303,7 +303,8 @@ remove_intermediates (sig)
doneany = 0;
for (i = 0; i < FILE_BUCKETS; ++i)
for (f = files[i]; f != 0; f = f->next)
- if (f->intermediate && (f->dontcare || !f->precious))
+ if (f->intermediate && (f->dontcare || !f->precious)
+ && !f->secondary)
{
int status;
if (f->update_status == -1)
@@ -349,7 +350,8 @@ remove_intermediates (sig)
/* For each dependency of each file, make the `struct dep' point
at the appropriate `struct file' (which may have to be created).
- Also mark the files depended on by .PRECIOUS and .PHONY. */
+ Also mark the files depended on by .PRECIOUS, .PHONY, .SILENT,
+ and various other special targets. */
void
snap_deps ()
@@ -387,6 +389,41 @@ snap_deps ()
f2->last_mtime = (time_t) -1;
}
+ for (f = lookup_file (".INTERMEDIATE"); f != 0; f = f->prev)
+ {
+ /* .INTERMEDIATE with deps listed
+ marks those deps as intermediate files. */
+ for (d = f->deps; d != 0; d = d->next)
+ for (f2 = d->file; f2 != 0; f2 = f2->prev)
+ f2->intermediate = 1;
+ /* .INTERMEDIATE with no deps does nothing.
+ Marking all files as intermediates is useless
+ since the goal targets would be deleted after they are built. */
+ }
+
+ for (f = lookup_file (".SECONDARY"); f != 0; f = f->prev)
+ {
+ /* .SECONDARY with deps listed
+ marks those deps as intermediate files
+ in that they don't get rebuilt if not actually needed;
+ but unlike real intermediate files,
+ these are not deleted after make finishes. */
+ if (f->deps)
+ {
+ for (d = f->deps; d != 0; d = d->next)
+ for (f2 = d->file; f2 != 0; f2 = f2->prev)
+ f2->intermediate = f2->secondary = 1;
+ }
+ /* .SECONDARY with no deps listed marks *all* files that way. */
+ else
+ {
+ int i;
+ for (i = 0; i < FILE_BUCKETS; i++)
+ for (f2 = files[i]; f2; f2= f2->next)
+ f2->intermediate = f2->secondary = 1;
+ }
+ }
+
f = lookup_file (".EXPORT_ALL_VARIABLES");
if (f != 0 && f->is_target)
export_all_variables = 1;
diff --git a/file.h b/file.h
index 5889474..6070ecb 100644
--- a/file.h
+++ b/file.h
@@ -72,6 +72,9 @@ struct file
unsigned int phony:1; /* Nonzero if this is a phony file
i.e., a dependency of .PHONY. */
unsigned int intermediate:1;/* Nonzero if this is an intermediate file. */
+ /* Nonzero, for an intermediate file,
+ means remove_intermediates should not delete it. */
+ unsigned int secondary:1;
unsigned int dontcare:1; /* Nonzero if no complaint is to be made if
this target cannot be remade. */
};
@@ -89,11 +92,17 @@ extern void rename_file (), file_hash_enter ();
extern void set_command_state ();
+/* Return the mtime of file F (a struct file *), caching it.
+ The value is -1 if the file does not exist. */
+#define file_mtime(f) file_mtime_1 ((f), 1)
+/* Return the mtime of file F (a struct file *), caching it.
+ Don't search using vpath for the file--if it doesn't actually exist,
+ we don't find it.
+ The value is -1 if the file does not exist. */
+#define file_mtime_no_search(f) file_mtime_1 ((f), 0)
extern time_t f_mtime ();
#define file_mtime_1(f, v) \
((f)->last_mtime != (time_t) 0 ? (f)->last_mtime : f_mtime ((f), v))
-#define file_mtime(f) file_mtime_1 ((f), 1)
-#define file_mtime_no_search(f) file_mtime_1 ((f), 0)
/* Modtime value to use for `infinitely new'. We used to get the current time
from the system and use that whenever we wanted `new'. But that causes