/* $NetBSD: make.c,v 1.273 2025/07/06 07:11:31 rillig Exp $ */12/*3* Copyright (c) 1988, 1989, 1990, 19934* The Regents of the University of California. All rights reserved.5*6* This code is derived from software contributed to Berkeley by7* Adam de Boor.8*9* Redistribution and use in source and binary forms, with or without10* modification, are permitted provided that the following conditions11* are met:12* 1. Redistributions of source code must retain the above copyright13* notice, this list of conditions and the following disclaimer.14* 2. Redistributions in binary form must reproduce the above copyright15* notice, this list of conditions and the following disclaimer in the16* documentation and/or other materials provided with the distribution.17* 3. Neither the name of the University nor the names of its contributors18* may be used to endorse or promote products derived from this software19* without specific prior written permission.20*21* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND22* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE23* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE24* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE25* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL26* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS27* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)28* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT29* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY30* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF31* SUCH DAMAGE.32*/3334/*35* Copyright (c) 1989 by Berkeley Softworks36* All rights reserved.37*38* This code is derived from software contributed to Berkeley by39* Adam de Boor.40*41* Redistribution and use in source and binary forms, with or without42* modification, are permitted provided that the following conditions43* are met:44* 1. Redistributions of source code must retain the above copyright45* notice, this list of conditions and the following disclaimer.46* 2. Redistributions in binary form must reproduce the above copyright47* notice, this list of conditions and the following disclaimer in the48* documentation and/or other materials provided with the distribution.49* 3. All advertising materials mentioning features or use of this software50* must display the following acknowledgement:51* This product includes software developed by the University of52* California, Berkeley and its contributors.53* 4. Neither the name of the University nor the names of its contributors54* may be used to endorse or promote products derived from this software55* without specific prior written permission.56*57* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND58* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE59* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE60* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE61* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL62* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS63* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)64* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT65* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY66* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF67* SUCH DAMAGE.68*/6970/*71* Examination of targets and their suitability for creation.72*73* Interface:74* Make_MakeParallel75* Make the targets in parallel mode.76*77* Make_Update After a target is made, update all its parents.78* Perform various bookkeeping chores like the updating79* of the youngestChild field of the parent, filling80* of the IMPSRC variable, etc. Place the parent on the81* toBeMade queue if it should be.82*83* GNode_UpdateYoungestChild84* Update the node's youngestChild field based on the85* child's modification time.86*87* GNode_SetLocalVars88* Set up the various local variables for a89* target, including the .ALLSRC variable, making90* sure that any variable that needs to exist91* at the very least has the empty value.92*93* GNode_IsOODate Determine if a target is out-of-date.94*95* Make_HandleUse See if a child is a .USE node for a parent96* and perform the .USE actions if so.97*98* Make_ExpandUse Expand .USE nodes99*/100101#include "make.h"102#include "dir.h"103#include "job.h"104#ifdef USE_META105# include "meta.h"106#endif107108/* "@(#)make.c 8.1 (Berkeley) 6/6/93" */109MAKE_RCSID("$NetBSD: make.c,v 1.273 2025/07/06 07:11:31 rillig Exp $");110111/* Sequence # to detect recursion. */112static unsigned checked_seqno = 1;113114/*115* The current fringe of the graph.116* These are nodes which await examination by MakeOODate.117* It is added to by Make_Update and subtracted from by MakeStartJobs118*/119static GNodeList toBeMade = LST_INIT;120121122void123debug_printf(const char *fmt, ...)124{125va_list ap;126127va_start(ap, fmt);128vfprintf(opts.debug_file, fmt, ap);129va_end(ap);130}131132char *133GNodeType_ToString(GNodeType type)134{135Buffer buf;136137Buf_Init(&buf);138#define ADD(flag) Buf_AddFlag(&buf, (type & (flag)) != OP_NONE, #flag)139ADD(OP_DEPENDS);140ADD(OP_FORCE);141ADD(OP_DOUBLEDEP);142ADD(OP_OPTIONAL);143ADD(OP_USE);144ADD(OP_EXEC);145ADD(OP_IGNORE);146ADD(OP_PRECIOUS);147ADD(OP_SILENT);148ADD(OP_MAKE);149ADD(OP_JOIN);150ADD(OP_MADE);151ADD(OP_SPECIAL);152ADD(OP_USEBEFORE);153ADD(OP_INVISIBLE);154ADD(OP_NOTMAIN);155ADD(OP_PHONY);156ADD(OP_NOPATH);157ADD(OP_WAIT);158ADD(OP_NOMETA);159ADD(OP_META);160ADD(OP_NOMETA_CMP);161ADD(OP_SUBMAKE);162ADD(OP_TRANSFORM);163ADD(OP_MEMBER);164ADD(OP_LIB);165ADD(OP_ARCHV);166ADD(OP_HAS_COMMANDS);167ADD(OP_SAVE_CMDS);168ADD(OP_DEPS_FOUND);169ADD(OP_MARK);170#undef ADD171if (buf.len == 0)172Buf_AddStr(&buf, "none");173return Buf_DoneData(&buf);174}175176static char *177GNodeFlags_ToString(GNodeFlags flags)178{179Buffer buf;180181Buf_Init(&buf);182Buf_AddFlag(&buf, flags.remake, "REMAKE");183Buf_AddFlag(&buf, flags.childMade, "CHILDMADE");184Buf_AddFlag(&buf, flags.force, "FORCE");185Buf_AddFlag(&buf, flags.doneWait, "DONE_WAIT");186Buf_AddFlag(&buf, flags.doneOrder, "DONE_ORDER");187Buf_AddFlag(&buf, flags.fromDepend, "FROM_DEPEND");188Buf_AddFlag(&buf, flags.doneAllsrc, "DONE_ALLSRC");189Buf_AddFlag(&buf, flags.cycle, "CYCLE");190Buf_AddFlag(&buf, flags.doneCycle, "DONECYCLE");191if (buf.len == 0)192Buf_AddStr(&buf, "none");193return Buf_DoneData(&buf);194}195196void197GNode_FprintDetails(FILE *f, const char *prefix, const GNode *gn,198const char *suffix)199{200char *type = GNodeType_ToString(gn->type);201char *flags = GNodeFlags_ToString(gn->flags);202203fprintf(f, "%s%s, type %s, flags %s%s",204prefix, GNodeMade_Name(gn->made), type, flags, suffix);205free(type);206free(flags);207}208209bool210GNode_ShouldExecute(GNode *gn)211{212return !((gn->type & OP_MAKE)213? opts.noRecursiveExecute214: opts.noExecute);215}216217/* Update the youngest child of the node, according to the given child. */218void219GNode_UpdateYoungestChild(GNode *gn, GNode *cgn)220{221if (gn->youngestChild == NULL || cgn->mtime > gn->youngestChild->mtime)222gn->youngestChild = cgn;223}224225static bool226IsOODateRegular(GNode *gn)227{228/* These rules are inherited from the original Make. */229230if (gn->youngestChild != NULL) {231if (gn->mtime < gn->youngestChild->mtime) {232DEBUG1(MAKE, "modified before source \"%s\"...",233GNode_Path(gn->youngestChild));234return true;235}236return false;237}238239if (gn->mtime == 0 && !(gn->type & OP_OPTIONAL)) {240DEBUG0(MAKE, "nonexistent and no sources...");241return true;242}243244if (gn->type & OP_DOUBLEDEP) {245DEBUG0(MAKE, ":: operator and no sources...");246return true;247}248249return false;250}251252/*253* See if the node is out of date with respect to its sources.254*255* Used by Make_MakeParallel when deciding which nodes to place on the256* toBeMade queue initially and by Make_Update to screen out .USE and257* .EXEC nodes. In the latter case, however, any other sort of node258* must be considered out-of-date since at least one of its children259* will have been recreated.260*261* The mtime field of the node and the youngestChild field of its parents262* may be changed.263*/264bool265GNode_IsOODate(GNode *gn)266{267bool oodate;268269/*270* Certain types of targets needn't even be sought as their datedness271* doesn't depend on their modification time...272*/273if (!(gn->type & (OP_JOIN | OP_USE | OP_USEBEFORE | OP_EXEC))) {274Dir_UpdateMTime(gn, true);275if (DEBUG(MAKE)) {276if (gn->mtime != 0)277debug_printf("modified %s...",278Targ_FmtTime(gn->mtime));279else280debug_printf("nonexistent...");281}282}283284/*285* A target is remade in one of the following circumstances:286*287* its modification time is smaller than that of its youngest288* child and it would actually be run (has commands or is not289* GNode_IsTarget)290*291* it's the object of a force operator292*293* it has no children, was on the lhs of an operator and doesn't294* exist already.295*296* Libraries are only considered out-of-date if the archive module297* says they are.298*299* These weird rules are brought to you by Backward-Compatibility300* and the strange people who wrote 'Make'.301*/302if (gn->type & (OP_USE | OP_USEBEFORE)) {303/*304* If the node is a USE node it is *never* out of date305* no matter *what*.306*/307DEBUG0(MAKE, ".USE node...");308oodate = false;309} else if ((gn->type & OP_LIB) && (gn->mtime == 0 || Arch_IsLib(gn))) {310DEBUG0(MAKE, "library...");311312/*313* always out of date if no children and :: target314* or nonexistent.315*/316oodate = (gn->mtime == 0 || Arch_LibOODate(gn) ||317(gn->youngestChild == NULL &&318(gn->type & OP_DOUBLEDEP)));319} else if (gn->type & OP_JOIN) {320/*321* A target with the .JOIN attribute is only considered322* out-of-date if any of its children was out-of-date.323*/324DEBUG0(MAKE, ".JOIN node...");325DEBUG1(MAKE, "source %smade...",326gn->flags.childMade ? "" : "not ");327oodate = gn->flags.childMade;328} else if (gn->type & (OP_FORCE | OP_EXEC | OP_PHONY)) {329/*330* A node which is the object of the force (!) operator or331* which has the .EXEC attribute is always considered332* out-of-date.333*/334if (DEBUG(MAKE)) {335if (gn->type & OP_FORCE)336debug_printf("! operator...");337else if (gn->type & OP_PHONY)338debug_printf(".PHONY node...");339else340debug_printf(".EXEC node...");341}342oodate = true;343} else if (IsOODateRegular(gn)) {344oodate = true;345} else {346/*347* When a nonexistent child with no sources348* (such as a typically used FORCE source) has been made and349* the target of the child (usually a directory) has the same350* timestamp as the timestamp just given to the nonexistent351* child after it was considered made.352*/353if (DEBUG(MAKE)) {354if (gn->flags.force)355debug_printf("non existing child...");356}357oodate = gn->flags.force;358}359360#ifdef USE_META361if (useMeta)362oodate = meta_oodate(gn, oodate);363#endif364365/*366* If the target isn't out-of-date, the parents need to know its367* modification time. Note that targets that appear to be out-of-date368* but aren't, because they have no commands and are GNode_IsTarget,369* have their mtime stay below their children's mtime to keep parents370* from thinking they're out-of-date.371*/372if (!oodate) {373GNodeListNode *ln;374for (ln = gn->parents.first; ln != NULL; ln = ln->next)375GNode_UpdateYoungestChild(ln->datum, gn);376}377378return oodate;379}380381static void382PretendAllChildrenAreMade(GNode *pgn)383{384GNodeListNode *ln;385386for (ln = pgn->children.first; ln != NULL; ln = ln->next) {387GNode *cgn = ln->datum;388389/* This may also update cgn->path. */390Dir_UpdateMTime(cgn, false);391GNode_UpdateYoungestChild(pgn, cgn);392pgn->unmade--;393}394}395396/*397* Called by Make_MakeParallel and SuffApplyTransform on the downward pass to398* handle .USE and transformation nodes, by copying the child node's commands,399* type flags and children to the parent node.400*401* A .USE node is much like an explicit transformation rule, except its402* commands are always added to the target node, even if the target already403* has commands.404*405* Input:406* cgn The source node, which is either a .USE/.USEBEFORE407* node or a transformation node (OP_TRANSFORM).408* pgn The target node409*/410void411Make_HandleUse(GNode *cgn, GNode *pgn)412{413GNodeListNode *ln; /* An element in the children list */414415#ifdef DEBUG_SRC416if (!(cgn->type & (OP_USE | OP_USEBEFORE | OP_TRANSFORM))) {417debug_printf("Make_HandleUse: called for plain node %s\n",418cgn->name);419/* XXX: debug mode should not affect control flow */420return;421}422#endif423424if ((cgn->type & (OP_USE | OP_USEBEFORE)) ||425Lst_IsEmpty(&pgn->commands)) {426if (cgn->type & OP_USEBEFORE) {427/* .USEBEFORE */428Lst_PrependAll(&pgn->commands, &cgn->commands);429} else {430/* .USE, or target has no commands */431Lst_AppendAll(&pgn->commands, &cgn->commands);432}433}434435for (ln = cgn->children.first; ln != NULL; ln = ln->next) {436GNode *gn = ln->datum;437438/*439* Expand variables in the .USE node's name440* and save the unexpanded form.441* We don't need to do this for commands.442* They get expanded properly when we execute.443*/444if (gn->uname == NULL)445gn->uname = gn->name;446else447free(gn->name);448gn->name = Var_Subst(gn->uname, pgn, VARE_EVAL);449/* TODO: handle errors */450if (gn->uname != NULL && strcmp(gn->name, gn->uname) != 0) {451/* See if we have a target for this node. */452GNode *tgn = Targ_FindNode(gn->name);453if (tgn != NULL)454gn = tgn;455}456457Lst_Append(&pgn->children, gn);458Lst_Append(&gn->parents, pgn);459pgn->unmade++;460}461462pgn->type |=463cgn->type & (unsigned)~(OP_OPMASK | OP_USE | OP_USEBEFORE | OP_TRANSFORM);464}465466/*467* Used by Make_MakeParallel on the downward pass to handle .USE nodes. Should468* be called before the children are enqueued to be looked at by MakeAddChild.469*470* For a .USE child, the commands, type flags and children are copied to the471* parent node, and since the relation to the .USE node is then no longer472* needed, that relation is removed.473*474* Input:475* cgn the child, which may be a .USE node476* pgn the current parent477*/478static void479MakeHandleUse(GNode *cgn, GNode *pgn, GNodeListNode *ln)480{481bool unmarked;482483unmarked = !(cgn->type & OP_MARK);484cgn->type |= OP_MARK;485486if (!(cgn->type & (OP_USE | OP_USEBEFORE)))487return;488489if (unmarked)490Make_HandleUse(cgn, pgn);491492Lst_Remove(&pgn->children, ln);493pgn->unmade--;494}495496static void497HandleUseNodes(GNode *gn)498{499GNodeListNode *ln, *nln;500for (ln = gn->children.first; ln != NULL; ln = nln) {501nln = ln->next;502MakeHandleUse(ln->datum, gn, ln);503}504}505506507/*508* Check the modification time of a gnode, and update it if necessary.509* Return 0 if the gnode does not exist, or its filesystem time if it does.510*/511time_t512Make_Recheck(GNode *gn)513{514time_t mtime;515516Dir_UpdateMTime(gn, true);517mtime = gn->mtime;518519#ifndef RECHECK520/*521* We can't re-stat the thing, but we can at least take care of rules522* where a target depends on a source that actually creates the523* target, but only if it has changed, e.g.524*525* parse.h : parse.o526*527* parse.o : parse.y528* yacc -d parse.y529* cc -c y.tab.c530* mv y.tab.o parse.o531* cmp -s y.tab.h parse.h || mv y.tab.h parse.h532*533* In this case, if the definitions produced by yacc haven't changed534* from before, parse.h won't have been updated and gn->mtime will535* reflect the current modification time for parse.h. This is536* something of a kludge, I admit, but it's a useful one.537*538* XXX: People like to use a rule like "FRC:" to force things that539* depend on FRC to be made, so we have to check for gn->children540* being empty as well.541*/542if (!Lst_IsEmpty(gn->commands) || Lst_IsEmpty(gn->children))543gn->mtime = now;544#else545/*546* This is what Make does and it's actually a good thing, as it547* allows rules like548*549* cmp -s y.tab.h parse.h || cp y.tab.h parse.h550*551* to function as intended. Unfortunately, thanks to the stateless552* nature of NFS (by which I mean the loose coupling of two clients553* using the same file from a common server), there are times when554* the modification time of a file created on a remote machine555* will not be modified before the local stat() implied by the556* Dir_UpdateMTime occurs, thus leading us to believe that the file557* is unchanged, wreaking havoc with files that depend on this one.558*559* I have decided it is better to make too much than to make too560* little, so this stuff is commented out unless you're sure it's ok.561* -- ardeb 1/12/88562*/563/*564* Christos, 4/9/92: If we are saving commands, pretend that565* the target is made now. Otherwise archives with '...' rules566* don't work!567*/568if (!GNode_ShouldExecute(gn) || (gn->type & OP_SAVE_CMDS) ||569(mtime == 0 && !(gn->type & OP_WAIT))) {570DEBUG2(MAKE, " recheck(%s): update time from %s to now\n",571gn->name,572gn->mtime == 0 ? "nonexistent" : Targ_FmtTime(gn->mtime));573gn->mtime = now;574} else {575DEBUG2(MAKE, " recheck(%s): current update time: %s\n",576gn->name, Targ_FmtTime(gn->mtime));577}578#endif579580/*581* XXX: The returned mtime may differ from gn->mtime. Intentionally?582*/583return mtime;584}585586/*587* Set the .PREFIX and .IMPSRC variables for all the implied parents588* of this node.589*/590static void591UpdateImplicitParentsVars(GNode *cgn, const char *cname)592{593GNodeListNode *ln;594const char *cpref = GNode_VarPrefix(cgn);595596for (ln = cgn->implicitParents.first; ln != NULL; ln = ln->next) {597GNode *pgn = ln->datum;598if (pgn->flags.remake) {599Var_Set(pgn, IMPSRC, cname);600if (cpref != NULL)601Var_Set(pgn, PREFIX, cpref);602}603}604}605606/* See if a .ORDER rule stops us from building this node. */607static bool608IsWaitingForOrder(GNode *gn)609{610GNodeListNode *ln;611612for (ln = gn->order_pred.first; ln != NULL; ln = ln->next) {613GNode *ogn = ln->datum;614615if (GNode_IsDone(ogn) || !ogn->flags.remake)616continue;617618DEBUG2(MAKE,619"IsWaitingForOrder: Waiting for .ORDER node \"%s%s\"\n",620ogn->name, ogn->cohort_num);621return true;622}623return false;624}625626static bool MakeBuildChild(GNode *, GNodeListNode *);627628static void629ScheduleOrderSuccessors(GNode *gn)630{631GNodeListNode *toBeMadeNext = toBeMade.first;632GNodeListNode *ln;633634for (ln = gn->order_succ.first; ln != NULL; ln = ln->next) {635GNode *succ = ln->datum;636637if (succ->made == DEFERRED &&638!MakeBuildChild(succ, toBeMadeNext))639succ->flags.doneOrder = true;640}641}642643/*644* Perform update on the parents of a node. Used by JobFinish once645* a node has been dealt with and by MakeStartJobs if it finds an646* up-to-date node.647*648* The unmade field of pgn is decremented and pgn may be placed on649* the toBeMade queue if this field becomes 0.650*651* If the child was made, the parent's flag CHILDMADE field will be652* set true.653*654* If the child is not up-to-date and still does not exist,655* set the FORCE flag on the parents.656*657* If the child wasn't made, the youngestChild field of the parent will be658* altered if the child's mtime is big enough.659*660* Finally, if the child is the implied source for the parent, the661* parent's IMPSRC variable is set appropriately.662*/663void664Make_Update(GNode *cgn)665{666const char *cname; /* the child's name */667time_t mtime = -1;668GNodeList *parents;669GNodeListNode *ln;670GNode *centurion;671672/* It is save to re-examine any nodes again */673checked_seqno++;674675cname = GNode_VarTarget(cgn);676677DEBUG2(MAKE, "Make_Update: %s%s\n", cgn->name, cgn->cohort_num);678679/*680* If the child was actually made, see what its modification time is681* now -- some rules won't actually update the file. If the file682* still doesn't exist, make its mtime now.683*/684if (cgn->made != UPTODATE)685mtime = Make_Recheck(cgn);686687/*688* If this is a `::' node, we must consult its first instance689* which is where all parents are linked.690*/691if ((centurion = cgn->centurion) != NULL) {692if (!Lst_IsEmpty(&cgn->parents))693Punt("%s%s: cohort has parents", cgn->name,694cgn->cohort_num);695centurion->unmade_cohorts--;696if (centurion->unmade_cohorts < 0)697Error("Graph cycles through centurion %s",698centurion->name);699} else {700centurion = cgn;701}702parents = ¢urion->parents;703704/* If this was a .ORDER node, schedule the RHS */705ScheduleOrderSuccessors(centurion);706707/* Now mark all the parents as having one less unmade child */708for (ln = parents->first; ln != NULL; ln = ln->next) {709GNode *pgn = ln->datum;710711if (DEBUG(MAKE)) {712debug_printf("inspect parent %s%s: ", pgn->name,713pgn->cohort_num);714GNode_FprintDetails(opts.debug_file, "", pgn, "");715debug_printf(", unmade %d ", pgn->unmade - 1);716}717718if (!pgn->flags.remake) {719/* This parent isn't needed */720DEBUG0(MAKE, "- not needed\n");721continue;722}723if (mtime == 0 && !(cgn->type & OP_WAIT))724pgn->flags.force = true;725726/*727* If the parent has the .MADE attribute, its timestamp got728* updated to that of its newest child, and its unmade729* child count got set to zero in Make_ExpandUse().730* However other things might cause us to build one of its731* children - and so we mustn't do any processing here when732* the child build finishes.733*/734if (pgn->type & OP_MADE) {735DEBUG0(MAKE, "- .MADE\n");736continue;737}738739if (!(cgn->type & (OP_EXEC | OP_USE | OP_USEBEFORE))) {740if (cgn->made == MADE)741pgn->flags.childMade = true;742GNode_UpdateYoungestChild(pgn, cgn);743}744745/*746* A parent must wait for the completion of all instances747* of a `::' dependency.748*/749if (centurion->unmade_cohorts != 0 ||750!GNode_IsDone(centurion)) {751DEBUG2(MAKE,752"- centurion made %d, %d unmade cohorts\n",753centurion->made, centurion->unmade_cohorts);754continue;755}756757/* One more child of this parent is now made */758pgn->unmade--;759if (pgn->unmade < 0) {760if (DEBUG(MAKE)) {761debug_printf("Graph cycles through %s%s\n",762pgn->name, pgn->cohort_num);763Targ_PrintGraph(2);764}765Error("Graph cycles through %s%s", pgn->name,766pgn->cohort_num);767}768769/*770* We must always rescan the parents of .WAIT and .ORDER771* nodes.772*/773if (pgn->unmade != 0 && !(centurion->type & OP_WAIT)774&& !centurion->flags.doneOrder) {775DEBUG0(MAKE, "- unmade children\n");776continue;777}778if (pgn->made != DEFERRED) {779/*780* Either this parent is on a different branch of781* the tree, or it on the RHS of a .WAIT directive782* or it is already on the toBeMade list.783*/784DEBUG0(MAKE, "- not deferred\n");785continue;786}787788if (IsWaitingForOrder(pgn))789continue;790791if (DEBUG(MAKE)) {792debug_printf("- %s%s made, schedule %s%s (made %d)\n",793cgn->name, cgn->cohort_num,794pgn->name, pgn->cohort_num, pgn->made);795Targ_PrintNode(pgn, 2);796}797/* Ok, we can schedule the parent again */798pgn->made = REQUESTED;799Lst_Enqueue(&toBeMade, pgn);800}801802UpdateImplicitParentsVars(cgn, cname);803}804805static void806UnmarkChildren(GNode *gn)807{808GNodeListNode *ln;809810for (ln = gn->children.first; ln != NULL; ln = ln->next) {811GNode *child = ln->datum;812child->type &= (unsigned)~OP_MARK;813}814}815816/*817* Add a child's name to the ALLSRC and OODATE variables of the given818* node, but only if it has not been given the .EXEC, .USE or .INVISIBLE819* attributes. .EXEC and .USE children are very rarely going to be files,820* so...821*822* If the child is a .JOIN node, its ALLSRC is propagated to the parent.823*824* A child is added to the OODATE variable if its modification time is825* later than that of its parent, as defined by Make, except if the826* parent is a .JOIN node. In that case, it is only added to the OODATE827* variable if it was actually made (since .JOIN nodes don't have828* modification times, the comparison is rather unfair...)..829*830* Input:831* cgn The child to add832* pgn The parent to whose ALLSRC variable it should833* be added834*/835static void836MakeAddAllSrc(GNode *cgn, GNode *pgn)837{838const char *child, *allsrc;839840if (cgn->type & OP_MARK)841return;842cgn->type |= OP_MARK;843844if (cgn->type & (OP_EXEC | OP_USE | OP_USEBEFORE | OP_INVISIBLE))845return;846847if (cgn->type & OP_ARCHV)848child = GNode_VarMember(cgn);849else850child = GNode_Path(cgn);851852if (cgn->type & OP_JOIN)853allsrc = GNode_VarAllsrc(cgn);854else855allsrc = child;856857if (allsrc != NULL)858Var_Append(pgn, ALLSRC, allsrc);859860if (pgn->type & OP_JOIN) {861if (cgn->made == MADE)862Var_Append(pgn, OODATE, child);863864} else if ((pgn->mtime < cgn->mtime) ||865(cgn->mtime >= now && cgn->made == MADE)) {866/*867* It goes in the OODATE variable if the parent is868* younger than the child or if the child has been869* modified more recently than the start of the make.870* This is to keep pmake from getting confused if871* something else updates the parent after the make872* starts (shouldn't happen, I know, but sometimes it873* does). In such a case, if we've updated the child,874* the parent is likely to have a modification time875* later than that of the child and anything that876* relies on the OODATE variable will be hosed.877*878* XXX: This will cause all made children to go in879* the OODATE variable, even if they're not touched,880* if RECHECK isn't defined, since cgn->mtime is set881* to now in Make_Update. According to some people,882* this is good...883*/884Var_Append(pgn, OODATE, child);885}886}887888/*889* Set up the ALLSRC and OODATE variables. Sad to say, it must be890* done separately, rather than while traversing the graph. This is891* because Make defined OODATE to contain all sources whose modification892* times were later than that of the target, *not* those sources that893* were out-of-date. Since in both compatibility and native modes,894* the modification time of the parent isn't found until the child895* has been dealt with, we have to wait until now to fill in the896* variable. As for ALLSRC, the ordering is important and not897* guaranteed when in native mode, so it must be set here, too.898*899* If the node is a .JOIN node, its TARGET variable will be set to900* match its ALLSRC variable.901*/902void903GNode_SetLocalVars(GNode *gn)904{905GNodeListNode *ln;906907if (gn->flags.doneAllsrc)908return;909910UnmarkChildren(gn);911for (ln = gn->children.first; ln != NULL; ln = ln->next)912MakeAddAllSrc(ln->datum, gn);913914if (!Var_Exists(gn, OODATE))915Var_Set(gn, OODATE, "");916if (!Var_Exists(gn, ALLSRC))917Var_Set(gn, ALLSRC, "");918919if (gn->type & OP_JOIN)920Var_Set(gn, TARGET, GNode_VarAllsrc(gn));921gn->flags.doneAllsrc = true;922}923924static void925ScheduleRandomly(GNode *gn)926{927GNodeListNode *ln;928size_t i, n;929930n = 0;931for (ln = toBeMade.first; ln != NULL; ln = ln->next)932n++;933i = n > 0 ? (size_t)random() % (n + 1) : 0;934935if (i == 0) {936Lst_Append(&toBeMade, gn);937return;938}939i--;940941for (ln = toBeMade.first; i > 0; ln = ln->next)942i--;943Lst_InsertBefore(&toBeMade, ln, gn);944}945946static bool947MakeBuildChild(GNode *cn, GNodeListNode *toBeMadeNext)948{949950if (DEBUG(MAKE)) {951debug_printf("MakeBuildChild: inspect %s%s, ",952cn->name, cn->cohort_num);953GNode_FprintDetails(opts.debug_file, "", cn, "\n");954}955if (GNode_IsReady(cn))956return false;957958/* If this node is on the RHS of a .ORDER, check LHSs. */959if (IsWaitingForOrder(cn)) {960/*961* Can't build this (or anything else in this child list) yet962*/963cn->made = DEFERRED;964return false; /* but keep looking */965}966967DEBUG2(MAKE, "MakeBuildChild: schedule %s%s\n",968cn->name, cn->cohort_num);969970cn->made = REQUESTED;971if (opts.randomizeTargets && !(cn->type & OP_WAIT))972ScheduleRandomly(cn);973else if (toBeMadeNext == NULL)974Lst_Append(&toBeMade, cn);975else976Lst_InsertBefore(&toBeMade, toBeMadeNext, cn);977978if (cn->unmade_cohorts != 0) {979ListNode *ln;980981for (ln = cn->cohorts.first; ln != NULL; ln = ln->next)982if (MakeBuildChild(ln->datum, toBeMadeNext))983break;984}985986/*987* If this node is a .WAIT node with unmade children988* then don't add the next sibling.989*/990return cn->type & OP_WAIT && cn->unmade > 0;991}992993static void994MakeChildren(GNode *gn)995{996GNodeListNode *toBeMadeNext = toBeMade.first;997GNodeListNode *ln;998999for (ln = gn->children.first; ln != NULL; ln = ln->next)1000if (MakeBuildChild(ln->datum, toBeMadeNext))1001break;1002}10031004/*1005* Start as many jobs as possible, taking them from the toBeMade queue.1006*1007* If the -q option was given, no job will be started,1008* but as soon as an out-of-date target is found, this function1009* returns true. In all other cases, this function returns false.1010*/1011static bool1012MakeStartJobs(void)1013{1014GNode *gn;1015bool have_token = false;10161017while (!Lst_IsEmpty(&toBeMade)) {1018/*1019* Get token now to avoid cycling job-list when we only1020* have 1 token1021*/1022if (!have_token && !TokenPool_Take())1023break;1024have_token = true;10251026gn = Lst_Dequeue(&toBeMade);1027DEBUG2(MAKE, "Examining %s%s...\n", gn->name, gn->cohort_num);10281029if (gn->made != REQUESTED) {1030debug_printf("internal error: made = %s\n",1031GNodeMade_Name(gn->made));1032Targ_PrintNode(gn, 2);1033Targ_PrintNodes(&toBeMade, 2);1034Targ_PrintGraph(3);1035abort();1036}10371038if (gn->checked_seqno == checked_seqno) {1039/*1040* We've already looked at this node since a job1041* finished...1042*/1043DEBUG2(MAKE, "already checked %s%s\n",1044gn->name, gn->cohort_num);1045gn->made = DEFERRED;1046continue;1047}1048gn->checked_seqno = checked_seqno;10491050if (gn->unmade != 0) {1051gn->made = DEFERRED;1052MakeChildren(gn);1053DEBUG2(MAKE, "deferred %s%s\n",1054gn->name, gn->cohort_num);1055continue;1056}10571058gn->made = BEINGMADE;1059if (GNode_IsOODate(gn)) {1060DEBUG0(MAKE, "out-of-date\n");1061if (opts.query)1062return strcmp(gn->name, ".MAIN") != 0;1063GNode_SetLocalVars(gn);1064Job_Make(gn);1065have_token = false;1066} else {1067DEBUG0(MAKE, "up-to-date\n");1068gn->made = UPTODATE;1069if (gn->type & OP_JOIN) {1070/*1071* Even for an up-to-date .JOIN node, we1072* need it to have its local variables so1073* references to it get the correct value1074* for .TARGET when building up the local1075* variables of its parent(s)...1076*/1077GNode_SetLocalVars(gn);1078}1079Make_Update(gn);1080}1081}10821083if (have_token)1084TokenPool_Return();10851086return false;1087}10881089/* Print the status of a .ORDER node. */1090static void1091MakePrintStatusOrderNode(GNode *ogn, GNode *gn)1092{1093if (!GNode_IsWaitingFor(ogn))1094return;10951096printf(" `%s%s' has .ORDER dependency on %s%s ",1097gn->name, gn->cohort_num, ogn->name, ogn->cohort_num);1098GNode_FprintDetails(stdout, "(", ogn, ")\n");10991100if (DEBUG(MAKE) && opts.debug_file != stdout) {1101debug_printf(" `%s%s' has .ORDER dependency on %s%s ",1102gn->name, gn->cohort_num, ogn->name, ogn->cohort_num);1103GNode_FprintDetails(opts.debug_file, "(", ogn, ")\n");1104}1105}11061107static void1108MakePrintStatusOrder(GNode *gn)1109{1110GNodeListNode *ln;1111for (ln = gn->order_pred.first; ln != NULL; ln = ln->next)1112MakePrintStatusOrderNode(ln->datum, gn);1113}11141115static void MakePrintStatusList(GNodeList *, int *);11161117/*1118* Print the status of a top-level node, viz. it being up-to-date already1119* or not created due to an error in a lower level.1120*/1121static bool1122MakePrintStatus(GNode *gn, int *errors)1123{1124if (gn->flags.doneCycle) {1125/*1126* We've completely processed this node before, don't do1127* it again.1128*/1129return false;1130}11311132if (gn->unmade == 0) {1133gn->flags.doneCycle = true;1134switch (gn->made) {1135case UPTODATE:1136printf("`%s%s' is up to date.\n", gn->name,1137gn->cohort_num);1138break;1139case MADE:1140break;1141case UNMADE:1142case DEFERRED:1143case REQUESTED:1144case BEINGMADE:1145(*errors)++;1146printf("`%s%s' was not built", gn->name,1147gn->cohort_num);1148GNode_FprintDetails(stdout, " (", gn, ")!\n");1149if (DEBUG(MAKE) && opts.debug_file != stdout) {1150debug_printf("`%s%s' was not built", gn->name,1151gn->cohort_num);1152GNode_FprintDetails(opts.debug_file, " (", gn,1153")!\n");1154}1155/* Most likely problem is actually caused by .ORDER */1156MakePrintStatusOrder(gn);1157break;1158default:1159/* Errors - already counted */1160printf("`%s%s' not remade because of errors.\n",1161gn->name, gn->cohort_num);1162if (DEBUG(MAKE) && opts.debug_file != stdout)1163debug_printf(1164"`%s%s' not remade because of errors.\n",1165gn->name, gn->cohort_num);1166break;1167}1168return false;1169}11701171DEBUG3(MAKE, "MakePrintStatus: %s%s has %d unmade children\n",1172gn->name, gn->cohort_num, gn->unmade);1173/*1174* If printing cycles and came to one that has unmade children,1175* print out the cycle by recursing on its children.1176*/1177if (!gn->flags.cycle) {1178/* First time we've seen this node, check all children */1179gn->flags.cycle = true;1180MakePrintStatusList(&gn->children, errors);1181/* Mark that this node needn't be processed again */1182gn->flags.doneCycle = true;1183return false;1184}11851186/* Only output the error once per node */1187gn->flags.doneCycle = true;1188Error("Graph cycles through `%s%s'", gn->name, gn->cohort_num);1189if ((*errors)++ > 100)1190/* Abandon the whole error report */1191return true;11921193/* Reporting for our children will give the rest of the loop */1194MakePrintStatusList(&gn->children, errors);1195return false;1196}11971198static void1199MakePrintStatusList(GNodeList *gnodes, int *errors)1200{1201GNodeListNode *ln;12021203for (ln = gnodes->first; ln != NULL; ln = ln->next)1204if (MakePrintStatus(ln->datum, errors))1205break;1206}12071208static void1209ExamineLater(GNodeList *examine, GNodeList *toBeExamined)1210{1211GNodeListNode *ln;12121213for (ln = toBeExamined->first; ln != NULL; ln = ln->next) {1214GNode *gn = ln->datum;12151216if (gn->flags.remake)1217continue;1218if (gn->type & (OP_USE | OP_USEBEFORE))1219continue;12201221DEBUG2(MAKE, "ExamineLater: need to examine \"%s%s\"\n",1222gn->name, gn->cohort_num);1223Lst_Enqueue(examine, gn);1224}1225}12261227/* Expand .USE nodes and create a new targets list. */1228void1229Make_ExpandUse(GNodeList *targets)1230{1231GNodeList examine = LST_INIT; /* Queue of targets to examine */1232Lst_AppendAll(&examine, targets);12331234/*1235* Make an initial downward pass over the graph, marking nodes to1236* be made as we go down.1237*1238* We call Suff_FindDeps to find where a node is and to get some1239* children for it if it has none and also has no commands. If the1240* node is a leaf, we stick it on the toBeMade queue to be looked1241* at in a minute, otherwise we add its children to our queue and1242* go on.1243*/1244while (!Lst_IsEmpty(&examine)) {1245GNode *gn = Lst_Dequeue(&examine);12461247if (gn->flags.remake)1248continue;1249gn->flags.remake = true;12501251DEBUG2(MAKE, "Make_ExpandUse: examine %s%s\n",1252gn->name, gn->cohort_num);12531254if (gn->type & OP_DOUBLEDEP)1255Lst_PrependAll(&examine, &gn->cohorts);12561257/*1258* Apply any .USE rules before looking for implicit1259* dependencies to make sure everything has commands that1260* should.1261*1262* Make sure that the TARGET is set, so that we can make1263* expansions.1264*/1265if (gn->type & OP_ARCHV) {1266char *eoa = strchr(gn->name, '(');1267char *eon = strchr(gn->name, ')');1268if (eoa == NULL || eon == NULL)1269continue;1270*eoa = '\0';1271*eon = '\0';1272Var_Set(gn, MEMBER, eoa + 1);1273Var_Set(gn, ARCHIVE, gn->name);1274*eoa = '(';1275*eon = ')';1276}12771278Dir_UpdateMTime(gn, false);1279Var_Set(gn, TARGET, GNode_Path(gn));1280UnmarkChildren(gn);1281HandleUseNodes(gn);12821283if (!(gn->type & OP_MADE))1284Suff_FindDeps(gn);1285else {1286PretendAllChildrenAreMade(gn);1287if (gn->unmade != 0) {1288printf(1289"Warning: "1290"%s%s still has %d unmade children\n",1291gn->name, gn->cohort_num, gn->unmade);1292}1293}12941295if (gn->unmade != 0)1296ExamineLater(&examine, &gn->children);1297}12981299Lst_Done(&examine);1300}13011302/* Make the .WAIT node depend on the previous children */1303static void1304AddWaitDependency(GNodeListNode *prevWaitNode, GNode *waitNode)1305{1306GNodeListNode *ln;13071308for (ln = prevWaitNode; ln->datum != waitNode; ln = ln->next) {1309GNode *gn = ln->datum;1310DEBUG3(MAKE, ".WAIT: add dependency \"%s: %s%s\"\n",1311waitNode->name, gn->name, gn->cohort_num);1312Lst_Append(&waitNode->children, gn);1313Lst_Append(&gn->parents, waitNode);1314waitNode->unmade++;1315}1316}13171318/* Convert .WAIT nodes into dependencies. */1319static void1320Make_ProcessWait(GNodeList *targets)1321{1322GNode *pgn; /* 'parent' node we are examining */1323GNodeList examine;13241325/*1326* We need all the nodes to have a common parent in order for the1327* .WAIT and .ORDER scheduling to work.1328* Perhaps this should be done earlier...1329*/13301331pgn = GNode_New(".MAIN");1332pgn->flags.remake = true;1333pgn->type = OP_PHONY | OP_DEPENDS;1334/* Get it displayed in the diag dumps */1335Lst_Prepend(Targ_List(), pgn);13361337{1338GNodeListNode *ln;1339for (ln = targets->first; ln != NULL; ln = ln->next) {1340GNode *cgn = ln->datum;13411342Lst_Append(&pgn->children, cgn);1343Lst_Append(&cgn->parents, pgn);1344pgn->unmade++;1345}1346}13471348/* Start building with the 'dummy' .MAIN' node */1349MakeBuildChild(pgn, NULL);13501351Lst_Init(&examine);1352Lst_Append(&examine, pgn);13531354while (!Lst_IsEmpty(&examine)) {1355GNodeListNode *waitNode, *ln;13561357pgn = Lst_Dequeue(&examine);13581359/* We only want to process each child-list once */1360if (pgn->flags.doneWait)1361continue;1362pgn->flags.doneWait = true;1363DEBUG1(MAKE, "Make_ProcessWait: examine %s\n", pgn->name);13641365if (pgn->type & OP_DOUBLEDEP)1366Lst_PrependAll(&examine, &pgn->cohorts);13671368waitNode = pgn->children.first;1369for (ln = pgn->children.first; ln != NULL; ln = ln->next) {1370GNode *cgn = ln->datum;1371if (cgn->type & OP_WAIT) {1372AddWaitDependency(waitNode, cgn);1373waitNode = ln;1374} else1375Lst_Append(&examine, cgn);1376}1377}13781379Lst_Done(&examine);1380}13811382bool1383Make_MakeParallel(GNodeList *targets)1384{1385int errors; /* Number of errors the Job module reports */13861387Lst_Init(&toBeMade);13881389Make_ExpandUse(targets);1390Make_ProcessWait(targets);13911392if (DEBUG(MAKE)) {1393debug_printf("#***# full graph\n");1394Targ_PrintGraph(1);1395}13961397if (opts.query)1398return MakeStartJobs();13991400(void)MakeStartJobs();1401while (!Lst_IsEmpty(&toBeMade) || jobTokensRunning > 0) {1402Job_CatchOutput();1403(void)MakeStartJobs();1404}14051406errors = Job_MakeDotEnd();14071408DEBUG1(MAKE, "done: errors %d\n", errors);1409if (errors == 0) {1410MakePrintStatusList(targets, &errors);1411if (DEBUG(MAKE)) {1412debug_printf("done: errors %d\n", errors);1413if (errors > 0)1414Targ_PrintGraph(4);1415}1416}1417return errors > 0;1418}141914201421