1 /* $NetBSD: suff.c,v 1.345 2021/02/05 05:15:12 rillig Exp $ */ 2 3 /* 4 * Copyright (c) 1988, 1989, 1990, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Adam de Boor. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 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. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35 /* 36 * Copyright (c) 1989 by Berkeley Softworks 37 * All rights reserved. 38 * 39 * This code is derived from software contributed to Berkeley by 40 * Adam de Boor. 41 * 42 * Redistribution and use in source and binary forms, with or without 43 * modification, are permitted provided that the following conditions 44 * are met: 45 * 1. Redistributions of source code must retain the above copyright 46 * notice, this list of conditions and the following disclaimer. 47 * 2. Redistributions in binary form must reproduce the above copyright 48 * notice, this list of conditions and the following disclaimer in the 49 * documentation and/or other materials provided with the distribution. 50 * 3. All advertising materials mentioning features or use of this software 51 * must display the following acknowledgement: 52 * This product includes software developed by the University of 53 * California, Berkeley and its contributors. 54 * 4. Neither the name of the University nor the names of its contributors 55 * may be used to endorse or promote products derived from this software 56 * without specific prior written permission. 57 * 58 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 61 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 68 * SUCH DAMAGE. 69 */ 70 71 /* 72 * Maintain suffix lists and find implicit dependents using suffix 73 * transformation rules such as ".c.o". 74 * 75 * Interface: 76 * Suff_Init Initialize the module. 77 * 78 * Suff_End Clean up the module. 79 * 80 * Suff_DoPaths Extend the search path of each suffix to include the 81 * default search path. 82 * 83 * Suff_ClearSuffixes 84 * Clear out all the suffixes and transformations. 85 * 86 * Suff_IsTransform 87 * See if the passed string is a transformation rule. 88 * 89 * Suff_AddSuffix Add the passed string as another known suffix. 90 * 91 * Suff_GetPath Return the search path for the given suffix. 92 * 93 * Suff_AddInclude 94 * Mark the given suffix as denoting an include file. 95 * 96 * Suff_AddLib Mark the given suffix as denoting a library. 97 * 98 * Suff_AddTransform 99 * Add another transformation to the suffix graph. 100 * 101 * Suff_SetNull Define the suffix to consider the suffix of 102 * any file that doesn't have a known one. 103 * 104 * Suff_FindDeps Find implicit sources for and the location of 105 * a target based on its suffix. Returns the 106 * bottom-most node added to the graph or NULL 107 * if the target had no implicit sources. 108 * 109 * Suff_FindPath Return the appropriate path to search in order to 110 * find the node. 111 */ 112 113 #include "make.h" 114 #include "dir.h" 115 116 /* "@(#)suff.c 8.4 (Berkeley) 3/21/94" */ 117 MAKE_RCSID("$NetBSD: suff.c,v 1.345 2021/02/05 05:15:12 rillig Exp $"); 118 119 typedef List SuffixList; 120 typedef ListNode SuffixListNode; 121 122 typedef List CandidateList; 123 typedef ListNode CandidateListNode; 124 125 /* The defined suffixes, such as '.c', '.o', '.l'. */ 126 static SuffixList sufflist = LST_INIT; 127 #ifdef CLEANUP 128 /* The suffixes to be cleaned up at the end. */ 129 static SuffixList suffClean = LST_INIT; 130 #endif 131 132 /* 133 * The transformation rules, such as '.c.o' to transform '.c' into '.o', 134 * or simply '.c' to transform 'file.c' into 'file'. 135 */ 136 static GNodeList transforms = LST_INIT; 137 138 /* 139 * Counter for assigning suffix numbers. 140 * TODO: What are these suffix numbers used for? 141 */ 142 static int sNum = 0; 143 144 typedef enum SuffixFlags { 145 SUFF_NONE = 0, 146 147 /* 148 * This suffix marks include files. Their search path ends up in the 149 * undocumented special variable '.INCLUDES'. 150 */ 151 SUFF_INCLUDE = 1 << 0, 152 153 /* 154 * This suffix marks library files. Their search path ends up in the 155 * undocumented special variable '.LIBS'. 156 */ 157 SUFF_LIBRARY = 1 << 1, 158 159 /* 160 * The empty suffix. 161 * 162 * XXX: What is the difference between the empty suffix and the null 163 * suffix? 164 * 165 * XXX: Why is SUFF_NULL needed at all? Wouldn't nameLen == 0 mean 166 * the same? 167 */ 168 SUFF_NULL = 1 << 2 169 170 } SuffixFlags; 171 172 ENUM_FLAGS_RTTI_3(SuffixFlags, 173 SUFF_INCLUDE, SUFF_LIBRARY, SUFF_NULL); 174 175 typedef List SuffixListList; 176 177 /* 178 * A suffix such as ".c" or ".o" that is used in suffix transformation rules 179 * such as ".c.o:". 180 */ 181 typedef struct Suffix { 182 /* The suffix itself, such as ".c" */ 183 char *name; 184 /* Length of the name, to avoid strlen calls */ 185 size_t nameLen; 186 /* Type of suffix */ 187 SuffixFlags flags; 188 /* The path along which files of this suffix may be found */ 189 SearchPath *searchPath; 190 /* The suffix number; TODO: document the purpose of this number */ 191 int sNum; 192 /* Reference count of list membership and several other places */ 193 int refCount; 194 /* Suffixes we have a transformation to */ 195 SuffixList parents; 196 /* Suffixes we have a transformation from */ 197 SuffixList children; 198 199 /* Lists in which this suffix is referenced. 200 * 201 * XXX: These lists are used nowhere, they are just appended to, for 202 * no apparent reason. They do have the side effect of increasing 203 * refCount though. */ 204 SuffixListList ref; 205 } Suffix; 206 207 /* 208 * A candidate when searching for implied sources. 209 * 210 * For example, when "src.o" is to be made, a typical candidate is "src.c" 211 * via the transformation rule ".c.o". If that doesn't exist, maybe there is 212 * another transformation rule ".pas.c" that would make "src.pas" an indirect 213 * candidate as well. The first such chain that leads to an existing file or 214 * node is finally chosen to be made. 215 */ 216 typedef struct Candidate { 217 /* The file or node to look for. */ 218 char *file; 219 /* The prefix from which file was formed. 220 * Its memory is shared among all candidates. */ 221 char *prefix; 222 /* The suffix on the file. */ 223 Suffix *suff; 224 225 /* The candidate that can be made from this, 226 * or NULL for the top-level candidate. */ 227 struct Candidate *parent; 228 /* The node describing the file. */ 229 GNode *node; 230 231 /* Count of existing children, only used for memory management, so we 232 * don't free this candidate too early or too late. */ 233 int numChildren; 234 #ifdef DEBUG_SRC 235 CandidateList childrenList; 236 #endif 237 } Candidate; 238 239 typedef struct CandidateSearcher { 240 241 CandidateList list; 242 243 /* 244 * TODO: Add HashSet for seen entries, to avoid endless loops such as 245 * in suff-transform-endless.mk. 246 */ 247 248 } CandidateSearcher; 249 250 251 /* TODO: Document the difference between nullSuff and emptySuff. */ 252 /* The NULL suffix for this run */ 253 static Suffix *nullSuff; 254 /* The empty suffix required for POSIX single-suffix transformation rules */ 255 static Suffix *emptySuff; 256 257 258 static Suffix * 259 Suffix_Ref(Suffix *suff) 260 { 261 suff->refCount++; 262 return suff; 263 } 264 265 /* Change the value of a Suffix variable, adjusting the reference counts. */ 266 static void 267 Suffix_Reassign(Suffix **var, Suffix *suff) 268 { 269 if (*var != NULL) 270 (*var)->refCount--; 271 *var = suff; 272 suff->refCount++; 273 } 274 275 /* Set a Suffix variable to NULL, adjusting the reference count. */ 276 static void 277 Suffix_Unassign(Suffix **var) 278 { 279 if (*var != NULL) 280 (*var)->refCount--; 281 *var = NULL; 282 } 283 284 /* 285 * See if pref is a prefix of str. 286 * Return NULL if it ain't, pointer to character in str after prefix if so. 287 */ 288 static const char * 289 StrTrimPrefix(const char *pref, const char *str) 290 { 291 while (*str != '\0' && *pref == *str) { 292 pref++; 293 str++; 294 } 295 296 return *pref != '\0' ? NULL : str; 297 } 298 299 /* 300 * See if suff is a suffix of str, and if so, return the pointer to the suffix 301 * in str, which at the same time marks the end of the prefix. 302 */ 303 static const char * 304 StrTrimSuffix(const char *str, size_t strLen, const char *suff, size_t suffLen) 305 { 306 const char *suffInStr; 307 size_t i; 308 309 if (strLen < suffLen) 310 return NULL; 311 312 suffInStr = str + strLen - suffLen; 313 for (i = 0; i < suffLen; i++) 314 if (suff[i] != suffInStr[i]) 315 return NULL; 316 317 return suffInStr; 318 } 319 320 /* 321 * See if suff is a suffix of name, and if so, return the end of the prefix 322 * in name. 323 */ 324 static const char * 325 Suffix_TrimSuffix(const Suffix *suff, size_t nameLen, const char *nameEnd) 326 { 327 return StrTrimSuffix(nameEnd - nameLen, nameLen, 328 suff->name, suff->nameLen); 329 } 330 331 static Boolean 332 Suffix_IsSuffix(const Suffix *suff, size_t nameLen, const char *nameEnd) 333 { 334 return Suffix_TrimSuffix(suff, nameLen, nameEnd) != NULL; 335 } 336 337 static Suffix * 338 FindSuffixByNameLen(const char *name, size_t nameLen) 339 { 340 SuffixListNode *ln; 341 342 for (ln = sufflist.first; ln != NULL; ln = ln->next) { 343 Suffix *suff = ln->datum; 344 if (suff->nameLen == nameLen && 345 memcmp(suff->name, name, nameLen) == 0) 346 return suff; 347 } 348 return NULL; 349 } 350 351 static Suffix * 352 FindSuffixByName(const char *name) 353 { 354 return FindSuffixByNameLen(name, strlen(name)); 355 } 356 357 static GNode * 358 FindTransformByName(const char *name) 359 { 360 GNodeListNode *ln; 361 362 for (ln = transforms.first; ln != NULL; ln = ln->next) { 363 GNode *gn = ln->datum; 364 if (strcmp(gn->name, name) == 0) 365 return gn; 366 } 367 return NULL; 368 } 369 370 static void 371 SuffixList_Unref(SuffixList *list, Suffix *suff) 372 { 373 SuffixListNode *ln = Lst_FindDatum(list, suff); 374 if (ln != NULL) { 375 Lst_Remove(list, ln); 376 suff->refCount--; 377 } 378 } 379 380 /* Free up all memory associated with the given suffix structure. */ 381 static void 382 Suffix_Free(Suffix *suff) 383 { 384 385 if (suff == nullSuff) 386 nullSuff = NULL; 387 388 if (suff == emptySuff) 389 emptySuff = NULL; 390 391 #if 0 392 /* We don't delete suffixes in order, so we cannot use this */ 393 if (suff->refCount != 0) 394 Punt("Internal error deleting suffix `%s' with refcount = %d", 395 suff->name, suff->refCount); 396 #endif 397 398 Lst_Done(&suff->ref); 399 Lst_Done(&suff->children); 400 Lst_Done(&suff->parents); 401 SearchPath_Free(suff->searchPath); 402 403 free(suff->name); 404 free(suff); 405 } 406 407 static void 408 SuffFree(void *p) 409 { 410 Suffix_Free(p); 411 } 412 413 /* Remove the suffix from the list, and free if it is otherwise unused. */ 414 static void 415 SuffixList_Remove(SuffixList *list, Suffix *suff) 416 { 417 SuffixList_Unref(list, suff); 418 if (suff->refCount == 0) { 419 /* XXX: can lead to suff->refCount == -1 */ 420 SuffixList_Unref(&sufflist, suff); 421 DEBUG1(SUFF, "Removing suffix \"%s\"\n", suff->name); 422 SuffFree(suff); 423 } 424 } 425 426 /* 427 * Insert the suffix into the list, keeping the list ordered by suffix 428 * number. 429 */ 430 static void 431 SuffixList_Insert(SuffixList *list, Suffix *suff) 432 { 433 SuffixListNode *ln; 434 Suffix *listSuff = NULL; 435 436 for (ln = list->first; ln != NULL; ln = ln->next) { 437 listSuff = ln->datum; 438 if (listSuff->sNum >= suff->sNum) 439 break; 440 } 441 442 if (ln == NULL) { 443 DEBUG2(SUFF, "inserting \"%s\" (%d) at end of list\n", 444 suff->name, suff->sNum); 445 Lst_Append(list, Suffix_Ref(suff)); 446 Lst_Append(&suff->ref, list); 447 } else if (listSuff->sNum != suff->sNum) { 448 DEBUG4(SUFF, "inserting \"%s\" (%d) before \"%s\" (%d)\n", 449 suff->name, suff->sNum, listSuff->name, listSuff->sNum); 450 Lst_InsertBefore(list, ln, Suffix_Ref(suff)); 451 Lst_Append(&suff->ref, list); 452 } else { 453 DEBUG2(SUFF, "\"%s\" (%d) is already there\n", 454 suff->name, suff->sNum); 455 } 456 } 457 458 static void 459 Relate(Suffix *srcSuff, Suffix *targSuff) 460 { 461 SuffixList_Insert(&targSuff->children, srcSuff); 462 SuffixList_Insert(&srcSuff->parents, targSuff); 463 } 464 465 static Suffix * 466 Suffix_New(const char *name) 467 { 468 Suffix *suff = bmake_malloc(sizeof *suff); 469 470 suff->name = bmake_strdup(name); 471 suff->nameLen = strlen(suff->name); 472 suff->searchPath = SearchPath_New(); 473 Lst_Init(&suff->children); 474 Lst_Init(&suff->parents); 475 Lst_Init(&suff->ref); 476 suff->sNum = sNum++; 477 suff->flags = SUFF_NONE; 478 suff->refCount = 1; /* XXX: why 1? It's not assigned anywhere yet. */ 479 480 return suff; 481 } 482 483 /* 484 * Nuke the list of suffixes but keep all transformation rules around. The 485 * transformation graph is destroyed in this process, but we leave the list 486 * of rules so when a new graph is formed, the rules will remain. This 487 * function is called when a line '.SUFFIXES:' with an empty suffixes list is 488 * encountered in a makefile. 489 */ 490 void 491 Suff_ClearSuffixes(void) 492 { 493 #ifdef CLEANUP 494 Lst_MoveAll(&suffClean, &sufflist); 495 #endif 496 DEBUG0(SUFF, "Clearing all suffixes\n"); 497 Lst_Init(&sufflist); 498 sNum = 0; 499 if (nullSuff != NULL) 500 SuffFree(nullSuff); 501 emptySuff = nullSuff = Suffix_New(""); 502 503 SearchPath_AddAll(nullSuff->searchPath, &dirSearchPath); 504 nullSuff->flags = SUFF_NULL; 505 } 506 507 /* 508 * Parse a transformation string such as ".c.o" to find its two component 509 * suffixes (the source ".c" and the target ".o"). If there are no such 510 * suffixes, try a single-suffix transformation as well. 511 * 512 * Return TRUE if the string is a valid transformation. 513 */ 514 static Boolean 515 ParseTransform(const char *str, Suffix **out_src, Suffix **out_targ) 516 { 517 SuffixListNode *ln; 518 Suffix *single = NULL; 519 520 /* 521 * Loop looking first for a suffix that matches the start of the 522 * string and then for one that exactly matches the rest of it. If 523 * we can find two that meet these criteria, we've successfully 524 * parsed the string. 525 */ 526 for (ln = sufflist.first; ln != NULL; ln = ln->next) { 527 Suffix *src = ln->datum; 528 529 if (StrTrimPrefix(src->name, str) == NULL) 530 continue; 531 532 if (str[src->nameLen] == '\0') { 533 single = src; 534 } else { 535 Suffix *targ = FindSuffixByName(str + src->nameLen); 536 if (targ != NULL) { 537 *out_src = src; 538 *out_targ = targ; 539 return TRUE; 540 } 541 } 542 } 543 544 if (single != NULL) { 545 /* 546 * There was a suffix that encompassed the entire string, so we 547 * assume it was a transformation to the null suffix (thank you 548 * POSIX; search for "single suffix" or "single-suffix"). 549 * 550 * We still prefer to find a double rule over a singleton, 551 * hence we leave this check until the end. 552 * 553 * XXX: Use emptySuff over nullSuff? 554 */ 555 *out_src = single; 556 *out_targ = nullSuff; 557 return TRUE; 558 } 559 return FALSE; 560 } 561 562 /* 563 * Return TRUE if the given string is a transformation rule, that is, a 564 * concatenation of two known suffixes such as ".c.o" or a single suffix 565 * such as ".o". 566 */ 567 Boolean 568 Suff_IsTransform(const char *str) 569 { 570 Suffix *src, *targ; 571 572 return ParseTransform(str, &src, &targ); 573 } 574 575 /* 576 * Add the transformation rule to the list of rules and place the 577 * transformation itself in the graph. 578 * 579 * The transformation is linked to the two suffixes mentioned in the name. 580 * 581 * Input: 582 * name must have the form ".from.to" or just ".from" 583 * 584 * Results: 585 * The created or existing transformation node in the transforms list 586 */ 587 GNode * 588 Suff_AddTransform(const char *name) 589 { 590 Suffix *srcSuff; 591 Suffix *targSuff; 592 593 GNode *gn = FindTransformByName(name); 594 if (gn == NULL) { 595 /* 596 * Make a new graph node for the transformation. It will be 597 * filled in by the Parse module. 598 */ 599 gn = GNode_New(name); 600 Lst_Append(&transforms, gn); 601 } else { 602 /* 603 * New specification for transformation rule. Just nuke the 604 * old list of commands so they can be filled in again. We 605 * don't actually free the commands themselves, because a 606 * given command can be attached to several different 607 * transformations. 608 */ 609 Lst_Done(&gn->commands); 610 Lst_Init(&gn->commands); 611 Lst_Done(&gn->children); 612 Lst_Init(&gn->children); 613 } 614 615 gn->type = OP_TRANSFORM; 616 617 { 618 /* TODO: Avoid the redundant parsing here. */ 619 Boolean ok = ParseTransform(name, &srcSuff, &targSuff); 620 assert(ok); 621 (void)ok; 622 } 623 624 /* Link the two together in the proper relationship and order. */ 625 DEBUG2(SUFF, "defining transformation from `%s' to `%s'\n", 626 srcSuff->name, targSuff->name); 627 Relate(srcSuff, targSuff); 628 629 return gn; 630 } 631 632 /* 633 * Handle the finish of a transformation definition, removing the 634 * transformation from the graph if it has neither commands nor sources. 635 * 636 * If the node has no commands or children, the children and parents lists 637 * of the affected suffixes are altered. 638 * 639 * Input: 640 * gn Node for transformation 641 */ 642 void 643 Suff_EndTransform(GNode *gn) 644 { 645 Suffix *srcSuff, *targSuff; 646 SuffixList *srcSuffParents; 647 648 if ((gn->type & OP_DOUBLEDEP) && !Lst_IsEmpty(&gn->cohorts)) 649 gn = gn->cohorts.last->datum; 650 651 if (!(gn->type & OP_TRANSFORM)) 652 return; 653 654 if (!Lst_IsEmpty(&gn->commands) || !Lst_IsEmpty(&gn->children)) { 655 DEBUG1(SUFF, "transformation %s complete\n", gn->name); 656 return; 657 } 658 659 /* 660 * SuffParseTransform() may fail for special rules which are not 661 * actual transformation rules. (e.g. .DEFAULT) 662 */ 663 if (!ParseTransform(gn->name, &srcSuff, &targSuff)) 664 return; 665 666 DEBUG2(SUFF, "deleting incomplete transformation from `%s' to `%s'\n", 667 srcSuff->name, targSuff->name); 668 669 /* 670 * Remember the parents since srcSuff could be deleted in 671 * SuffixList_Remove. 672 */ 673 srcSuffParents = &srcSuff->parents; 674 SuffixList_Remove(&targSuff->children, srcSuff); 675 SuffixList_Remove(srcSuffParents, targSuff); 676 } 677 678 /* 679 * Called from Suff_AddSuffix to search through the list of 680 * existing transformation rules and rebuild the transformation graph when 681 * it has been destroyed by Suff_ClearSuffixes. If the given rule is a 682 * transformation involving this suffix and another, existing suffix, the 683 * proper relationship is established between the two. 684 * 685 * The appropriate links will be made between this suffix and others if 686 * transformation rules exist for it. 687 * 688 * Input: 689 * transform Transformation to test 690 * suff Suffix to rebuild 691 */ 692 static void 693 RebuildGraph(GNode *transform, Suffix *suff) 694 { 695 const char *name = transform->name; 696 size_t nameLen = strlen(name); 697 const char *toName; 698 699 /* See if it is a transformation from this suffix to another suffix. */ 700 toName = StrTrimPrefix(suff->name, name); 701 if (toName != NULL) { 702 Suffix *to = FindSuffixByName(toName); 703 if (to != NULL) { 704 Relate(suff, to); 705 return; 706 } 707 } 708 709 /* See if it is a transformation from another suffix to this suffix. */ 710 toName = Suffix_TrimSuffix(suff, nameLen, name + nameLen); 711 if (toName != NULL) { 712 Suffix *from = FindSuffixByNameLen(name, 713 (size_t)(toName - name)); 714 if (from != NULL) 715 Relate(from, suff); 716 } 717 } 718 719 /* 720 * During Suff_AddSuffix, search through the list of existing targets and find 721 * if any of the existing targets can be turned into a transformation rule. 722 * 723 * If such a target is found and the target is the current main target, the 724 * main target is set to NULL and the next target examined (if that exists) 725 * becomes the main target. 726 * 727 * Results: 728 * TRUE iff a new main target has been selected. 729 */ 730 static Boolean 731 UpdateTarget(GNode *target, GNode **inout_main, Suffix *suff, 732 Boolean *inout_removedMain) 733 { 734 Suffix *srcSuff, *targSuff; 735 char *ptr; 736 737 if (*inout_main == NULL && *inout_removedMain && 738 !(target->type & OP_NOTARGET)) { 739 DEBUG1(MAKE, "Setting main node to \"%s\"\n", target->name); 740 *inout_main = target; 741 Targ_SetMain(target); 742 /* 743 * XXX: Why could it be a good idea to return TRUE here? 744 * The main task of this function is to turn ordinary nodes 745 * into transformations, no matter whether or not a new .MAIN 746 * node has been found. 747 */ 748 /* 749 * XXX: Even when changing this to FALSE, none of the existing 750 * unit tests fails. 751 */ 752 return TRUE; 753 } 754 755 if (target->type == OP_TRANSFORM) 756 return FALSE; 757 758 /* 759 * XXX: What about a transformation ".cpp.c"? If ".c" is added as 760 * a new suffix, it seems wrong that this transformation would be 761 * skipped just because ".c" happens to be a prefix of ".cpp". 762 */ 763 ptr = strstr(target->name, suff->name); 764 if (ptr == NULL) 765 return FALSE; 766 767 /* 768 * XXX: In suff-rebuild.mk, in the line '.SUFFIXES: .c .b .a', this 769 * condition prevents the rule '.b.c' from being added again during 770 * Suff_AddSuffix(".b"). 771 * 772 * XXX: Removing this paragraph makes suff-add-later.mk use massive 773 * amounts of memory. 774 */ 775 if (ptr == target->name) 776 return FALSE; 777 778 if (ParseTransform(target->name, &srcSuff, &targSuff)) { 779 if (*inout_main == target) { 780 DEBUG1(MAKE, 781 "Setting main node from \"%s\" back to null\n", 782 target->name); 783 *inout_removedMain = TRUE; 784 *inout_main = NULL; 785 Targ_SetMain(NULL); 786 } 787 Lst_Done(&target->children); 788 Lst_Init(&target->children); 789 target->type = OP_TRANSFORM; 790 791 /* 792 * Link the two together in the proper relationship and order. 793 */ 794 DEBUG2(SUFF, "defining transformation from `%s' to `%s'\n", 795 srcSuff->name, targSuff->name); 796 Relate(srcSuff, targSuff); 797 } 798 return FALSE; 799 } 800 801 /* 802 * Look at all existing targets to see if adding this suffix will make one 803 * of the current targets mutate into a suffix rule. 804 * 805 * This is ugly, but other makes treat all targets that start with a '.' as 806 * suffix rules. 807 */ 808 static void 809 UpdateTargets(GNode **inout_main, Suffix *suff) 810 { 811 Boolean removedMain = FALSE; 812 GNodeListNode *ln; 813 814 for (ln = Targ_List()->first; ln != NULL; ln = ln->next) { 815 GNode *gn = ln->datum; 816 if (UpdateTarget(gn, inout_main, suff, &removedMain)) 817 break; 818 } 819 } 820 821 /* 822 * Add the suffix to the end of the list of known suffixes. 823 * Should we restructure the suffix graph? Make doesn't. 824 * 825 * A GNode is created for the suffix (XXX: this sounds completely wrong) and 826 * a Suffix structure is created and added to the suffixes list unless the 827 * suffix was already known. 828 * The mainNode passed can be modified if a target mutated into a 829 * transform and that target happened to be the main target. 830 * 831 * Input: 832 * name the name of the suffix to add 833 */ 834 void 835 Suff_AddSuffix(const char *name, GNode **inout_main) 836 { 837 GNodeListNode *ln; 838 839 Suffix *suff = FindSuffixByName(name); 840 if (suff != NULL) 841 return; 842 843 suff = Suffix_New(name); 844 Lst_Append(&sufflist, suff); 845 DEBUG1(SUFF, "Adding suffix \"%s\"\n", suff->name); 846 847 UpdateTargets(inout_main, suff); 848 849 /* 850 * Look for any existing transformations from or to this suffix. 851 * XXX: Only do this after a Suff_ClearSuffixes? 852 */ 853 for (ln = transforms.first; ln != NULL; ln = ln->next) 854 RebuildGraph(ln->datum, suff); 855 } 856 857 /* Return the search path for the given suffix, or NULL. */ 858 SearchPath * 859 Suff_GetPath(const char *sname) 860 { 861 Suffix *suff = FindSuffixByName(sname); 862 return suff != NULL ? suff->searchPath : NULL; 863 } 864 865 /* 866 * Extend the search paths for all suffixes to include the default search 867 * path (dirSearchPath). 868 * 869 * The default search path can be defined using the special target '.PATH'. 870 * The search path of each suffix can be defined using the special target 871 * '.PATH<suffix>'. 872 * 873 * If paths were specified for the ".h" suffix, the directories are stuffed 874 * into a global variable called ".INCLUDES" with each directory preceded by 875 * '-I'. The same is done for the ".a" suffix, except the variable is called 876 * ".LIBS" and the flag is '-L'. 877 */ 878 void 879 Suff_DoPaths(void) 880 { 881 SuffixListNode *ln; 882 char *flags; 883 SearchPath *includesPath = SearchPath_New(); 884 SearchPath *libsPath = SearchPath_New(); 885 886 for (ln = sufflist.first; ln != NULL; ln = ln->next) { 887 Suffix *suff = ln->datum; 888 if (!Lst_IsEmpty(&suff->searchPath->dirs)) { 889 #ifdef INCLUDES 890 if (suff->flags & SUFF_INCLUDE) 891 SearchPath_AddAll(includesPath, 892 suff->searchPath); 893 #endif 894 #ifdef LIBRARIES 895 if (suff->flags & SUFF_LIBRARY) 896 SearchPath_AddAll(libsPath, suff->searchPath); 897 #endif 898 SearchPath_AddAll(suff->searchPath, &dirSearchPath); 899 } else { 900 SearchPath_Free(suff->searchPath); 901 suff->searchPath = Dir_CopyDirSearchPath(); 902 } 903 } 904 905 flags = SearchPath_ToFlags(includesPath, "-I"); 906 Global_Set(".INCLUDES", flags); 907 free(flags); 908 909 flags = SearchPath_ToFlags(libsPath, "-L"); 910 Global_Set(".LIBS", flags); 911 free(flags); 912 913 SearchPath_Free(includesPath); 914 SearchPath_Free(libsPath); 915 } 916 917 /* 918 * Add the given suffix as a type of file which gets included. 919 * Called when a '.INCLUDES: .h' line is parsed. 920 * To have an effect, the suffix must already exist. 921 * This affects the magic variable '.INCLUDES'. 922 */ 923 void 924 Suff_AddInclude(const char *suffName) 925 { 926 Suffix *suff = FindSuffixByName(suffName); 927 if (suff != NULL) 928 suff->flags |= SUFF_INCLUDE; 929 } 930 931 /* 932 * Add the given suffix as a type of file which is a library. 933 * Called when a '.LIBS: .a' line is parsed. 934 * To have an effect, the suffix must already exist. 935 * This affects the magic variable '.LIBS'. 936 */ 937 void 938 Suff_AddLib(const char *suffName) 939 { 940 Suffix *suff = FindSuffixByName(suffName); 941 if (suff != NULL) 942 suff->flags |= SUFF_LIBRARY; 943 } 944 945 /********** Implicit Source Search Functions *********/ 946 947 static void 948 CandidateSearcher_Init(CandidateSearcher *cs) 949 { 950 Lst_Init(&cs->list); 951 } 952 953 static void 954 CandidateSearcher_Done(CandidateSearcher *cs) 955 { 956 Lst_Done(&cs->list); 957 } 958 959 static void 960 CandidateSearcher_Add(CandidateSearcher *cs, Candidate *cand) 961 { 962 /* TODO: filter duplicates */ 963 Lst_Append(&cs->list, cand); 964 } 965 966 static void 967 CandidateSearcher_AddIfNew(CandidateSearcher *cs, Candidate *cand) 968 { 969 /* TODO: filter duplicates */ 970 if (Lst_FindDatum(&cs->list, cand) == NULL) 971 Lst_Append(&cs->list, cand); 972 } 973 974 static void 975 CandidateSearcher_MoveAll(CandidateSearcher *cs, CandidateList *list) 976 { 977 /* TODO: filter duplicates */ 978 Lst_MoveAll(&cs->list, list); 979 } 980 981 982 #ifdef DEBUG_SRC 983 static void 984 CandidateList_PrintAddrs(CandidateList *list) 985 { 986 CandidateListNode *ln; 987 988 for (ln = list->first; ln != NULL; ln = ln->next) { 989 Candidate *cand = ln->datum; 990 debug_printf(" %p:%s", cand, cand->file); 991 } 992 debug_printf("\n"); 993 } 994 #endif 995 996 static Candidate * 997 Candidate_New(char *name, char *prefix, Suffix *suff, Candidate *parent, 998 GNode *gn) 999 { 1000 Candidate *cand = bmake_malloc(sizeof *cand); 1001 1002 cand->file = name; 1003 cand->prefix = prefix; 1004 cand->suff = Suffix_Ref(suff); 1005 cand->parent = parent; 1006 cand->node = gn; 1007 cand->numChildren = 0; 1008 #ifdef DEBUG_SRC 1009 Lst_Init(&cand->childrenList); 1010 #endif 1011 1012 return cand; 1013 } 1014 1015 /* Add a new candidate to the list. */ 1016 /*ARGSUSED*/ 1017 static void 1018 CandidateList_Add(CandidateList *list, char *srcName, Candidate *targ, 1019 Suffix *suff, const char *debug_tag) 1020 { 1021 Candidate *cand = Candidate_New(srcName, targ->prefix, suff, targ, 1022 NULL); 1023 targ->numChildren++; 1024 Lst_Append(list, cand); 1025 1026 #ifdef DEBUG_SRC 1027 Lst_Append(&targ->childrenList, cand); 1028 debug_printf("%s add suff %p:%s candidate %p:%s to list %p:", 1029 debug_tag, targ, targ->file, cand, cand->file, list); 1030 CandidateList_PrintAddrs(list); 1031 #endif 1032 } 1033 1034 /* 1035 * Add all candidates to the list that can be formed by applying a suffix to 1036 * the candidate. 1037 */ 1038 static void 1039 CandidateList_AddCandidatesFor(CandidateList *list, Candidate *cand) 1040 { 1041 SuffixListNode *ln; 1042 for (ln = cand->suff->children.first; ln != NULL; ln = ln->next) { 1043 Suffix *suff = ln->datum; 1044 1045 if ((suff->flags & SUFF_NULL) && suff->name[0] != '\0') { 1046 /* 1047 * If the suffix has been marked as the NULL suffix, 1048 * also create a candidate for a file with no suffix 1049 * attached. 1050 */ 1051 CandidateList_Add(list, bmake_strdup(cand->prefix), 1052 cand, suff, "1"); 1053 } 1054 1055 CandidateList_Add(list, str_concat2(cand->prefix, suff->name), 1056 cand, suff, "2"); 1057 } 1058 } 1059 1060 /* 1061 * Free the first candidate in the list that is not referenced anymore. 1062 * Return whether a candidate was removed. 1063 */ 1064 static Boolean 1065 RemoveCandidate(CandidateList *srcs) 1066 { 1067 CandidateListNode *ln; 1068 1069 #ifdef DEBUG_SRC 1070 debug_printf("cleaning list %p:", srcs); 1071 CandidateList_PrintAddrs(srcs); 1072 #endif 1073 1074 for (ln = srcs->first; ln != NULL; ln = ln->next) { 1075 Candidate *src = ln->datum; 1076 1077 if (src->numChildren == 0) { 1078 if (src->parent == NULL) 1079 free(src->prefix); 1080 else { 1081 #ifdef DEBUG_SRC 1082 /* XXX: Lst_RemoveDatum */ 1083 CandidateListNode *ln2; 1084 ln2 = Lst_FindDatum(&src->parent->childrenList, 1085 src); 1086 if (ln2 != NULL) 1087 Lst_Remove(&src->parent->childrenList, 1088 ln2); 1089 #endif 1090 src->parent->numChildren--; 1091 } 1092 #ifdef DEBUG_SRC 1093 debug_printf("free: list %p src %p:%s children %d\n", 1094 srcs, src, src->file, src->numChildren); 1095 Lst_Done(&src->childrenList); 1096 #endif 1097 Lst_Remove(srcs, ln); 1098 free(src->file); 1099 free(src); 1100 return TRUE; 1101 } 1102 #ifdef DEBUG_SRC 1103 else { 1104 debug_printf("keep: list %p src %p:%s children %d:", 1105 srcs, src, src->file, src->numChildren); 1106 CandidateList_PrintAddrs(&src->childrenList); 1107 } 1108 #endif 1109 } 1110 1111 return FALSE; 1112 } 1113 1114 /* Find the first existing file/target in srcs. */ 1115 static Candidate * 1116 FindThem(CandidateList *srcs, CandidateSearcher *cs) 1117 { 1118 HashSet seen; 1119 1120 HashSet_Init(&seen); 1121 1122 while (!Lst_IsEmpty(srcs)) { 1123 Candidate *src = Lst_Dequeue(srcs); 1124 1125 #ifdef DEBUG_SRC 1126 debug_printf("remove from list %p src %p:%s\n", 1127 srcs, src, src->file); 1128 #endif 1129 DEBUG1(SUFF, "\ttrying %s...", src->file); 1130 1131 /* 1132 * A file is considered to exist if either a node exists in the 1133 * graph for it or the file actually exists. 1134 */ 1135 if (Targ_FindNode(src->file) != NULL) { 1136 found: 1137 HashSet_Done(&seen); 1138 DEBUG0(SUFF, "got it\n"); 1139 return src; 1140 } 1141 1142 { 1143 char *file = Dir_FindFile(src->file, 1144 src->suff->searchPath); 1145 if (file != NULL) { 1146 free(file); 1147 goto found; 1148 } 1149 } 1150 1151 DEBUG0(SUFF, "not there\n"); 1152 1153 if (HashSet_Add(&seen, src->file)) 1154 CandidateList_AddCandidatesFor(srcs, src); 1155 else { 1156 DEBUG1(SUFF, "FindThem: skipping duplicate \"%s\"\n", 1157 src->file); 1158 } 1159 1160 CandidateSearcher_Add(cs, src); 1161 } 1162 1163 HashSet_Done(&seen); 1164 return NULL; 1165 } 1166 1167 /* 1168 * See if any of the children of the candidate's GNode is one from which the 1169 * target can be transformed. If there is one, a candidate is put together 1170 * for it and returned. 1171 */ 1172 static Candidate * 1173 FindCmds(Candidate *targ, CandidateSearcher *cs) 1174 { 1175 GNodeListNode *gln; 1176 GNode *tgn; /* Target GNode */ 1177 GNode *sgn; /* Source GNode */ 1178 size_t prefLen; /* The length of the defined prefix */ 1179 Suffix *suff; /* Suffix of the matching candidate */ 1180 Candidate *ret; /* Return value */ 1181 1182 tgn = targ->node; 1183 prefLen = strlen(targ->prefix); 1184 1185 for (gln = tgn->children.first; gln != NULL; gln = gln->next) { 1186 const char *base; 1187 1188 sgn = gln->datum; 1189 1190 if (sgn->type & OP_OPTIONAL && Lst_IsEmpty(&tgn->commands)) { 1191 /* 1192 * We haven't looked to see if .OPTIONAL files exist 1193 * yet, so don't use one as the implicit source. 1194 * This allows us to use .OPTIONAL in .depend files so 1195 * make won't complain "don't know how to make xxx.h" 1196 * when a dependent file has been moved/deleted. 1197 */ 1198 continue; 1199 } 1200 1201 base = str_basename(sgn->name); 1202 if (strncmp(base, targ->prefix, prefLen) != 0) 1203 continue; 1204 /* The node matches the prefix, see if it has a known suffix. */ 1205 suff = FindSuffixByName(base + prefLen); 1206 if (suff == NULL) 1207 continue; 1208 1209 /* 1210 * It even has a known suffix, see if there's a transformation 1211 * defined between the node's suffix and the target's suffix. 1212 * 1213 * XXX: Handle multi-stage transformations here, too. 1214 */ 1215 1216 if (Lst_FindDatum(&suff->parents, targ->suff) != NULL) 1217 break; 1218 } 1219 1220 if (gln == NULL) 1221 return NULL; 1222 1223 ret = Candidate_New(bmake_strdup(sgn->name), targ->prefix, suff, targ, 1224 sgn); 1225 targ->numChildren++; 1226 #ifdef DEBUG_SRC 1227 debug_printf("3 add targ %p:%s ret %p:%s\n", 1228 targ, targ->file, ret, ret->file); 1229 Lst_Append(&targ->childrenList, ret); 1230 #endif 1231 CandidateSearcher_Add(cs, ret); 1232 DEBUG1(SUFF, "\tusing existing source %s\n", sgn->name); 1233 return ret; 1234 } 1235 1236 static void 1237 ExpandWildcards(GNodeListNode *cln, GNode *pgn) 1238 { 1239 GNode *cgn = cln->datum; 1240 StringList expansions; 1241 1242 if (!Dir_HasWildcards(cgn->name)) 1243 return; 1244 1245 /* 1246 * Expand the word along the chosen path 1247 */ 1248 Lst_Init(&expansions); 1249 SearchPath_Expand(Suff_FindPath(cgn), cgn->name, &expansions); 1250 1251 while (!Lst_IsEmpty(&expansions)) { 1252 GNode *gn; 1253 /* 1254 * Fetch next expansion off the list and find its GNode 1255 */ 1256 char *cp = Lst_Dequeue(&expansions); 1257 1258 DEBUG1(SUFF, "%s...", cp); 1259 gn = Targ_GetNode(cp); 1260 1261 /* Add gn to the parents child list before the original child */ 1262 Lst_InsertBefore(&pgn->children, cln, gn); 1263 Lst_Append(&gn->parents, pgn); 1264 pgn->unmade++; 1265 } 1266 1267 Lst_Done(&expansions); 1268 1269 DEBUG0(SUFF, "\n"); 1270 1271 /* 1272 * Now the source is expanded, remove it from the list of children to 1273 * keep it from being processed. 1274 */ 1275 pgn->unmade--; 1276 Lst_Remove(&pgn->children, cln); 1277 Lst_Remove(&cgn->parents, Lst_FindDatum(&cgn->parents, pgn)); 1278 } 1279 1280 /* 1281 * Break the result into a vector of strings whose nodes we can find, then 1282 * add those nodes to the members list. 1283 * 1284 * Unfortunately, we can't use Str_Words because it doesn't understand about 1285 * variable specifications with spaces in them. 1286 */ 1287 static void 1288 ExpandChildrenRegular(char *cp, GNode *pgn, GNodeList *members) 1289 { 1290 char *start; 1291 1292 pp_skip_hspace(&cp); 1293 start = cp; 1294 while (*cp != '\0') { 1295 if (*cp == ' ' || *cp == '\t') { 1296 GNode *gn; 1297 /* 1298 * White-space -- terminate element, find the node, 1299 * add it, skip any further spaces. 1300 */ 1301 *cp++ = '\0'; 1302 gn = Targ_GetNode(start); 1303 Lst_Append(members, gn); 1304 pp_skip_hspace(&cp); 1305 /* Continue at the next non-space. */ 1306 start = cp; 1307 } else if (*cp == '$') { 1308 /* Skip over the variable expression. */ 1309 const char *nested_p = cp; 1310 FStr junk; 1311 1312 (void)Var_Parse(&nested_p, pgn, VARE_NONE, &junk); 1313 /* TODO: handle errors */ 1314 if (junk.str == var_Error) { 1315 Parse_Error(PARSE_FATAL, 1316 "Malformed variable expression at \"%s\"", 1317 cp); 1318 cp++; 1319 } else { 1320 cp += nested_p - cp; 1321 } 1322 1323 FStr_Done(&junk); 1324 } else if (cp[0] == '\\' && cp[1] != '\0') { 1325 /* Escaped something -- skip over it. */ 1326 /* 1327 * XXX: In other places, escaping at this syntactical 1328 * position is done by a '$', not a '\'. The '\' is 1329 * only used in variable modifiers. 1330 */ 1331 cp += 2; 1332 } else { 1333 cp++; 1334 } 1335 } 1336 1337 if (cp != start) { 1338 /* 1339 * Stuff left over -- add it to the list too 1340 */ 1341 GNode *gn = Targ_GetNode(start); 1342 Lst_Append(members, gn); 1343 } 1344 } 1345 1346 /* 1347 * Expand the names of any children of a given node that contain variable 1348 * expressions or file wildcards into actual targets. 1349 * 1350 * The expanded node is removed from the parent's list of children, and the 1351 * parent's unmade counter is decremented, but other nodes may be added. 1352 * 1353 * Input: 1354 * cln Child to examine 1355 * pgn Parent node being processed 1356 */ 1357 static void 1358 ExpandChildren(GNodeListNode *cln, GNode *pgn) 1359 { 1360 GNode *cgn = cln->datum; 1361 char *cp; /* Expanded value */ 1362 1363 if (!Lst_IsEmpty(&cgn->order_pred) || !Lst_IsEmpty(&cgn->order_succ)) 1364 /* It is all too hard to process the result of .ORDER */ 1365 return; 1366 1367 if (cgn->type & OP_WAIT) 1368 /* Ignore these (& OP_PHONY ?) */ 1369 return; 1370 1371 /* 1372 * First do variable expansion -- this takes precedence over wildcard 1373 * expansion. If the result contains wildcards, they'll be gotten to 1374 * later since the resulting words are tacked on to the end of the 1375 * children list. 1376 */ 1377 if (strchr(cgn->name, '$') == NULL) { 1378 ExpandWildcards(cln, pgn); 1379 return; 1380 } 1381 1382 DEBUG1(SUFF, "Expanding \"%s\"...", cgn->name); 1383 (void)Var_Subst(cgn->name, pgn, VARE_WANTRES | VARE_UNDEFERR, &cp); 1384 /* TODO: handle errors */ 1385 1386 { 1387 GNodeList members = LST_INIT; 1388 1389 if (cgn->type & OP_ARCHV) { 1390 /* 1391 * Node was an 'archive(member)' target, so 1392 * call on the Arch module to find the nodes for us, 1393 * expanding variables in the parent's scope. 1394 */ 1395 char *p = cp; 1396 (void)Arch_ParseArchive(&p, &members, pgn); 1397 } else { 1398 ExpandChildrenRegular(cp, pgn, &members); 1399 } 1400 1401 /* 1402 * Add all elements of the members list to the parent node. 1403 */ 1404 while (!Lst_IsEmpty(&members)) { 1405 GNode *gn = Lst_Dequeue(&members); 1406 1407 DEBUG1(SUFF, "%s...", gn->name); 1408 /* 1409 * Add gn to the parents child list before the 1410 * original child. 1411 */ 1412 Lst_InsertBefore(&pgn->children, cln, gn); 1413 Lst_Append(&gn->parents, pgn); 1414 pgn->unmade++; 1415 /* Expand wildcards on new node */ 1416 ExpandWildcards(cln->prev, pgn); 1417 } 1418 Lst_Done(&members); 1419 1420 free(cp); 1421 } 1422 1423 DEBUG0(SUFF, "\n"); 1424 1425 /* 1426 * Now the source is expanded, remove it from the list of children to 1427 * keep it from being processed. 1428 */ 1429 pgn->unmade--; 1430 Lst_Remove(&pgn->children, cln); 1431 Lst_Remove(&cgn->parents, Lst_FindDatum(&cgn->parents, pgn)); 1432 } 1433 1434 static void 1435 ExpandAllChildren(GNode *gn) 1436 { 1437 GNodeListNode *ln, *nln; 1438 1439 for (ln = gn->children.first; ln != NULL; ln = nln) { 1440 nln = ln->next; 1441 ExpandChildren(ln, gn); 1442 } 1443 } 1444 1445 /* 1446 * Find a path along which to expand the node. 1447 * 1448 * If the node has a known suffix, use that path. 1449 * If it has no known suffix, use the default system search path. 1450 * 1451 * Input: 1452 * gn Node being examined 1453 * 1454 * Results: 1455 * The appropriate path to search for the GNode. 1456 */ 1457 SearchPath * 1458 Suff_FindPath(GNode *gn) 1459 { 1460 Suffix *suff = gn->suffix; 1461 1462 if (suff == NULL) { 1463 char *name = gn->name; 1464 size_t nameLen = strlen(gn->name); 1465 SuffixListNode *ln; 1466 for (ln = sufflist.first; ln != NULL; ln = ln->next) 1467 if (Suffix_IsSuffix(ln->datum, nameLen, name + nameLen)) 1468 break; 1469 1470 DEBUG1(SUFF, "Wildcard expanding \"%s\"...", gn->name); 1471 if (ln != NULL) 1472 suff = ln->datum; 1473 /* 1474 * XXX: Here we can save the suffix so we don't have to do 1475 * this again. 1476 */ 1477 } 1478 1479 if (suff != NULL) { 1480 DEBUG1(SUFF, "suffix is \"%s\"...\n", suff->name); 1481 return suff->searchPath; 1482 } else { 1483 DEBUG0(SUFF, "\n"); 1484 return &dirSearchPath; /* Use default search path */ 1485 } 1486 } 1487 1488 /* 1489 * Apply a transformation rule, given the source and target nodes and 1490 * suffixes. 1491 * 1492 * The source and target are linked and the commands from the transformation 1493 * are added to the target node's commands list. The target also inherits all 1494 * the sources for the transformation rule. 1495 * 1496 * Results: 1497 * TRUE if successful, FALSE if not. 1498 */ 1499 static Boolean 1500 ApplyTransform(GNode *tgn, GNode *sgn, Suffix *tsuff, Suffix *ssuff) 1501 { 1502 GNodeListNode *ln; 1503 char *tname; /* Name of transformation rule */ 1504 GNode *gn; /* Node for the transformation rule */ 1505 1506 /* Form the proper links between the target and source. */ 1507 Lst_Append(&tgn->children, sgn); 1508 Lst_Append(&sgn->parents, tgn); 1509 tgn->unmade++; 1510 1511 /* Locate the transformation rule itself. */ 1512 tname = str_concat2(ssuff->name, tsuff->name); 1513 gn = FindTransformByName(tname); 1514 free(tname); 1515 1516 /* This can happen when linking an OP_MEMBER and OP_ARCHV node. */ 1517 if (gn == NULL) 1518 return FALSE; 1519 1520 DEBUG3(SUFF, "\tapplying %s -> %s to \"%s\"\n", 1521 ssuff->name, tsuff->name, tgn->name); 1522 1523 /* Record last child; Make_HandleUse may add child nodes. */ 1524 ln = tgn->children.last; 1525 1526 /* Apply the rule. */ 1527 Make_HandleUse(gn, tgn); 1528 1529 /* Deal with wildcards and variables in any acquired sources. */ 1530 ln = ln != NULL ? ln->next : NULL; 1531 while (ln != NULL) { 1532 GNodeListNode *nln = ln->next; 1533 ExpandChildren(ln, tgn); 1534 ln = nln; 1535 } 1536 1537 /* 1538 * Keep track of another parent to which this node is transformed so 1539 * the .IMPSRC variable can be set correctly for the parent. 1540 */ 1541 Lst_Append(&sgn->implicitParents, tgn); 1542 1543 return TRUE; 1544 } 1545 1546 /* 1547 * Member has a known suffix, so look for a transformation rule from 1548 * it to a possible suffix of the archive. 1549 * 1550 * Rather than searching through the entire list, we just look at 1551 * suffixes to which the member's suffix may be transformed. 1552 */ 1553 static void 1554 ExpandMember(GNode *gn, const char *eoarch, GNode *mem, Suffix *memSuff) 1555 { 1556 GNodeListNode *ln; 1557 size_t nameLen = (size_t)(eoarch - gn->name); 1558 1559 /* Use first matching suffix... */ 1560 for (ln = memSuff->parents.first; ln != NULL; ln = ln->next) 1561 if (Suffix_IsSuffix(ln->datum, nameLen, eoarch)) 1562 break; 1563 1564 if (ln != NULL) { 1565 /* Got one -- apply it */ 1566 Suffix *suff = ln->datum; 1567 if (!ApplyTransform(gn, mem, suff, memSuff)) { 1568 DEBUG2(SUFF, "\tNo transformation from %s -> %s\n", 1569 memSuff->name, suff->name); 1570 } 1571 } 1572 } 1573 1574 static void FindDeps(GNode *, CandidateSearcher *); 1575 1576 /* 1577 * Locate dependencies for an OP_ARCHV node. 1578 * 1579 * Input: 1580 * gn Node for which to locate dependencies 1581 * 1582 * Side Effects: 1583 * Same as Suff_FindDeps 1584 */ 1585 static void 1586 FindDepsArchive(GNode *gn, CandidateSearcher *cs) 1587 { 1588 char *eoarch; /* End of archive portion */ 1589 char *eoname; /* End of member portion */ 1590 GNode *mem; /* Node for member */ 1591 Suffix *memSuff; 1592 const char *name; /* Start of member's name */ 1593 1594 /* 1595 * The node is an archive(member) pair. so we must find a 1596 * suffix for both of them. 1597 */ 1598 eoarch = strchr(gn->name, '('); 1599 eoname = strchr(eoarch, ')'); 1600 1601 /* 1602 * Caller guarantees the format `libname(member)', via 1603 * Arch_ParseArchive. 1604 */ 1605 assert(eoarch != NULL); 1606 assert(eoname != NULL); 1607 1608 *eoname = '\0'; /* Nuke parentheses during suffix search */ 1609 *eoarch = '\0'; /* So a suffix can be found */ 1610 1611 name = eoarch + 1; 1612 1613 /* 1614 * To simplify things, call Suff_FindDeps recursively on the member 1615 * now, so we can simply compare the member's .PREFIX and .TARGET 1616 * variables to locate its suffix. This allows us to figure out the 1617 * suffix to use for the archive without having to do a quadratic 1618 * search over the suffix list, backtracking for each one. 1619 */ 1620 mem = Targ_GetNode(name); 1621 FindDeps(mem, cs); 1622 1623 /* Create the link between the two nodes right off. */ 1624 Lst_Append(&gn->children, mem); 1625 Lst_Append(&mem->parents, gn); 1626 gn->unmade++; 1627 1628 /* Copy in the variables from the member node to this one. */ 1629 Var_Set(gn, PREFIX, GNode_VarPrefix(mem)); 1630 Var_Set(gn, TARGET, GNode_VarTarget(mem)); 1631 1632 memSuff = mem->suffix; 1633 if (memSuff == NULL) { /* Didn't know what it was. */ 1634 DEBUG0(SUFF, "using null suffix\n"); 1635 memSuff = nullSuff; 1636 } 1637 1638 1639 /* Set the other two local variables required for this target. */ 1640 Var_Set(gn, MEMBER, name); 1641 Var_Set(gn, ARCHIVE, gn->name); 1642 /* Set $@ for compatibility with other makes. */ 1643 Var_Set(gn, TARGET, gn->name); 1644 1645 /* 1646 * Now we've got the important local variables set, expand any sources 1647 * that still contain variables or wildcards in their names. 1648 */ 1649 ExpandAllChildren(gn); 1650 1651 if (memSuff != NULL) 1652 ExpandMember(gn, eoarch, mem, memSuff); 1653 1654 /* 1655 * Replace the opening and closing parens now we've no need of the 1656 * separate pieces. 1657 */ 1658 *eoarch = '('; 1659 *eoname = ')'; 1660 1661 /* 1662 * Pretend gn appeared to the left of a dependency operator so the 1663 * user needn't provide a transformation from the member to the 1664 * archive. 1665 */ 1666 if (!GNode_IsTarget(gn)) 1667 gn->type |= OP_DEPENDS; 1668 1669 /* 1670 * Flag the member as such so we remember to look in the archive for 1671 * its modification time. The OP_JOIN | OP_MADE is needed because 1672 * this target should never get made. 1673 */ 1674 mem->type |= OP_MEMBER | OP_JOIN | OP_MADE; 1675 } 1676 1677 /* 1678 * If the node is a library, it is the arch module's job to find it 1679 * and set the TARGET variable accordingly. We merely provide the 1680 * search path, assuming all libraries end in ".a" (if the suffix 1681 * hasn't been defined, there's nothing we can do for it, so we just 1682 * set the TARGET variable to the node's name in order to give it a 1683 * value). 1684 */ 1685 static void 1686 FindDepsLib(GNode *gn) 1687 { 1688 Suffix *suff = FindSuffixByName(LIBSUFF); 1689 if (suff != NULL) { 1690 Suffix_Reassign(&gn->suffix, suff); 1691 Arch_FindLib(gn, suff->searchPath); 1692 } else { 1693 Suffix_Unassign(&gn->suffix); 1694 Var_Set(gn, TARGET, gn->name); 1695 } 1696 1697 /* 1698 * Because a library (-lfoo) target doesn't follow the standard 1699 * filesystem conventions, we don't set the regular variables for 1700 * the thing. .PREFIX is simply made empty. 1701 */ 1702 Var_Set(gn, PREFIX, ""); 1703 } 1704 1705 static void 1706 FindDepsRegularKnown(const char *name, size_t nameLen, GNode *gn, 1707 CandidateList *srcs, CandidateList *targs) 1708 { 1709 SuffixListNode *ln; 1710 Candidate *targ; 1711 char *pref; 1712 1713 for (ln = sufflist.first; ln != NULL; ln = ln->next) { 1714 Suffix *suff = ln->datum; 1715 if (!Suffix_IsSuffix(suff, nameLen, name + nameLen)) 1716 continue; 1717 1718 pref = bmake_strldup(name, (size_t)(nameLen - suff->nameLen)); 1719 targ = Candidate_New(bmake_strdup(gn->name), pref, suff, NULL, 1720 gn); 1721 1722 CandidateList_AddCandidatesFor(srcs, targ); 1723 1724 /* Record the target so we can nuke it. */ 1725 Lst_Append(targs, targ); 1726 } 1727 } 1728 1729 static void 1730 FindDepsRegularUnknown(GNode *gn, const char *sopref, 1731 CandidateList *srcs, CandidateList *targs) 1732 { 1733 Candidate *targ; 1734 1735 if (!Lst_IsEmpty(targs) || nullSuff == NULL) 1736 return; 1737 1738 DEBUG1(SUFF, "\tNo known suffix on %s. Using .NULL suffix\n", gn->name); 1739 1740 targ = Candidate_New(bmake_strdup(gn->name), bmake_strdup(sopref), 1741 nullSuff, NULL, gn); 1742 1743 /* 1744 * Only use the default suffix rules if we don't have commands 1745 * defined for this gnode; traditional make programs used to not 1746 * define suffix rules if the gnode had children but we don't do 1747 * this anymore. 1748 */ 1749 if (Lst_IsEmpty(&gn->commands)) 1750 CandidateList_AddCandidatesFor(srcs, targ); 1751 else { 1752 DEBUG0(SUFF, "not "); 1753 } 1754 1755 DEBUG0(SUFF, "adding suffix rules\n"); 1756 1757 Lst_Append(targs, targ); 1758 } 1759 1760 /* 1761 * Deal with finding the thing on the default search path. We always do 1762 * that, not only if the node is only a source (not on the lhs of a 1763 * dependency operator or [XXX] it has neither children or commands) as 1764 * the old pmake did. 1765 */ 1766 static void 1767 FindDepsRegularPath(GNode *gn, Candidate *targ) 1768 { 1769 if (gn->type & (OP_PHONY | OP_NOPATH)) 1770 return; 1771 1772 free(gn->path); 1773 gn->path = Dir_FindFile(gn->name, 1774 (targ == NULL ? &dirSearchPath : 1775 targ->suff->searchPath)); 1776 if (gn->path == NULL) 1777 return; 1778 1779 Var_Set(gn, TARGET, gn->path); 1780 1781 if (targ != NULL) { 1782 /* 1783 * Suffix known for the thing -- trim the suffix off 1784 * the path to form the proper .PREFIX variable. 1785 */ 1786 size_t savep = strlen(gn->path) - targ->suff->nameLen; 1787 char savec; 1788 1789 Suffix_Reassign(&gn->suffix, targ->suff); 1790 1791 savec = gn->path[savep]; 1792 gn->path[savep] = '\0'; 1793 1794 Var_Set(gn, PREFIX, str_basename(gn->path)); 1795 1796 gn->path[savep] = savec; 1797 } else { 1798 /* 1799 * The .PREFIX gets the full path if the target has no 1800 * known suffix. 1801 */ 1802 Suffix_Unassign(&gn->suffix); 1803 Var_Set(gn, PREFIX, str_basename(gn->path)); 1804 } 1805 } 1806 1807 /* 1808 * Locate implicit dependencies for regular targets. 1809 * 1810 * Input: 1811 * gn Node for which to find sources 1812 * 1813 * Side Effects: 1814 * Same as Suff_FindDeps 1815 */ 1816 static void 1817 FindDepsRegular(GNode *gn, CandidateSearcher *cs) 1818 { 1819 /* List of sources at which to look */ 1820 CandidateList srcs = LST_INIT; 1821 /* 1822 * List of targets to which things can be transformed. 1823 * They all have the same file, but different suff and prefix fields. 1824 */ 1825 CandidateList targs = LST_INIT; 1826 Candidate *bottom; /* Start of found transformation path */ 1827 Candidate *src; 1828 Candidate *targ; 1829 1830 const char *name = gn->name; 1831 size_t nameLen = strlen(name); 1832 1833 #ifdef DEBUG_SRC 1834 DEBUG1(SUFF, "FindDepsRegular \"%s\"\n", gn->name); 1835 #endif 1836 1837 /* 1838 * We're caught in a catch-22 here. On the one hand, we want to use 1839 * any transformation implied by the target's sources, but we can't 1840 * examine the sources until we've expanded any variables/wildcards 1841 * they may hold, and we can't do that until we've set up the 1842 * target's local variables and we can't do that until we know what 1843 * the proper suffix for the target is (in case there are two 1844 * suffixes one of which is a suffix of the other) and we can't know 1845 * that until we've found its implied source, which we may not want 1846 * to use if there's an existing source that implies a different 1847 * transformation. 1848 * 1849 * In an attempt to get around this, which may not work all the time, 1850 * but should work most of the time, we look for implied sources 1851 * first, checking transformations to all possible suffixes of the 1852 * target, use what we find to set the target's local variables, 1853 * expand the children, then look for any overriding transformations 1854 * they imply. Should we find one, we discard the one we found before. 1855 */ 1856 bottom = NULL; 1857 targ = NULL; 1858 1859 if (!(gn->type & OP_PHONY)) { 1860 1861 FindDepsRegularKnown(name, nameLen, gn, &srcs, &targs); 1862 1863 /* Handle target of unknown suffix... */ 1864 FindDepsRegularUnknown(gn, name, &srcs, &targs); 1865 1866 /* 1867 * Using the list of possible sources built up from the target 1868 * suffix(es), try and find an existing file/target that 1869 * matches. 1870 */ 1871 bottom = FindThem(&srcs, cs); 1872 1873 if (bottom == NULL) { 1874 /* 1875 * No known transformations -- use the first suffix 1876 * found for setting the local variables. 1877 */ 1878 if (targs.first != NULL) 1879 targ = targs.first->datum; 1880 else 1881 targ = NULL; 1882 } else { 1883 /* 1884 * Work up the transformation path to find the suffix 1885 * of the target to which the transformation was made. 1886 */ 1887 for (targ = bottom; 1888 targ->parent != NULL; targ = targ->parent) 1889 continue; 1890 } 1891 } 1892 1893 Var_Set(gn, TARGET, GNode_Path(gn)); 1894 Var_Set(gn, PREFIX, targ != NULL ? targ->prefix : gn->name); 1895 1896 /* 1897 * Now we've got the important local variables set, expand any sources 1898 * that still contain variables or wildcards in their names. 1899 */ 1900 { 1901 GNodeListNode *ln, *nln; 1902 for (ln = gn->children.first; ln != NULL; ln = nln) { 1903 nln = ln->next; 1904 ExpandChildren(ln, gn); 1905 } 1906 } 1907 1908 if (targ == NULL) { 1909 DEBUG1(SUFF, "\tNo valid suffix on %s\n", gn->name); 1910 1911 sfnd_abort: 1912 FindDepsRegularPath(gn, targ); 1913 goto sfnd_return; 1914 } 1915 1916 /* 1917 * If the suffix indicates that the target is a library, mark that in 1918 * the node's type field. 1919 */ 1920 if (targ->suff->flags & SUFF_LIBRARY) 1921 gn->type |= OP_LIB; 1922 1923 /* 1924 * Check for overriding transformation rule implied by sources 1925 */ 1926 if (!Lst_IsEmpty(&gn->children)) { 1927 src = FindCmds(targ, cs); 1928 1929 if (src != NULL) { 1930 /* 1931 * Free up all the candidates in the transformation 1932 * path, up to but not including the parent node. 1933 */ 1934 while (bottom != NULL && bottom->parent != NULL) { 1935 CandidateSearcher_AddIfNew(cs, bottom); 1936 bottom = bottom->parent; 1937 } 1938 bottom = src; 1939 } 1940 } 1941 1942 if (bottom == NULL) { 1943 /* No idea from where it can come -- return now. */ 1944 goto sfnd_abort; 1945 } 1946 1947 /* 1948 * We now have a list of candidates headed by 'bottom' and linked via 1949 * their 'parent' pointers. What we do next is create links between 1950 * source and target nodes (which may or may not have been created) 1951 * and set the necessary local variables in each target. 1952 * 1953 * The commands for each target are set from the commands of the 1954 * transformation rule used to get from the src suffix to the targ 1955 * suffix. Note that this causes the commands list of the original 1956 * node, gn, to be replaced with the commands of the final 1957 * transformation rule. 1958 */ 1959 if (bottom->node == NULL) 1960 bottom->node = Targ_GetNode(bottom->file); 1961 1962 for (src = bottom; src->parent != NULL; src = src->parent) { 1963 targ = src->parent; 1964 1965 Suffix_Reassign(&src->node->suffix, src->suff); 1966 1967 if (targ->node == NULL) 1968 targ->node = Targ_GetNode(targ->file); 1969 1970 ApplyTransform(targ->node, src->node, 1971 targ->suff, src->suff); 1972 1973 if (targ->node != gn) { 1974 /* 1975 * Finish off the dependency-search process for any 1976 * nodes between bottom and gn (no point in questing 1977 * around the filesystem for their implicit source 1978 * when it's already known). Note that the node 1979 * can't have any sources that need expanding, since 1980 * SuffFindThem will stop on an existing node, so all 1981 * we need to do is set the standard variables. 1982 */ 1983 targ->node->type |= OP_DEPS_FOUND; 1984 Var_Set(targ->node, PREFIX, targ->prefix); 1985 Var_Set(targ->node, TARGET, targ->node->name); 1986 } 1987 } 1988 1989 Suffix_Reassign(&gn->suffix, src->suff); 1990 1991 /* 1992 * Nuke the transformation path and the candidates left over in the 1993 * two lists. 1994 */ 1995 sfnd_return: 1996 if (bottom != NULL) 1997 CandidateSearcher_AddIfNew(cs, bottom); 1998 1999 while (RemoveCandidate(&srcs) || RemoveCandidate(&targs)) 2000 continue; 2001 2002 CandidateSearcher_MoveAll(cs, &srcs); 2003 CandidateSearcher_MoveAll(cs, &targs); 2004 } 2005 2006 static void 2007 CandidateSearcher_CleanUp(CandidateSearcher *cs) 2008 { 2009 while (RemoveCandidate(&cs->list)) 2010 continue; 2011 assert(Lst_IsEmpty(&cs->list)); 2012 } 2013 2014 2015 /* 2016 * Find implicit sources for the target. 2017 * 2018 * Nodes are added to the graph as children of the passed-in node. The nodes 2019 * are marked to have their IMPSRC variable filled in. The PREFIX variable 2020 * is set for the given node and all its implied children. 2021 * 2022 * The path found by this target is the shortest path in the transformation 2023 * graph, which may pass through nonexistent targets, to an existing target. 2024 * The search continues on all paths from the root suffix until a file is 2025 * found. I.e. if there's a path .o -> .c -> .l -> .l,v from the root and the 2026 * .l,v file exists but the .c and .l files don't, the search will branch out 2027 * in all directions from .o and again from all the nodes on the next level 2028 * until the .l,v node is encountered. 2029 */ 2030 void 2031 Suff_FindDeps(GNode *gn) 2032 { 2033 CandidateSearcher cs; 2034 2035 CandidateSearcher_Init(&cs); 2036 2037 FindDeps(gn, &cs); 2038 2039 CandidateSearcher_CleanUp(&cs); 2040 CandidateSearcher_Done(&cs); 2041 } 2042 2043 static void 2044 FindDeps(GNode *gn, CandidateSearcher *cs) 2045 { 2046 if (gn->type & OP_DEPS_FOUND) 2047 return; 2048 gn->type |= OP_DEPS_FOUND; 2049 2050 /* Make sure we have these set, may get revised below. */ 2051 Var_Set(gn, TARGET, GNode_Path(gn)); 2052 Var_Set(gn, PREFIX, gn->name); 2053 2054 DEBUG1(SUFF, "SuffFindDeps \"%s\"\n", gn->name); 2055 2056 if (gn->type & OP_ARCHV) 2057 FindDepsArchive(gn, cs); 2058 else if (gn->type & OP_LIB) 2059 FindDepsLib(gn); 2060 else 2061 FindDepsRegular(gn, cs); 2062 } 2063 2064 /* 2065 * Define which suffix is the null suffix. 2066 * 2067 * Need to handle the changing of the null suffix gracefully so the old 2068 * transformation rules don't just go away. 2069 * 2070 * Input: 2071 * name Name of null suffix 2072 */ 2073 void 2074 Suff_SetNull(const char *name) 2075 { 2076 Suffix *suff = FindSuffixByName(name); 2077 if (suff == NULL) { 2078 Parse_Error(PARSE_WARNING, 2079 "Desired null suffix %s not defined.", 2080 name); 2081 return; 2082 } 2083 2084 if (nullSuff != NULL) 2085 nullSuff->flags &= ~(unsigned)SUFF_NULL; 2086 suff->flags |= SUFF_NULL; 2087 /* XXX: Here's where the transformation mangling would take place. */ 2088 nullSuff = suff; 2089 } 2090 2091 /* Initialize the suffixes module. */ 2092 void 2093 Suff_Init(void) 2094 { 2095 /* 2096 * Create null suffix for single-suffix rules (POSIX). The thing 2097 * doesn't actually go on the suffix list or everyone will think 2098 * that's its suffix. 2099 */ 2100 Suff_ClearSuffixes(); 2101 } 2102 2103 2104 /* Clean up the suffixes module. */ 2105 void 2106 Suff_End(void) 2107 { 2108 #ifdef CLEANUP 2109 Lst_DoneCall(&sufflist, SuffFree); 2110 Lst_DoneCall(&suffClean, SuffFree); 2111 if (nullSuff != NULL) 2112 SuffFree(nullSuff); 2113 Lst_Done(&transforms); 2114 #endif 2115 } 2116 2117 2118 static void 2119 PrintSuffNames(const char *prefix, SuffixList *suffs) 2120 { 2121 SuffixListNode *ln; 2122 2123 debug_printf("#\t%s: ", prefix); 2124 for (ln = suffs->first; ln != NULL; ln = ln->next) { 2125 Suffix *suff = ln->datum; 2126 debug_printf("%s ", suff->name); 2127 } 2128 debug_printf("\n"); 2129 } 2130 2131 static void 2132 Suffix_Print(Suffix *suff) 2133 { 2134 debug_printf("# \"%s\" (num %d, ref %d)", 2135 suff->name, suff->sNum, suff->refCount); 2136 if (suff->flags != 0) { 2137 char flags_buf[SuffixFlags_ToStringSize]; 2138 2139 debug_printf(" (%s)", 2140 SuffixFlags_ToString(flags_buf, suff->flags)); 2141 } 2142 debug_printf("\n"); 2143 2144 PrintSuffNames("To", &suff->parents); 2145 PrintSuffNames("From", &suff->children); 2146 2147 debug_printf("#\tSearch Path: "); 2148 SearchPath_Print(suff->searchPath); 2149 debug_printf("\n"); 2150 } 2151 2152 static void 2153 PrintTransformation(GNode *t) 2154 { 2155 debug_printf("%-16s:", t->name); 2156 Targ_PrintType(t->type); 2157 debug_printf("\n"); 2158 Targ_PrintCmds(t); 2159 debug_printf("\n"); 2160 } 2161 2162 void 2163 Suff_PrintAll(void) 2164 { 2165 debug_printf("#*** Suffixes:\n"); 2166 { 2167 SuffixListNode *ln; 2168 for (ln = sufflist.first; ln != NULL; ln = ln->next) 2169 Suffix_Print(ln->datum); 2170 } 2171 2172 debug_printf("#*** Transformations:\n"); 2173 { 2174 GNodeListNode *ln; 2175 for (ln = transforms.first; ln != NULL; ln = ln->next) 2176 PrintTransformation(ln->datum); 2177 } 2178 } 2179