2 * Copyright (c) 1988, 1989, 1990, 1993
3 * The Regents of the University of California. All rights reserved.
4 * Copyright (c) 1989 by Berkeley Softworks
7 * This code is derived from software contributed to Berkeley by
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * @(#)suff.c 8.4 (Berkeley) 3/21/94
39 * $FreeBSD: src/usr.bin/make/suff.c,v 1.43 2005/02/04 13:23:39 harti Exp $
40 * $DragonFly: src/usr.bin/make/suff.c,v 1.66 2005/09/24 07:37:01 okumoto Exp $
45 * Functions to maintain suffix lists and find implicit dependents
46 * using suffix transformation rules
49 * Suff_Init Initialize all things to do with suffixes.
51 * Suff_DoPaths This function is used to make life easier
52 * when searching for a file according to its
53 * suffix. It takes the global search path,
54 * as defined using the .PATH: target, and appends
55 * its directories to the path of each of the
56 * defined suffixes, as specified using
57 * .PATH<suffix>: targets. In addition, all
58 * directories given for suffixes labeled as
59 * include files or libraries, using the .INCLUDES
60 * or .LIBS targets, are played with using
61 * Dir_MakeFlags to create the .INCLUDES and
62 * .LIBS global variables.
64 * Suff_ClearSuffixes Clear out all the suffixes and defined
67 * Suff_IsTransform Return true if the passed string is the lhs
68 * of a transformation rule.
70 * Suff_AddSuffix Add the passed string as another known suffix.
72 * Suff_GetPath Return the search path for the given suffix.
74 * Suff_AddInclude Mark the given suffix as denoting an include
77 * Suff_AddLib Mark the given suffix as denoting a library.
79 * Suff_AddTransform Add another transformation to the suffix
80 * graph. Returns GNode suitable for framing, I
81 * mean, tacking commands, attributes, etc. on.
83 * Suff_SetNull Define the suffix to consider the suffix of
84 * any file that doesn't have a known one.
86 * Suff_FindDeps Find implicit sources for and the location of
87 * a target based on its suffix. Returns the
88 * bottom-most node added to the graph or NULL
89 * if the target had no implicit sources.
92 #include <sys/queue.h>
113 * The suffix used to denote libraries and is used by the Suff module
114 * to find the search path on which to seek any -l<xx> targets.
118 /* Lst of suffixes */
119 static Lst sufflist
= Lst_Initializer(sufflist
);
121 /* Lst of suffixes to be cleaned */
122 static Lst suffClean
= Lst_Initializer(suffClean
);
125 static Lst srclist
= Lst_Initializer(srclist
);
127 /* Lst of transformation rules */
128 static Lst transforms
= Lst_Initializer(transforms
);
130 /* Counter for assigning suffix numbers */
134 * Structure describing an individual suffix.
136 typedef struct Suff
{
137 char *name
; /* The suffix itself */
138 int nameLen
; /* Length of the suffix */
139 short flags
; /* Type of suffix */
140 #define SUFF_INCLUDE 0x01 /* One which is #include'd */
141 #define SUFF_LIBRARY 0x02 /* One which contains a library */
142 #define SUFF_NULL 0x04 /* The empty suffix */
143 struct Path searchPath
; /* Path for files with this suffix */
144 int sNum
; /* The suffix number */
145 int refCount
; /* Reference count of list membership */
146 Lst parents
; /* Suffixes we have a transformation to */
147 Lst children
; /* Suffixes we have a transformation from */
148 Lst ref
; /* List of lists this suffix is referenced */
152 * Structure used in the search for implied sources.
155 char *file
; /* The file to look for */
156 char *pref
; /* Prefix from which file was formed */
157 Suff
*suff
; /* The suffix on the file */
158 struct Src
*parent
; /* The Src for which this is a source */
159 GNode
*node
; /* The node describing the file */
160 int children
; /* Count of existing children (so we don't free
161 * this thing too early or never nuke it) */
163 Lst cp
; /* Debug; children list */
167 /* The NULL suffix for this run */
168 static Suff
*suffNull
;
170 /* The empty suffix required for POSIX single-suffix transformation rules */
171 static Suff
*emptySuff
;
173 static void SuffFindDeps(GNode
*, Lst
*);
177 *-----------------------------------------------------------------------
178 * SuffSuffIsSuffix --
179 * See if suff is a suffix of str.
182 * NULL if it ain't, pointer to character in str before suffix if
187 *-----------------------------------------------------------------------
190 SuffSuffIsSuffix(const Suff
*s
, char *str
)
192 const char *p1
; /* Pointer into suffix name */
193 char *p2
; /* Pointer into string being examined */
197 p1
= s
->name
+ s
->nameLen
;
200 while (p1
>= s
->name
&& len
> 0 && *p1
== *p2
) {
206 return (p1
== s
->name
- 1 ? p2
: NULL
);
210 *-----------------------------------------------------------------------
212 * Find a suffix given its name.
215 * The suffix or NULL.
219 *-----------------------------------------------------------------------
222 SuffSuffFind(const char *s
)
226 LST_FOREACH(ln
, &sufflist
) {
227 if (strcmp(s
, ((const Suff
*)Lst_Datum(ln
))->name
) == 0)
228 return (Lst_Datum(ln
));
234 *-----------------------------------------------------------------------
243 *-----------------------------------------------------------------------
246 SuffTransFind(const char *name
)
250 LST_FOREACH(ln
, &transforms
) {
251 if (strcmp(name
, ((const GNode
*)Lst_Datum(ln
))->name
) == 0)
252 return (Lst_Datum(ln
));
257 /*********** Maintenance Functions ************/
261 * Keep this function for now until it is clear why a .SUFFIXES: doesn't
262 * actually delete the suffixes but just puts them on the suffClean list.
265 *-----------------------------------------------------------------------
267 * Free up all memory associated with the given suffix structure.
273 * the suffix entry is detroyed
274 *-----------------------------------------------------------------------
287 Lst_Destroy(&s
->ref
, NOFREE
);
288 Lst_Destroy(&s
->children
, NOFREE
);
289 Lst_Destroy(&s
->parents
, NOFREE
);
290 Lst_Destroy(&s
->searchPath
, Dir_Destroy
);
298 *-----------------------------------------------------------------------
300 * Remove the suffix into the list
306 * The reference count for the suffix is decremented
307 *-----------------------------------------------------------------------
310 SuffRemove(Lst
*l
, Suff
*s
)
312 LstNode
*ln
= Lst_Member(l
, s
);
321 *-----------------------------------------------------------------------
323 * Insert the suffix into the list keeping the list ordered by suffix
330 * The reference count of the suffix is incremented
331 *-----------------------------------------------------------------------
334 SuffInsert(Lst
*l
, Suff
*s
)
336 LstNode
*ln
; /* current element in l we're examining */
337 Suff
*s2
; /* the suffix descriptor in this element */
340 for (ln
= Lst_First(l
); ln
!= NULL
; ln
= Lst_Succ(ln
)) {
342 if (s2
->sNum
>= s
->sNum
)
346 DEBUGF(SUFF
, ("inserting an empty list?..."));
349 DEBUGF(SUFF
, ("inserting %s(%d)...", s
->name
, s
->sNum
));
351 DEBUGF(SUFF
, ("at end of list\n"));
354 Lst_AtEnd(&s
->ref
, l
);
355 } else if (s2
->sNum
!= s
->sNum
) {
356 DEBUGF(SUFF
, ("before %s(%d)\n", s2
->name
, s2
->sNum
));
357 Lst_Insert(l
, ln
, s
);
359 Lst_AtEnd(&s
->ref
, l
);
361 DEBUGF(SUFF
, ("already there\n"));
366 *-----------------------------------------------------------------------
367 * Suff_ClearSuffixes --
368 * This is gross. Nuke the list of suffixes but keep all transformation
369 * rules around. The transformation graph is destroyed in this process,
370 * but we leave the list of rules so when a new graph is formed the rules
372 * This function is called from the parse module when a
373 * .SUFFIXES:\n line is encountered.
379 * the sufflist and its graph nodes are destroyed
380 *-----------------------------------------------------------------------
383 Suff_ClearSuffixes(void)
386 Lst_Concat(&suffClean
, &sufflist
, LST_CONCLINK
);
389 suffNull
= emptySuff
;
391 * Clear suffNull's children list (the other suffixes are built new, but
392 * suffNull is used as is).
393 * NOFREE is used because all suffixes are are on the suffClean list.
394 * suffNull should not have parents.
396 Lst_Destroy(&suffNull
->children
, NOFREE
);
400 *-----------------------------------------------------------------------
401 * SuffParseTransform --
402 * Parse a transformation string to find its two component suffixes.
405 * true if the string is a valid transformation and false otherwise.
408 * The passed pointers are overwritten.
410 *-----------------------------------------------------------------------
413 SuffParseTransform(char *str
, Suff
**srcPtr
, Suff
**targPtr
)
415 LstNode
*srcLn
; /* element in suffix list of trans source*/
416 Suff
*src
; /* Source of transformation */
417 char *str2
; /* Extra pointer (maybe target suffix) */
418 LstNode
*singleLn
; /* element in suffix list of any suffix
419 * that exactly matches str */
420 Suff
*single
= NULL
; /* Source of possible transformation to
426 * Loop looking first for a suffix that matches the start of the
427 * string and then for one that exactly matches the rest of it. If
428 * we can find two that meet these criteria, we've successfully
431 srcLn
= Lst_First(&sufflist
);
433 /* advance to next possible suffix */
434 while (srcLn
!= NULL
) {
435 src
= Lst_Datum(srcLn
);
436 if (strncmp(str
, src
->name
, strlen(src
->name
)) == 0)
438 srcLn
= LST_NEXT(srcLn
);
443 * Ran out of source suffixes -- no such rule
445 if (singleLn
!= NULL
) {
447 * Not so fast Mr. Smith! There was a suffix
448 * that encompassed the entire string, so we
449 * assume it was a transformation to the null
450 * suffix (thank you POSIX). We still prefer to
451 * find a double rule over a singleton, hence we
452 * leave this check until the end.
454 * XXX: Use emptySuff over suffNull?
462 str2
= str
+ src
->nameLen
;
468 *targPtr
= SuffSuffFind(str2
);
469 if (*targPtr
!= NULL
) {
475 srcLn
= LST_NEXT(srcLn
);
480 *-----------------------------------------------------------------------
481 * Suff_IsTransform --
482 * Return true if the given string is a transformation rule
486 * true if the string is a concatenation of two known suffixes.
491 *-----------------------------------------------------------------------
494 Suff_IsTransform(char *str
)
498 return (SuffParseTransform(str
, &src
, &targ
));
502 *-----------------------------------------------------------------------
503 * Suff_AddTransform --
504 * Add the transformation rule described by the line to the
505 * list of rules and place the transformation itself in the graph
508 * The node created for the transformation in the transforms list
511 * The node is placed on the end of the transforms Lst and links are
512 * made between the two suffixes mentioned in the target name
513 *-----------------------------------------------------------------------
516 Suff_AddTransform(char *line
)
518 GNode
*gn
; /* GNode of transformation rule */
519 Suff
*s
; /* source suffix */
520 Suff
*t
; /* target suffix */
522 gn
= SuffTransFind(line
);
525 * Make a new graph node for the transformation.
526 * It will be filled in by the Parse module.
528 gn
= Targ_NewGN(line
);
529 Lst_AtEnd(&transforms
, gn
);
532 * New specification for transformation rule. Just nuke the
533 * old list of commands so they can be filled in again...
534 * We don't actually free the commands themselves, because a
535 * given command can be attached to several different
538 Lst_Destroy(&gn
->commands
, NOFREE
);
539 Lst_Destroy(&gn
->children
, NOFREE
);
542 gn
->type
= OP_TRANSFORM
;
544 SuffParseTransform(line
, &s
, &t
);
547 * link the two together in the proper relationship and order
549 DEBUGF(SUFF
, ("defining transformation from `%s' to `%s'\n",
551 SuffInsert(&t
->children
, s
);
552 SuffInsert(&s
->parents
, t
);
558 *-----------------------------------------------------------------------
559 * Suff_EndTransform --
560 * Handle the finish of a transformation definition, removing the
561 * transformation from the graph if it has neither commands nor
562 * sources. This is called from the Parse module at the end of
563 * a dependency block.
566 * If the node has no commands or children, the children and parents
567 * lists of the affected suffices are altered.
569 *-----------------------------------------------------------------------
572 Suff_EndTransform(const GNode
*gn
)
576 if (!Lst_IsEmpty(&gn
->commands
) || !Lst_IsEmpty(&gn
->children
)) {
577 DEBUGF(SUFF
, ("transformation %s complete\n", gn
->name
));
582 * SuffParseTransform() may fail for special rules which are not
583 * actual transformation rules (e.g., .DEFAULT).
585 if (!SuffParseTransform(gn
->name
, &s
, &t
))
588 DEBUGF(SUFF
, ("deleting transformation from `%s' to `%s'\n",
592 * Remove the source from the target's children list. We check
593 * for a NULL return to handle a beanhead saying something like
596 * We'll be called twice when the next target is seen, but .c
597 * and .o are only linked once...
599 SuffRemove(&t
->children
, s
);
602 * Remove the target from the source's parents list
604 SuffRemove(&s
->parents
, t
);
608 *-----------------------------------------------------------------------
609 * SuffRebuildGraph --
610 * Called from Suff_AddSuffix via LST_FOREACH to search through the
611 * list of existing transformation rules and rebuild the transformation
612 * graph when it has been destroyed by Suff_ClearSuffixes. If the
613 * given rule is a transformation involving this suffix and another,
614 * existing suffix, the proper relationship is established between
618 * The appropriate links will be made between this suffix and
619 * others if transformation rules exist for it.
621 *-----------------------------------------------------------------------
624 SuffRebuildGraph(const GNode
*transform
, Suff
*s
)
630 * First see if it is a transformation from this suffix.
632 if (strncmp(transform
->name
, s
->name
, strlen(s
->name
)) == 0) {
633 cp
= transform
->name
+ strlen(s
->name
);
635 if (cp
[0] == '\0') /* null rule */
638 s2
= SuffSuffFind(cp
);
641 * Found target. Link in and return, since it can't be
644 SuffInsert(&s2
->children
, s
);
645 SuffInsert(&s
->parents
, s2
);
651 * Not from, maybe to?
653 cp
= SuffSuffIsSuffix(s
, transform
->name
);
656 * Null-terminate the source suffix in order to find it.
659 s2
= SuffSuffFind(transform
->name
);
662 * Replace the start of the target suffix
667 * Found it -- establish the proper relationship
669 SuffInsert(&s
->children
, s2
);
670 SuffInsert(&s2
->parents
, s
);
676 *-----------------------------------------------------------------------
678 * Add the suffix in string to the end of the list of known suffixes.
679 * Should we restructure the suffix graph? Make doesn't...
685 * A GNode is created for the suffix and a Suff structure is created and
686 * added to the suffixes list unless the suffix was already known.
687 *-----------------------------------------------------------------------
690 Suff_AddSuffix(char *str
)
692 Suff
*s
; /* new suffix descriptor */
695 if (SuffSuffFind(str
) != NULL
)
701 s
= emalloc(sizeof(Suff
));
703 s
->name
= estrdup(str
);
704 s
->nameLen
= strlen(s
->name
);
705 TAILQ_INIT(&s
->searchPath
);
706 Lst_Init(&s
->children
);
707 Lst_Init(&s
->parents
);
713 Lst_AtEnd(&sufflist
, s
);
716 * Look for any existing transformations from or to this suffix.
717 * XXX: Only do this after a Suff_ClearSuffixes?
719 LST_FOREACH(ln
, &transforms
)
720 SuffRebuildGraph(Lst_Datum(ln
), s
);
724 *-----------------------------------------------------------------------
726 * Return the search path for the given suffix, if it's defined.
729 * The searchPath for the desired suffix or NULL if the suffix isn't
734 *-----------------------------------------------------------------------
737 Suff_GetPath(char *sname
)
741 s
= SuffSuffFind(sname
);
744 return (&s
->searchPath
);
748 *-----------------------------------------------------------------------
750 * Extend the search paths for all suffixes to include the default
757 * The searchPath field of all the suffixes is extended by the
758 * directories in dirSearchPath. If paths were specified for the
759 * ".h" suffix, the directories are stuffed into a global variable
760 * called ".INCLUDES" with each directory preceded by a -I. The same
761 * is done for the ".a" suffix, except the variable is called
762 * ".LIBS" and the flag is -L.
763 *-----------------------------------------------------------------------
771 struct Path inIncludes
; /* Cumulative .INCLUDES path */
772 struct Path inLibs
; /* Cumulative .LIBS path */
774 TAILQ_INIT(&inIncludes
);
777 for (ln
= Lst_First(&sufflist
); ln
!= NULL
; ln
= Lst_Succ(ln
)) {
780 if (s
->flags
& SUFF_INCLUDE
) {
781 Path_Concat(&inIncludes
, &s
->searchPath
);
783 #endif /* INCLUDES */
785 if (s
->flags
& SUFF_LIBRARY
) {
786 Path_Concat(&inLibs
, &s
->searchPath
);
788 #endif /* LIBRARIES */
789 Path_Concat(&s
->searchPath
, &dirSearchPath
);
792 ptr
= Path_MakeFlags("-I", &inIncludes
);
793 Var_SetGlobal(".INCLUDES", ptr
);
796 ptr
= Path_MakeFlags("-L", &inLibs
);
797 Var_SetGlobal(".LIBS", ptr
);
800 Path_Clear(&inIncludes
);
805 *-----------------------------------------------------------------------
807 * Add the given suffix as a type of file which gets included.
808 * Called from the parse module when a .INCLUDES line is parsed.
809 * The suffix must have already been defined.
815 * The SUFF_INCLUDE bit is set in the suffix's flags field
817 *-----------------------------------------------------------------------
820 Suff_AddInclude(char *sname
)
824 if ((s
= SuffSuffFind(sname
)) != NULL
)
825 s
->flags
|= SUFF_INCLUDE
;
829 *-----------------------------------------------------------------------
831 * Add the given suffix as a type of file which is a library.
832 * Called from the parse module when parsing a .LIBS line. The
833 * suffix must have been defined via .SUFFIXES before this is
840 * The SUFF_LIBRARY bit is set in the suffix's flags field
842 *-----------------------------------------------------------------------
845 Suff_AddLib(char *sname
)
849 if ((s
= SuffSuffFind(sname
)) != NULL
)
850 s
->flags
|= SUFF_LIBRARY
;
854 * Create a new Src structure
857 SuffSrcCreate(char *file
, char *prefix
, Suff
*suff
, Src
*parent
, GNode
*node
)
861 s
= emalloc(sizeof(*s
));
876 /********** Implicit Source Search Functions *********/
879 *-----------------------------------------------------------------------
881 * Add all the children of targ as Src structures to the given list:
882 * Add a suffix as a Src structure to the given list with its parent
883 * being the given Src structure. If the suffix is the null suffix,
884 * the prefix is used unaltered as the file name in the Src structure.
890 * Lots of structures are created and added to the list
891 *-----------------------------------------------------------------------
894 SuffAddLevel(Lst
*l
, Src
*targ
)
903 LST_FOREACH(ln
, &targ
->suff
->children
) {
904 suff
= Lst_Datum(ln
);
906 if ((suff
->flags
& SUFF_NULL
) && *suff
->name
!= '\0') {
908 * If the suffix has been marked as the NULL suffix,
909 * also create a Src structure for a file with no suffix
910 * attached. Two birds, and all that...
912 s2
= SuffSrcCreate(estrdup(targ
->pref
), targ
->pref
,
918 Lst_AtEnd(&targ
->cp
, s2
);
919 printf("1 add %p %p to %p:", targ
, s2
, l
);
921 printf("%p ", (const void *)Lst_Datum(ln1
));
926 str_concat(targ
->pref
, '\0', suff
->name
),
927 targ
->pref
, suff
, targ
, NULL
);
932 Lst_AtEnd(&targ
->cp
, s2
);
933 printf("2 add %p %p to %p:", targ
, s2
, l
);
935 printf("%p ", (const void *)Lst_Datum(ln1
));
942 *----------------------------------------------------------------------
944 * Free all src structures in list that don't have a reference count
945 * XXX this actually frees only the first of these.
948 * True if a src was removed
951 * The memory is free'd.
952 *----------------------------------------------------------------------
955 SuffRemoveSrc(Lst
*l
)
962 printf("cleaning %lx: ", (unsigned long) l
);
964 printf("%p ", (const void *)Lst_Datum(ln
));
968 for (ln
= Lst_First(l
); ln
!= NULL
; ln
= ln1
) {
971 s
= (Src
*)Lst_Datum(ln
);
972 if (s
->children
== 0) {
978 LstNode
*ln
= Lst_Member(&s
->parent
->cp
, s
);
980 Lst_Remove(&s
->parent
->cp
, ln
);
982 --s
->parent
->children
;
985 printf("free: [l=%p] p=%p %d\n", l
, s
, s
->children
);
986 Lst_Destroy(&s
->cp
, NOFREE
);
997 printf("keep: [l=%p] p=%p %d: ", l
, s
, s
->children
);
998 LST_FOREACH(tln
, &s
->cp
)
999 printf("%p ", (const void *)Lst_Datum(tln
));
1009 *-----------------------------------------------------------------------
1011 * Find the first existing file/target in the list srcs
1014 * The lowest structure in the chain of transformations
1018 *-----------------------------------------------------------------------
1021 SuffFindThem(Lst
*srcs
, Lst
*slst
)
1023 Src
*s
; /* current Src */
1024 Src
*rs
; /* returned Src */
1029 while (!Lst_IsEmpty (srcs
)) {
1030 s
= Lst_DeQueue(srcs
);
1032 DEBUGF(SUFF
, ("\ttrying %s...", s
->file
));
1035 * A file is considered to exist if either a node exists in the
1036 * graph for it or the file actually exists.
1038 if (Targ_FindNode(s
->file
, TARG_NOCREATE
) != NULL
) {
1040 printf("remove %p from %p\n", s
, srcs
);
1046 if ((ptr
= Path_FindFile(s
->file
,
1047 &s
->suff
->searchPath
)) != NULL
) {
1050 printf("remove %p from %p\n", s
, srcs
);
1056 DEBUGF(SUFF
, ("not there\n"));
1058 SuffAddLevel(srcs
, s
);
1063 DEBUGF(SUFF
, ("got it\n"));
1069 *-----------------------------------------------------------------------
1071 * See if any of the children of the target in the Src structure is
1072 * one from which the target can be transformed. If there is one,
1073 * a Src structure is put together for it and returned.
1076 * The Src structure of the "winning" child, or NULL if no such beast.
1079 * A Src structure may be allocated.
1081 *-----------------------------------------------------------------------
1084 SuffFindCmds(Src
*targ
, Lst
*slst
)
1086 LstNode
*ln
; /* General-purpose list node */
1087 GNode
*t
; /* Target GNode */
1088 GNode
*s
; /* Source GNode */
1089 int prefLen
;/* The length of the defined prefix */
1090 Suff
*suff
; /* Suffix on matching beastie */
1091 Src
*ret
; /* Return value */
1095 prefLen
= strlen(targ
->pref
);
1097 for (ln
= Lst_First(&t
->children
); ln
!= NULL
; ln
= Lst_Succ(ln
)) {
1100 cp
= strrchr(s
->name
, '/');
1106 if (strncmp(cp
, targ
->pref
, prefLen
) == 0) {
1108 * The node matches the prefix ok, see if it has
1111 suff
= SuffSuffFind(&cp
[prefLen
]);
1114 * It even has a known suffix, see if there's
1115 * a transformation defined between the node's
1116 * suffix and the target's suffix.
1118 * XXX: Handle multi-stage transformations
1121 if (Lst_Member(&suff
->parents
,
1122 targ
->suff
) != NULL
) {
1124 * Hot Damn! Create a new Src structure
1125 * to describe this transformation
1126 * (making sure to duplicate the
1127 * source node's name so Suff_FindDeps
1128 * can free it again (ick)), and return
1129 * the new structure.
1131 ret
= SuffSrcCreate(estrdup(s
->name
),
1132 targ
->pref
, suff
, targ
, s
);
1134 targ
->children
+= 1;
1136 printf("3 add %p %p\n", &targ
, ret
);
1137 Lst_AtEnd(&targ
->cp
, ret
);
1139 Lst_AtEnd(slst
, ret
);
1140 DEBUGF(SUFF
, ("\tusing existing source "
1151 * The child node contains variable references. Expand them and return
1152 * a list of expansions.
1155 SuffExpandVariables(GNode
*parent
, GNode
*child
, Lst
*members
)
1163 DEBUGF(SUFF
, ("Expanding \"%s\"...", child
->name
));
1164 buf
= Var_Subst(child
->name
, parent
, true);
1167 if (child
->type
& OP_ARCHV
) {
1169 * Node was an archive(member) target, so we
1170 * want to call on the Arch module to find the
1171 * nodes for us, expanding variables in the
1174 Arch_ParseArchive(&cp
, members
, parent
);
1175 Buf_Destroy(buf
, true);
1179 * Break the result into a vector of strings whose nodes we can find,
1180 * then add those nodes to the members list.
1182 for (start
= cp
; *start
== ' ' || *start
== '\t'; start
++)
1185 for (cp
= start
; *cp
!= '\0'; cp
++) {
1186 if (*cp
== ' ' || *cp
== '\t') {
1188 * White-space -- terminate element, find the node,
1189 * add it, skip any further spaces.
1192 Lst_AtEnd(members
, Targ_FindNode(start
, TARG_CREATE
));
1194 while (*cp
== ' ' || *cp
== '\t') {
1198 * Adjust cp for increment at
1199 * start of loop, but set start
1200 * to first non-space.
1204 } else if (*cp
== '$') {
1206 * Start of a variable spec -- contact variable module
1207 * to find the end so we can skip over it.
1213 junk
= Var_Parse(cp
, parent
, true, &len
, &doFree
);
1214 if (junk
!= var_Error
) {
1221 } else if (*cp
== '\\' && *cp
!= '\0') {
1223 * Escaped something -- skip over it
1231 * Stuff left over -- add it to the
1234 Lst_AtEnd(members
, Targ_FindNode(start
, TARG_CREATE
));
1237 Buf_Destroy(buf
, true);
1241 * The child node contains wildcards. Expand them and return a list of
1245 SuffExpandWildcards(GNode
*child
, Lst
*members
)
1248 Lst exp
; /* List of expansions */
1250 struct Path
*path
; /* Search path along which to expand */
1255 * Find a path along which to expand the word.
1257 * If the word has a known suffix, use that path.
1258 * If it has no known suffix and we're allowed to use the null
1259 * suffix, use its path.
1260 * Else use the default system search path.
1262 LST_FOREACH(ln
, &sufflist
) {
1263 if (SuffSuffIsSuffix(Lst_Datum(ln
), child
->name
) != NULL
)
1267 DEBUGF(SUFF
, ("Wildcard expanding \"%s\"...", child
->name
));
1270 Suff
*s
= Lst_Datum(ln
);
1272 DEBUGF(SUFF
, ("suffix is \"%s\"...", s
->name
));
1273 path
= &s
->searchPath
;
1276 * Use default search path
1278 path
= &dirSearchPath
;
1282 * Expand the word along the chosen path
1285 Path_Expand(child
->name
, path
, &exp
);
1287 while (!Lst_IsEmpty(&exp
)) {
1289 * Fetch next expansion off the list and find its GNode
1291 cp
= Lst_DeQueue(&exp
);
1293 DEBUGF(SUFF
, ("%s...", cp
));
1294 Lst_AtEnd(members
, Targ_FindNode(cp
, TARG_CREATE
));
1299 *-----------------------------------------------------------------------
1300 * SuffExpandChildren --
1301 * Expand the names of any children of a given node that contain
1302 * variable invocations or file wildcards into actual targets.
1308 * The expanded node is removed from the parent's list of children,
1309 * and the parent's unmade counter is decremented, but other nodes
1312 *-----------------------------------------------------------------------
1315 SuffExpandChildren(GNode
*parent
, LstNode
*current
)
1317 GNode
*cchild
; /* current child */
1319 LstNode
*prev
; /* node after which to append new source */
1320 Lst members
; /* expanded nodes */
1322 if (current
== NULL
) {
1323 /* start from begin of parent's children list */
1324 current
= Lst_First(&parent
->children
);
1327 while (current
!= NULL
) {
1328 cchild
= Lst_Datum(current
);
1331 * First do variable expansion -- this takes precedence over
1332 * wildcard expansion. If the result contains wildcards, they'll
1333 * be gotten to later since the resulting words are tacked
1334 * instead of the current child onto the children list.
1336 * XXXHB what if cchild contains lib.a(t1.o t2.o t3.o) but
1339 if (strchr(cchild
->name
, '$') != NULL
) {
1340 SuffExpandVariables(parent
, cchild
, &members
);
1342 } else if (Dir_HasWildcards(cchild
->name
)) {
1343 SuffExpandWildcards(cchild
, &members
);
1346 /* nothing special just advance to next child */
1347 current
= LST_NEXT(current
);
1352 * New nodes effectively take the place of the child,
1353 * so place them after the child
1358 * Add all new elements to the parent node if they aren't
1359 * already children of it.
1361 while(!Lst_IsEmpty(&members
)) {
1362 gn
= Lst_DeQueue(&members
);
1364 DEBUGF(SUFF
, ("%s...", gn
->name
));
1365 if (Lst_Member(&parent
->children
, gn
) == NULL
) {
1366 Lst_Append(&parent
->children
, prev
, gn
);
1367 prev
= Lst_Succ(prev
);
1368 Lst_AtEnd(&gn
->parents
, parent
);
1374 * Now the source is expanded, remove it from the list
1375 * of children to keep it from being processed.
1376 * Advance to the next child.
1379 current
= LST_NEXT(current
);
1382 Lst_Remove(&parent
->children
, prev
);
1383 DEBUGF(SUFF
, ("\n"));
1388 *-----------------------------------------------------------------------
1389 * SuffApplyTransform --
1390 * Apply a transformation rule, given the source and target nodes
1394 * true if successful, false if not.
1397 * The source and target are linked and the commands from the
1398 * transformation are added to the target node's commands list.
1399 * All attributes but OP_DEPMASK and OP_TRANSFORM are applied
1400 * to the target. The target also inherits all the sources for
1401 * the transformation rule.
1403 *-----------------------------------------------------------------------
1406 SuffApplyTransform(GNode
*tGn
, GNode
*sGn
, Suff
*t
, Suff
*s
)
1408 LstNode
*ln
; /* General node */
1409 char *tname
; /* Name of transformation rule */
1410 GNode
*gn
; /* Node for same */
1412 if (Lst_Member(&tGn
->children
, sGn
) == NULL
) {
1414 * Not already linked, so form the proper links between the
1415 * target and source.
1417 Lst_AtEnd(&tGn
->children
, sGn
);
1418 Lst_AtEnd(&sGn
->parents
, tGn
);
1422 if ((sGn
->type
& OP_OPMASK
) == OP_DOUBLEDEP
) {
1424 * When a :: node is used as the implied source of a node,
1425 * we have to link all its cohorts in as sources as well. Only
1426 * the initial sGn gets the target in its iParents list, however
1427 * as that will be sufficient to get the .IMPSRC variable set
1430 for (ln
= Lst_First(&sGn
->cohorts
); ln
!= NULL
;
1431 ln
= Lst_Succ(ln
)) {
1434 if (Lst_Member(&tGn
->children
, gn
) == NULL
) {
1436 * Not already linked, so form the proper
1437 * links between the target and source.
1439 Lst_AtEnd(&tGn
->children
, gn
);
1440 Lst_AtEnd(&gn
->parents
, tGn
);
1446 * Locate the transformation rule itself
1448 tname
= str_concat(s
->name
, '\0', t
->name
);
1449 gn
= SuffTransFind(tname
);
1454 * Not really such a transformation rule (can happen when we're
1455 * called to link an OP_MEMBER and OP_ARCHV node), so return
1461 DEBUGF(SUFF
, ("\tapplying %s -> %s to \"%s\"\n",
1462 s
->name
, t
->name
, tGn
->name
));
1465 * Record last child for expansion purposes
1467 ln
= Lst_Last(&tGn
->children
);
1470 * Pass the buck to Make_HandleUse to apply the rule
1472 Make_HandleUse(gn
, tGn
);
1475 * Deal with wildcards and variables in any acquired sources
1479 SuffExpandChildren(tGn
, ln
);
1483 * Keep track of another parent to which this beast is transformed so
1484 * the .IMPSRC variable can be set correctly for the parent.
1486 Lst_AtEnd(&sGn
->iParents
, tGn
);
1493 *-----------------------------------------------------------------------
1494 * SuffFindArchiveDeps --
1495 * Locate dependencies for an OP_ARCHV node.
1501 * Same as Suff_FindDeps
1503 *-----------------------------------------------------------------------
1506 SuffFindArchiveDeps(GNode
*gn
, Lst
*slst
)
1508 char *eoarch
; /* End of archive portion */
1509 char *eoname
; /* End of member portion */
1510 char *name
; /* Start of member's name */
1511 GNode
*mem
; /* Node for member */
1512 Suff
*ms
; /* Suffix descriptor for member */
1515 * The node is an archive(member) pair. so we must find a
1516 * suffix for both of them.
1518 eoarch
= strchr(gn
->name
, OPEN_PAREN
);
1519 eoname
= strchr(eoarch
, CLOSE_PAREN
);
1521 *eoname
= '\0'; /* Nuke parentheses during suffix search */
1522 *eoarch
= '\0'; /* So a suffix can be found */
1527 * To simplify things, call Suff_FindDeps recursively on the member now,
1528 * so we can simply compare the member's .PREFIX and .TARGET variables
1529 * to locate its suffix. This allows us to figure out the suffix to
1530 * use for the archive without having to do a quadratic search over the
1531 * suffix list, backtracking for each one...
1533 mem
= Targ_FindNode(name
, TARG_CREATE
);
1534 SuffFindDeps(mem
, slst
);
1537 * Create the link between the two nodes right off
1539 if (Lst_Member(&gn
->children
, mem
) == NULL
) {
1540 Lst_AtEnd(&gn
->children
, mem
);
1541 Lst_AtEnd(&mem
->parents
, gn
);
1546 * Copy in the variables from the member node to this one.
1548 Var_Set(PREFIX
, Var_Value(PREFIX
, mem
), gn
);
1549 Var_Set(TARGET
, Var_Value(TARGET
, mem
), gn
);
1554 * Didn't know what it was -- use .NULL suffix if not in
1557 DEBUGF(SUFF
, ("using null suffix\n"));
1562 * Set the other two local variables required for this target.
1564 Var_Set(MEMBER
, name
, gn
);
1565 Var_Set(ARCHIVE
, gn
->name
, gn
);
1569 * Member has a known suffix, so look for a transformation rule
1570 * from it to a possible suffix of the archive. Rather than
1571 * searching through the entire list, we just look at suffixes
1572 * to which the member's suffix may be transformed...
1577 * Use first matching suffix...
1579 LST_FOREACH(ln
, &ms
->parents
) {
1580 if (SuffSuffIsSuffix(Lst_Datum(ln
), gn
->name
) != NULL
)
1586 * Got one -- apply it
1588 if (!SuffApplyTransform(gn
, mem
, Lst_Datum(ln
), ms
)) {
1589 DEBUGF(SUFF
, ("\tNo transformation from "
1590 "%s -> %s\n", ms
->name
,
1591 ((Suff
*)Lst_Datum(ln
))->name
));
1597 * Replace the opening and closing parens now we've no need
1598 * of the separate pieces.
1600 *eoarch
= OPEN_PAREN
;
1601 *eoname
= CLOSE_PAREN
;
1604 * Pretend gn appeared to the left of a dependency operator so
1605 * the user needn't provide a transformation from the member to the
1608 if (OP_NOP(gn
->type
)) {
1609 gn
->type
|= OP_DEPENDS
;
1613 * Flag the member as such so we remember to look in the archive for
1614 * its modification time.
1616 mem
->type
|= OP_MEMBER
;
1620 *-----------------------------------------------------------------------
1621 * SuffFindNormalDeps --
1622 * Locate implicit dependencies for regular targets.
1628 * Same as Suff_FindDeps...
1630 *-----------------------------------------------------------------------
1633 SuffFindNormalDeps(GNode
*gn
, Lst
*slst
)
1635 char *eoname
; /* End of name */
1636 char *sopref
; /* Start of prefix */
1637 LstNode
*ln
; /* Next suffix node to check */
1638 Lst srcs
; /* List of sources at which to look */
1639 Lst targs
; /* List of targets to which things can be
1640 * transformed. They all have the same file,
1641 * but different suff and pref fields */
1642 Src
*bottom
; /* Start of found transformation path */
1643 Src
*src
; /* General Src pointer */
1644 char *pref
; /* Prefix to use */
1645 Src
*targ
; /* General Src target pointer */
1647 eoname
= gn
->name
+ strlen(gn
->name
);
1651 * Begin at the beginning...
1653 ln
= Lst_First(&sufflist
);
1658 * We're caught in a catch-22 here. On the one hand, we want to use any
1659 * transformation implied by the target's sources, but we can't examine
1660 * the sources until we've expanded any variables/wildcards they may
1661 * hold, and we can't do that until we've set up the target's local
1662 * variables and we can't do that until we know what the proper suffix
1663 * for the target is (in case there are two suffixes one of which is a
1664 * suffix of the other) and we can't know that until we've found its
1665 * implied source, which we may not want to use if there's an existing
1666 * source that implies a different transformation.
1668 * In an attempt to get around this, which may not work all the time,
1669 * but should work most of the time, we look for implied sources first,
1670 * checking transformations to all possible suffixes of the target,
1671 * use what we find to set the target's local variables, expand the
1672 * children, then look for any overriding transformations they imply.
1673 * Should we find one, we discard the one we found before.
1676 while (ln
!= NULL
) {
1678 * Look for next possible suffix...
1680 while (ln
!= NULL
) {
1681 if (SuffSuffIsSuffix(Lst_Datum(ln
), gn
->name
) != NULL
)
1687 int prefLen
; /* Length of the prefix */
1691 * Allocate a Src structure to which things can be
1694 target
= SuffSrcCreate(estrdup(gn
->name
), NULL
,
1695 Lst_Datum(ln
), NULL
, gn
);
1696 target
->suff
->refCount
++;
1699 * Allocate room for the prefix, whose end is found
1700 * by subtracting the length of the suffix from
1701 * the end of the name.
1703 prefLen
= (eoname
- target
->suff
->nameLen
) - sopref
;
1704 assert(prefLen
>= 0);
1705 target
->pref
= emalloc(prefLen
+ 1);
1706 memcpy(target
->pref
, sopref
, prefLen
);
1707 target
->pref
[prefLen
] = '\0';
1710 * Add nodes from which the target can be made
1712 SuffAddLevel(&srcs
, target
);
1715 * Record the target so we can nuke it
1717 Lst_AtEnd(&targs
, target
);
1720 * Search from this suffix's successor...
1727 * Handle target of unknown suffix...
1729 if (Lst_IsEmpty(&targs
) && suffNull
!= NULL
) {
1730 DEBUGF(SUFF
, ("\tNo known suffix on %s. Using .NULL suffix\n",
1733 targ
= SuffSrcCreate(estrdup(gn
->name
), estrdup(sopref
),
1734 suffNull
, NULL
, gn
);
1735 targ
->suff
->refCount
++;
1738 * Only use the default suffix rules if we don't have commands
1739 * or dependencies defined for this gnode
1741 if (Lst_IsEmpty(&gn
->commands
) && Lst_IsEmpty(&gn
->children
))
1742 SuffAddLevel(&srcs
, targ
);
1744 DEBUGF(SUFF
, ("not "));
1747 DEBUGF(SUFF
, ("adding suffix rules\n"));
1749 Lst_AtEnd(&targs
, targ
);
1753 * Using the list of possible sources built up from the target
1754 * suffix(es), try and find an existing file/target that matches.
1756 bottom
= SuffFindThem(&srcs
, slst
);
1758 if (bottom
== NULL
) {
1760 * No known transformations -- use the first suffix found for
1761 * setting the local variables.
1763 if (!Lst_IsEmpty(&targs
)) {
1764 targ
= Lst_Datum(Lst_First(&targs
));
1770 * Work up the transformation path to find the suffix of the
1771 * target to which the transformation was made.
1773 for (targ
= bottom
; targ
->parent
!= NULL
; targ
= targ
->parent
)
1778 * The .TARGET variable we always set to be the name at this point,
1779 * since it's only set to the path if the thing is only a source and
1780 * if it's only a source, it doesn't matter what we put here as far
1781 * as expanding sources is concerned, since it has none...
1783 Var_Set(TARGET
, gn
->name
, gn
);
1785 pref
= (targ
!= NULL
) ? targ
->pref
: gn
->name
;
1786 Var_Set(PREFIX
, pref
, gn
);
1789 * Now we've got the important local variables set, expand any sources
1790 * that still contain variables or wildcards in their names.
1792 SuffExpandChildren(gn
, NULL
);
1795 DEBUGF(SUFF
, ("\tNo valid suffix on %s\n", gn
->name
));
1799 * Deal with finding the thing on the default search path if the
1800 * node is only a source (not on the lhs of a dependency
1801 * operator or [XXX] it has neither children or commands).
1803 if (OP_NOP(gn
->type
) || (Lst_IsEmpty(&gn
->children
) &&
1804 Lst_IsEmpty(&gn
->commands
))) {
1805 gn
->path
= Path_FindFile(gn
->name
,
1806 (targ
== NULL
? &dirSearchPath
:
1807 &targ
->suff
->searchPath
));
1808 if (gn
->path
!= NULL
) {
1810 Var_Set(TARGET
, gn
->path
, gn
);
1814 * Suffix known for the thing -- trim
1815 * the suffix off the path to form the
1816 * proper .PREFIX variable.
1818 int savep
= strlen(gn
->path
) -
1819 targ
->suff
->nameLen
;
1823 gn
->suffix
->refCount
--;
1824 gn
->suffix
= targ
->suff
;
1825 gn
->suffix
->refCount
++;
1827 savec
= gn
->path
[savep
];
1828 gn
->path
[savep
] = '\0';
1830 if ((ptr
= strrchr(gn
->path
, '/')) != NULL
)
1835 Var_Set(PREFIX
, ptr
, gn
);
1837 gn
->path
[savep
] = savec
;
1840 * The .PREFIX gets the full path if
1841 * the target has no known suffix.
1844 gn
->suffix
->refCount
--;
1847 if ((ptr
= strrchr(gn
->path
, '/')) != NULL
)
1852 Var_Set(PREFIX
, ptr
, gn
);
1857 * Not appropriate to search for the thing -- set the
1858 * path to be the name so Dir_MTime won't go
1859 * grovelling for it.
1862 gn
->suffix
->refCount
--;
1863 gn
->suffix
= (targ
== NULL
) ? NULL
: targ
->suff
;
1865 gn
->suffix
->refCount
++;
1867 gn
->path
= estrdup(gn
->name
);
1874 * If the suffix indicates that the target is a library, mark that in
1875 * the node's type field.
1877 if (targ
->suff
->flags
& SUFF_LIBRARY
) {
1882 * Check for overriding transformation rule implied by sources
1884 if (!Lst_IsEmpty(&gn
->children
)) {
1885 src
= SuffFindCmds(targ
, slst
);
1889 * Free up all the Src structures in the
1890 * transformation path up to, but not including,
1893 while (bottom
&& bottom
->parent
!= NULL
) {
1894 if (Lst_Member(slst
, bottom
) == NULL
) {
1895 Lst_AtEnd(slst
, bottom
);
1897 bottom
= bottom
->parent
;
1903 if (bottom
== NULL
) {
1905 * No idea from where it can come -- return now.
1911 * We now have a list of Src structures headed by 'bottom' and linked
1912 * via their 'parent' pointers. What we do next is create links between
1913 * source and target nodes (which may or may not have been created)
1914 * and set the necessary local variables in each target. The
1915 * commands for each target are set from the commands of the
1916 * transformation rule used to get from the src suffix to the targ
1917 * suffix. Note that this causes the commands list of the original
1918 * node, gn, to be replaced by the commands of the final
1919 * transformation rule. Also, the unmade field of gn is incremented.
1922 if (bottom
->node
== NULL
) {
1923 bottom
->node
= Targ_FindNode(bottom
->file
, TARG_CREATE
);
1926 for (src
= bottom
; src
->parent
!= NULL
; src
= src
->parent
) {
1929 if (src
->node
->suffix
)
1930 src
->node
->suffix
->refCount
--;
1931 src
->node
->suffix
= src
->suff
;
1932 src
->node
->suffix
->refCount
++;
1934 if (targ
->node
== NULL
) {
1935 targ
->node
= Targ_FindNode(targ
->file
, TARG_CREATE
);
1938 SuffApplyTransform(targ
->node
, src
->node
,
1939 targ
->suff
, src
->suff
);
1941 if (targ
->node
!= gn
) {
1943 * Finish off the dependency-search process for any
1944 * nodes between bottom and gn (no point in questing
1945 * around the filesystem for their implicit source
1946 * when it's already known). Note that the node can't
1947 * have any sources that need expanding, since
1948 * SuffFindThem will stop on an existing
1949 * node, so all we need to do is set the standard and
1950 * System V variables.
1952 targ
->node
->type
|= OP_DEPS_FOUND
;
1954 Var_Set(PREFIX
, targ
->pref
, targ
->node
);
1955 Var_Set(TARGET
, targ
->node
->name
, targ
->node
);
1960 gn
->suffix
->refCount
--;
1961 gn
->suffix
= src
->suff
;
1962 gn
->suffix
->refCount
++;
1965 * So Dir_MTime doesn't go questing for it...
1968 gn
->path
= estrdup(gn
->name
);
1971 * Nuke the transformation path and the Src structures left over in the
1976 if (Lst_Member(slst
, bottom
) == NULL
)
1977 Lst_AtEnd(slst
, bottom
);
1979 while (SuffRemoveSrc(&srcs
) || SuffRemoveSrc(&targs
))
1982 Lst_Concat(slst
, &srcs
, LST_CONCLINK
);
1983 Lst_Concat(slst
, &targs
, LST_CONCLINK
);
1987 *-----------------------------------------------------------------------
1989 * Find implicit sources for the target described by the graph node
1996 * Nodes are added to the graph below the passed-in node. The nodes
1997 * are marked to have their IMPSRC variable filled in. The
1998 * PREFIX variable is set for the given node and all its
2002 * The path found by this target is the shortest path in the
2003 * transformation graph, which may pass through non-existent targets,
2004 * to an existing target. The search continues on all paths from the
2005 * root suffix until a file is found. I.e. if there's a path
2006 * .o -> .c -> .l -> .l,v from the root and the .l,v file exists but
2007 * the .c and .l files don't, the search will branch out in
2008 * all directions from .o and again from all the nodes on the
2009 * next level until the .l,v node is encountered.
2011 *-----------------------------------------------------------------------
2014 Suff_FindDeps(GNode
*gn
)
2017 SuffFindDeps(gn
, &srclist
);
2018 while (SuffRemoveSrc(&srclist
))
2024 SuffFindDeps(GNode
*gn
, Lst
*slst
)
2027 if (gn
->type
& OP_DEPS_FOUND
) {
2029 * If dependencies already found, no need to do it again...
2033 gn
->type
|= OP_DEPS_FOUND
;
2036 DEBUGF(SUFF
, ("SuffFindDeps (%s)\n", gn
->name
));
2038 if (gn
->type
& OP_ARCHV
) {
2039 SuffFindArchiveDeps(gn
, slst
);
2041 } else if (gn
->type
& OP_LIB
) {
2043 * If the node is a library, it is the arch module's job to find
2044 * it and set the TARGET variable accordingly. We merely provide
2045 * the search path, assuming all libraries end in ".a" (if the
2046 * suffix hasn't been defined, there's nothing we can do for it,
2047 * so we just set the TARGET variable to the node's name in order
2048 * to give it a value).
2052 s
= SuffSuffFind(LIBSUFF
);
2054 gn
->suffix
->refCount
--;
2057 gn
->suffix
->refCount
++;
2058 Arch_FindLib(gn
, &s
->searchPath
);
2061 Var_Set(TARGET
, gn
->name
, gn
);
2065 * Because a library (-lfoo) target doesn't follow the standard
2066 * filesystem conventions, we don't set the regular variables for
2067 * the thing. .PREFIX is simply made empty...
2069 Var_Set(PREFIX
, "", gn
);
2072 SuffFindNormalDeps(gn
, slst
);
2077 *-----------------------------------------------------------------------
2079 * Define which suffix is the null suffix.
2085 * 'suffNull' is altered.
2088 * Need to handle the changing of the null suffix gracefully so the
2089 * old transformation rules don't just go away.
2091 *-----------------------------------------------------------------------
2094 Suff_SetNull(char *name
)
2098 if ((s
= SuffSuffFind(name
)) == NULL
) {
2099 Parse_Error(PARSE_WARNING
, "Desired null suffix %s "
2100 "not defined.", name
);
2104 if (suffNull
!= NULL
) {
2105 suffNull
->flags
&= ~SUFF_NULL
;
2107 s
->flags
|= SUFF_NULL
;
2110 * XXX: Here's where the transformation mangling
2117 *-----------------------------------------------------------------------
2119 * Initialize suffixes module
2126 *-----------------------------------------------------------------------
2134 * Create null suffix for single-suffix rules (POSIX). The thing doesn't
2135 * actually go on the suffix list or everyone will think that's its
2138 emptySuff
= suffNull
= emalloc(sizeof(Suff
));
2140 suffNull
->name
= estrdup("");
2141 suffNull
->nameLen
= 0;
2142 TAILQ_INIT(&suffNull
->searchPath
);
2143 Path_Concat(&suffNull
->searchPath
, &dirSearchPath
);
2144 Lst_Init(&suffNull
->children
);
2145 Lst_Init(&suffNull
->parents
);
2146 Lst_Init(&suffNull
->ref
);
2147 suffNull
->sNum
= sNum
++;
2148 suffNull
->flags
= SUFF_NULL
;
2149 suffNull
->refCount
= 1;
2152 /********************* DEBUGGING FUNCTIONS **********************/
2162 static const struct flag2str suff_flags
[] = {
2163 { SUFF_INCLUDE
, "INCLUDE" },
2164 { SUFF_LIBRARY
, "LIBRARY" },
2165 { SUFF_NULL
, "NULL" },
2169 printf("#*** Suffixes:\n");
2170 LST_FOREACH(ln
, &sufflist
) {
2172 printf("# `%s' [%d] ", s
->name
, s
->refCount
);
2174 if (s
->flags
!= 0) {
2176 print_flags(stdout
, suff_flags
, s
->flags
, 1);
2179 printf("\n#\tTo: ");
2180 LST_FOREACH(tln
, &s
->parents
)
2181 printf("`%s' ", ((const Suff
*)Lst_Datum(tln
))->name
);
2183 printf("\n#\tFrom: ");
2184 LST_FOREACH(tln
, &s
->children
)
2185 printf("`%s' ", ((const Suff
*)Lst_Datum(tln
))->name
);
2187 printf("\n#\tSearch Path: ");
2188 Path_Print(&s
->searchPath
);
2193 printf("#*** Transformations:\n");
2194 LST_FOREACH(ln
, &transforms
) {
2196 printf("%-16s: ", gn
->name
);
2197 Targ_PrintType(gn
->type
);
2199 LST_FOREACH(tln
, &gn
->commands
)
2200 printf("\t%s\n", (const char *)Lst_Datum(tln
));