On Mon, Feb 16, 2026, 1:46 PM Yair Lenga <[email protected]> wrote:
> Hello, > > This patch introduces two optional target-specific variables, > 'valid-for' and 'valid-max', that allow controlling the freshness > and expiration of existing targets based on their modification time. > > Motivation > ---------- > > GNU make treats an existing target with no prerequisites as > permanently up to date. In practice, many build workflows generate > cache or artifact files that should be reused while fresh but > periodically regenerated even without explicit dependencies. Today > this: requires introducing artificial phony prerequisites or external > timestamp logic. > > The new variables provide a declarative mechanism for this: > > valid-for = DURATION > If the target exists and its age is less than or equal to the > specified duration, make treats it as up to date and skips > dependency checking. > > valid-max = DURATION > If the target exists and its age exceeds the specified duration, > make forces a rebuild even if the target has no prerequisites. > > Durations are specified as either an integer number of seconds or a > sequence of <number><unit> segments without spaces, where unit is one > of 's', 'm', 'h', 'd', or 'w' (e.g. "300", "5m", "1d5h"). > > When both variables are present, 'valid-for' takes precedence for > fresh targets, while 'valid-max' forces rebuild of expired targets. > I'm not sure I entirely understand this and think it could probably be better expressed for documentation at least. By fresh I assume you mean otherwise up-to-date? > Implementation > -------------- > > The logic is implemented in update_file_1() via a small helper that > parses and evaluates the TTL variables. Invalid values are ignored > and reported under --debug=v. Successful use of the TTL is reported > under --debug=b. > > This approach preserves existing make semantics while enabling > expiration of leaf targets and optional dependency skipping for > recent artifacts. > Is it usable only for leaves? I guess these variables are not inherited by dependent targets (as other target-local variables are) since that would presumably add a bunch of undesired edges to the DAG? > ------- > Example 1: Periodic reloading of remote resources that change very > frequently. > > cache.json: private valid-max=1d > cache.json: > curl -o $@ https://example/api > > The file will be regenerated once per day even without prerequisites.This > can be useful when a test job is running every few minutes, but loading of > remote resources is time consuming. > > Other use cases include periodically refreshing generated version > stamps, expiring downloaded resources in reproducible builds, and > limiting reuse of expensive intermediate artifacts in CI or code > generation workflows. > > --- > > Patch attached. Comments welcome. > > Best regards, > Yair Lenga >
