diff options
Diffstat (limited to 'miscutils/make.c')
-rw-r--r-- | miscutils/make.c | 263 |
1 files changed, 193 insertions, 70 deletions
diff --git a/miscutils/make.c b/miscutils/make.c index 7316408bf..01fc18822 100644 --- a/miscutils/make.c +++ b/miscutils/make.c | |||
@@ -257,6 +257,11 @@ enum { | |||
257 | #define MAKE_FAILURE 0x01 | 257 | #define MAKE_FAILURE 0x01 |
258 | #define MAKE_DIDSOMETHING 0x02 | 258 | #define MAKE_DIDSOMETHING 0x02 |
259 | 259 | ||
260 | // Return TRUE if c is allowed in a POSIX 2017 macro or target name | ||
261 | #define ispname(c) (isalpha(c) || isdigit(c) || c == '.' || c == '_') | ||
262 | // Return TRUE if c is in the POSIX 'portable filename character set' | ||
263 | #define isfname(c) (ispname(c) || c == '-') | ||
264 | |||
260 | #define HTABSIZE 39 | 265 | #define HTABSIZE 39 |
261 | 266 | ||
262 | struct globals { | 267 | struct globals { |
@@ -320,11 +325,8 @@ struct globals { | |||
320 | #endif | 325 | #endif |
321 | 326 | ||
322 | static int make(struct name *np, int level); | 327 | static int make(struct name *np, int level); |
323 | 328 | static struct name *dyndep(struct name *np, struct rule *infrule, | |
324 | // Return TRUE if c is allowed in a POSIX 2017 macro or target name | 329 | const char **ptsuff); |
325 | #define ispname(c) (isalpha(c) || isdigit(c) || c == '.' || c == '_') | ||
326 | // Return TRUE if c is in the POSIX 'portable filename character set' | ||
327 | #define isfname(c) (ispname(c) || c == '-') | ||
328 | 330 | ||
329 | /* | 331 | /* |
330 | * Utility functions. | 332 | * Utility functions. |
@@ -993,38 +995,27 @@ suffix(const char *name) | |||
993 | } | 995 | } |
994 | 996 | ||
995 | /* | 997 | /* |
996 | * Dynamic dependency. This routine applies the suffix rules | 998 | * Search for an inference rule to convert some suffix ('psuff') |
997 | * to try and find a source and a set of rules for a missing | 999 | * to the target suffix 'tsuff'. The basename of the prerequisite |
998 | * target. NULL is returned on failure. On success the name of | 1000 | * is 'base'. |
999 | * the implicit prerequisite is returned and the details are | ||
1000 | * placed in the imprule structure provided by the caller. | ||
1001 | */ | 1001 | */ |
1002 | static struct name * | 1002 | static struct name * |
1003 | dyndep(struct name *np, struct rule *imprule) | 1003 | dyndep0(char *base, const char *tsuff, struct rule *infrule) |
1004 | { | 1004 | { |
1005 | char *suff, *newsuff; | 1005 | char *psuff; |
1006 | char *base, *name, *member; | ||
1007 | struct name *xp; // Suffixes | 1006 | struct name *xp; // Suffixes |
1008 | struct name *sp; // Suffix rule | 1007 | struct name *sp; // Suffix rule |
1009 | struct name *pp = NULL; // Implicit prerequisite | ||
1010 | struct rule *rp; | 1008 | struct rule *rp; |
1011 | struct depend *dp; | 1009 | struct depend *dp; |
1012 | bool chain = FALSE; | 1010 | bool chain = FALSE; |
1013 | 1011 | ||
1014 | member = NULL; | ||
1015 | name = splitlib(np->n_name, &member); | ||
1016 | |||
1017 | suff = xstrdup(suffix(name)); | ||
1018 | base = member ? member : name; | ||
1019 | *suffix(base) = '\0'; | ||
1020 | |||
1021 | xp = newname(".SUFFIXES"); | 1012 | xp = newname(".SUFFIXES"); |
1022 | retry: | 1013 | retry: |
1023 | for (rp = xp->n_rule; rp; rp = rp->r_next) { | 1014 | for (rp = xp->n_rule; rp; rp = rp->r_next) { |
1024 | for (dp = rp->r_dep; dp; dp = dp->d_next) { | 1015 | for (dp = rp->r_dep; dp; dp = dp->d_next) { |
1025 | // Generate new suffix rule to try | 1016 | // Generate new suffix rule to try |
1026 | newsuff = dp->d_name->n_name; | 1017 | psuff = dp->d_name->n_name; |
1027 | sp = findname(auto_concat(newsuff, suff)); | 1018 | sp = findname(auto_concat(psuff, tsuff)); |
1028 | if (sp && sp->n_rule) { | 1019 | if (sp && sp->n_rule) { |
1029 | struct name *ip; | 1020 | struct name *ip; |
1030 | int got_ip; | 1021 | int got_ip; |
@@ -1032,9 +1023,8 @@ dyndep(struct name *np, struct rule *imprule) | |||
1032 | // Has rule already been used in this chain? | 1023 | // Has rule already been used in this chain? |
1033 | if ((sp->n_flag & N_MARK)) | 1024 | if ((sp->n_flag & N_MARK)) |
1034 | continue; | 1025 | continue; |
1035 | |||
1036 | // Generate a name for an implicit prerequisite | 1026 | // Generate a name for an implicit prerequisite |
1037 | ip = newname(auto_concat(base, newsuff)); | 1027 | ip = newname(auto_concat(base, psuff)); |
1038 | if ((ip->n_flag & N_DOING)) | 1028 | if ((ip->n_flag & N_DOING)) |
1039 | continue; | 1029 | continue; |
1040 | 1030 | ||
@@ -1045,20 +1035,19 @@ dyndep(struct name *np, struct rule *imprule) | |||
1045 | got_ip = ip->n_tim.tv_sec || (ip->n_flag & N_TARGET); | 1035 | got_ip = ip->n_tim.tv_sec || (ip->n_flag & N_TARGET); |
1046 | } else { | 1036 | } else { |
1047 | sp->n_flag |= N_MARK; | 1037 | sp->n_flag |= N_MARK; |
1048 | got_ip = dyndep(ip, NULL) != NULL; | 1038 | got_ip = dyndep(ip, NULL, NULL) != NULL; |
1049 | sp->n_flag &= ~N_MARK; | 1039 | sp->n_flag &= ~N_MARK; |
1050 | } | 1040 | } |
1051 | 1041 | ||
1052 | if (got_ip) { | 1042 | if (got_ip) { |
1053 | // Prerequisite exists or we know how to make it | 1043 | // Prerequisite exists or we know how to make it |
1054 | if (imprule) { | 1044 | if (infrule) { |
1055 | dp = NULL; | 1045 | dp = NULL; |
1056 | newdep(&dp, ip); | 1046 | newdep(&dp, ip); |
1057 | imprule->r_dep = dp; | 1047 | infrule->r_dep = dp; |
1058 | imprule->r_cmd = sp->n_rule->r_cmd; | 1048 | infrule->r_cmd = sp->n_rule->r_cmd; |
1059 | } | 1049 | } |
1060 | pp = ip; | 1050 | return ip; |
1061 | goto finish; | ||
1062 | } | 1051 | } |
1063 | } | 1052 | } |
1064 | } | 1053 | } |
@@ -1069,9 +1058,77 @@ dyndep(struct name *np, struct rule *imprule) | |||
1069 | chain = TRUE; | 1058 | chain = TRUE; |
1070 | goto retry; | 1059 | goto retry; |
1071 | } | 1060 | } |
1072 | finish: | 1061 | return NULL; |
1073 | free(suff); | 1062 | } |
1063 | |||
1064 | /* | ||
1065 | * If 'name' ends with 'suffix' return an allocated string containing | ||
1066 | * the name with the suffix removed, else return NULL. | ||
1067 | */ | ||
1068 | static char * | ||
1069 | has_suffix(const char *name, const char *suffix) | ||
1070 | { | ||
1071 | ssize_t delta = strlen(name) - strlen(suffix); | ||
1072 | char *base = NULL; | ||
1073 | |||
1074 | if (delta > 0 && strcmp(name + delta, suffix) == 0) { | ||
1075 | base = xstrdup(name); | ||
1076 | base[delta] = '\0'; | ||
1077 | } | ||
1078 | |||
1079 | return base; | ||
1080 | } | ||
1081 | |||
1082 | /* | ||
1083 | * Dynamic dependency. This routine applies the suffix rules | ||
1084 | * to try and find a source and a set of rules for a missing | ||
1085 | * target. NULL is returned on failure. On success the name of | ||
1086 | * the implicit prerequisite is returned and the rule used is | ||
1087 | * placed in the infrule structure provided by the caller. | ||
1088 | */ | ||
1089 | static struct name * | ||
1090 | dyndep(struct name *np, struct rule *infrule, const char **ptsuff) | ||
1091 | { | ||
1092 | const char *tsuff; | ||
1093 | char *base, *name, *member; | ||
1094 | struct name *pp = NULL; // Implicit prerequisite | ||
1095 | |||
1096 | member = NULL; | ||
1097 | name = splitlib(np->n_name, &member); | ||
1098 | |||
1099 | // POSIX only allows inference rules with one or two periods. | ||
1100 | // As an extension this restriction is lifted, but not for | ||
1101 | // targets of the form lib.a(member.o). | ||
1102 | if (!posix && member == NULL) { | ||
1103 | struct name *xp = newname(".SUFFIXES"); | ||
1104 | for (struct rule *rp = xp->n_rule; rp; rp = rp->r_next) { | ||
1105 | for (struct depend *dp = rp->r_dep; dp; dp = dp->d_next) { | ||
1106 | tsuff = dp->d_name->n_name; | ||
1107 | base = has_suffix(name, tsuff); | ||
1108 | if (base) { | ||
1109 | pp = dyndep0(base, tsuff, infrule); | ||
1110 | free(base); | ||
1111 | if (pp) { | ||
1112 | if (ptsuff) | ||
1113 | *ptsuff = tsuff; | ||
1114 | goto done; | ||
1115 | } | ||
1116 | } | ||
1117 | } | ||
1118 | } | ||
1119 | |||
1120 | } else | ||
1121 | { | ||
1122 | tsuff = xstrdup(suffix(name)); | ||
1123 | base = member ? member : name; | ||
1124 | *suffix(base) = '\0'; | ||
1125 | |||
1126 | pp = dyndep0(base, tsuff, infrule); | ||
1127 | free((void *)tsuff); | ||
1128 | } | ||
1129 | done: | ||
1074 | free(name); | 1130 | free(name); |
1131 | |||
1075 | return pp; | 1132 | return pp; |
1076 | } | 1133 | } |
1077 | 1134 | ||
@@ -1789,9 +1846,10 @@ readline(FILE *fd, int want_command) | |||
1789 | } | 1846 | } |
1790 | 1847 | ||
1791 | /* | 1848 | /* |
1792 | * Return TRUE if the argument is a known suffix. | 1849 | * Return a pointer to the suffix name if the argument is a known suffix |
1850 | * or NULL if it isn't. | ||
1793 | */ | 1851 | */ |
1794 | static int | 1852 | static const char * |
1795 | is_suffix(const char *s) | 1853 | is_suffix(const char *s) |
1796 | { | 1854 | { |
1797 | struct name *np; | 1855 | struct name *np; |
@@ -1802,7 +1860,39 @@ is_suffix(const char *s) | |||
1802 | for (rp = np->n_rule; rp; rp = rp->r_next) { | 1860 | for (rp = np->n_rule; rp; rp = rp->r_next) { |
1803 | for (dp = rp->r_dep; dp; dp = dp->d_next) { | 1861 | for (dp = rp->r_dep; dp; dp = dp->d_next) { |
1804 | if (strcmp(s, dp->d_name->n_name) == 0) { | 1862 | if (strcmp(s, dp->d_name->n_name) == 0) { |
1805 | return TRUE; | 1863 | return dp->d_name->n_name; |
1864 | } | ||
1865 | } | ||
1866 | } | ||
1867 | return NULL; | ||
1868 | } | ||
1869 | |||
1870 | /* | ||
1871 | * Return TRUE if the argument is formed by concatenating two | ||
1872 | * known suffixes. | ||
1873 | */ | ||
1874 | static int | ||
1875 | is_inference_target(const char *s) | ||
1876 | { | ||
1877 | struct name *np; | ||
1878 | struct rule *rp1, *rp2; | ||
1879 | struct depend *dp1, *dp2; | ||
1880 | |||
1881 | np = newname(".SUFFIXES"); | ||
1882 | for (rp1 = np->n_rule; rp1; rp1 = rp1->r_next) { | ||
1883 | for (dp1 = rp1->r_dep; dp1; dp1 = dp1->d_next) { | ||
1884 | const char *suff1 = dp1->d_name->n_name; | ||
1885 | size_t len = strlen(suff1); | ||
1886 | |||
1887 | if (strncmp(s, suff1, len) == 0) { | ||
1888 | for (rp2 = np->n_rule; rp2; rp2 = rp2->r_next) { | ||
1889 | for (dp2 = rp2->r_dep; dp2; dp2 = dp2->d_next) { | ||
1890 | const char *suff2 = dp2->d_name->n_name; | ||
1891 | if (strcmp(s + len, suff2) == 0) { | ||
1892 | return TRUE; | ||
1893 | } | ||
1894 | } | ||
1895 | } | ||
1806 | } | 1896 | } |
1807 | } | 1897 | } |
1808 | } | 1898 | } |
@@ -1824,7 +1914,6 @@ enum { | |||
1824 | static int | 1914 | static int |
1825 | target_type(char *s) | 1915 | target_type(char *s) |
1826 | { | 1916 | { |
1827 | char *sfx; | ||
1828 | int ret; | 1917 | int ret; |
1829 | static const char *s_name = | 1918 | static const char *s_name = |
1830 | ".DEFAULT\0" | 1919 | ".DEFAULT\0" |
@@ -1854,9 +1943,6 @@ target_type(char *s) | |||
1854 | T_SPECIAL, | 1943 | T_SPECIAL, |
1855 | }; | 1944 | }; |
1856 | 1945 | ||
1857 | if (*s != '.') | ||
1858 | return T_NORMAL; | ||
1859 | |||
1860 | // Check for one of the known special targets | 1946 | // Check for one of the known special targets |
1861 | ret = index_in_strings(s_name, s); | 1947 | ret = index_in_strings(s_name, s); |
1862 | if (ret >= 0) | 1948 | if (ret >= 0) |
@@ -1864,16 +1950,24 @@ target_type(char *s) | |||
1864 | 1950 | ||
1865 | // Check for an inference rule | 1951 | // Check for an inference rule |
1866 | ret = T_NORMAL; | 1952 | ret = T_NORMAL; |
1867 | sfx = suffix(s); | 1953 | if (!posix) { |
1868 | if (is_suffix(sfx)) { | 1954 | if (is_suffix(s) || is_inference_target(s)) { |
1869 | if (s == sfx) { // Single suffix rule | ||
1870 | ret = T_INFERENCE | T_NOPREREQ | T_COMMAND; | 1955 | ret = T_INFERENCE | T_NOPREREQ | T_COMMAND; |
1871 | } else { | 1956 | } |
1872 | // Suffix is valid, check that prefix is too | 1957 | } else |
1873 | *sfx = '\0'; | 1958 | { |
1874 | if (is_suffix(s)) | 1959 | // In POSIX inference rule targets must contain one or two dots |
1960 | char *sfx = suffix(s); | ||
1961 | if (*s == '.' && is_suffix(sfx)) { | ||
1962 | if (s == sfx) { // Single suffix rule | ||
1875 | ret = T_INFERENCE | T_NOPREREQ | T_COMMAND; | 1963 | ret = T_INFERENCE | T_NOPREREQ | T_COMMAND; |
1876 | *sfx = '.'; | 1964 | } else { |
1965 | // Suffix is valid, check that prefix is too | ||
1966 | *sfx = '\0'; | ||
1967 | if (is_suffix(s)) | ||
1968 | ret = T_INFERENCE | T_NOPREREQ | T_COMMAND; | ||
1969 | *sfx = '.'; | ||
1970 | } | ||
1877 | } | 1971 | } |
1878 | } | 1972 | } |
1879 | return ret; | 1973 | return ret; |
@@ -2587,7 +2681,7 @@ docmds(struct name *np, struct cmd *cp) | |||
2587 | 2681 | ||
2588 | static int | 2682 | static int |
2589 | make1(struct name *np, struct cmd *cp, char *oodate, char *allsrc, | 2683 | make1(struct name *np, struct cmd *cp, char *oodate, char *allsrc, |
2590 | char *dedup, struct name *implicit) | 2684 | char *dedup, struct name *implicit, const char *tsuff) |
2591 | { | 2685 | { |
2592 | char *name, *member = NULL, *base = NULL, *prereq = NULL; | 2686 | char *name, *member = NULL, *base = NULL, *prereq = NULL; |
2593 | 2687 | ||
@@ -2603,7 +2697,7 @@ make1(struct name *np, struct cmd *cp, char *oodate, char *allsrc, | |||
2603 | char *s; | 2697 | char *s; |
2604 | 2698 | ||
2605 | // As an extension, if we're not dealing with an implicit | 2699 | // As an extension, if we're not dealing with an implicit |
2606 | // rule set $< to the first out-of-date prerequisite. | 2700 | // prerequisite set $< to the first out-of-date prerequisite. |
2607 | if (implicit == NULL) { | 2701 | if (implicit == NULL) { |
2608 | if (oodate) { | 2702 | if (oodate) { |
2609 | s = strchr(oodate, ' '); | 2703 | s = strchr(oodate, ' '); |
@@ -2614,16 +2708,43 @@ make1(struct name *np, struct cmd *cp, char *oodate, char *allsrc, | |||
2614 | } else | 2708 | } else |
2615 | prereq = implicit->n_name; | 2709 | prereq = implicit->n_name; |
2616 | 2710 | ||
2617 | base = member ? member : name; | 2711 | if (!posix && member == NULL) { |
2618 | s = suffix(base); | 2712 | // As an extension remove the suffix from a target, either |
2619 | // As an extension, if we're not dealing with an implicit | 2713 | // that obtained by an inference rule or one of the known |
2620 | // rule and the target ends with a known suffix, remove it | 2714 | // suffixes. Not for targets of the form lib.a(member.o). |
2621 | // and set $* to the stem, else to an empty string. | 2715 | if (tsuff != NULL) { |
2622 | if (implicit == NULL && !is_suffix(s)) | 2716 | base = has_suffix(name, tsuff); |
2623 | base = NULL; | 2717 | if (base) { |
2624 | else | 2718 | free(name); |
2625 | *s = '\0'; | 2719 | name = base; |
2720 | } | ||
2721 | } else { | ||
2722 | struct name *xp = newname(".SUFFIXES"); | ||
2723 | for (struct rule *rp = xp->n_rule; rp; rp = rp->r_next) { | ||
2724 | for (struct depend *dp = rp->r_dep; dp; dp = dp->d_next) { | ||
2725 | base = has_suffix(name, dp->d_name->n_name); | ||
2726 | if (base) { | ||
2727 | free(name); | ||
2728 | name = base; | ||
2729 | goto done; | ||
2730 | } | ||
2731 | } | ||
2732 | } | ||
2733 | } | ||
2734 | } else | ||
2735 | { | ||
2736 | base = member ? member : name; | ||
2737 | s = suffix(base); | ||
2738 | // As an extension, if we're not dealing with an implicit | ||
2739 | // prerequisite and the target ends with a known suffix, | ||
2740 | // remove it and set $* to the stem, else to an empty string. | ||
2741 | if (implicit == NULL && !is_suffix(s)) | ||
2742 | base = NULL; | ||
2743 | else | ||
2744 | *s = '\0'; | ||
2745 | } | ||
2626 | } | 2746 | } |
2747 | done: | ||
2627 | setmacro("<", prereq, 0 | M_VALID); | 2748 | setmacro("<", prereq, 0 | M_VALID); |
2628 | setmacro("*", base, 0 | M_VALID); | 2749 | setmacro("*", base, 0 | M_VALID); |
2629 | free(name); | 2750 | free(name); |
@@ -2667,11 +2788,12 @@ make(struct name *np, int level) | |||
2667 | struct depend *dp; | 2788 | struct depend *dp; |
2668 | struct rule *rp; | 2789 | struct rule *rp; |
2669 | struct name *impdep = NULL; // implicit prerequisite | 2790 | struct name *impdep = NULL; // implicit prerequisite |
2670 | struct rule imprule; | 2791 | struct rule infrule; |
2671 | struct cmd *sc_cmd = NULL; // commands for single-colon rule | 2792 | struct cmd *sc_cmd = NULL; // commands for single-colon rule |
2672 | char *oodate = NULL; | 2793 | char *oodate = NULL; |
2673 | char *allsrc = NULL; | 2794 | char *allsrc = NULL; |
2674 | char *dedup = NULL; | 2795 | char *dedup = NULL; |
2796 | const char *tsuff = NULL; | ||
2675 | struct timespec dtim = {1, 0}; | 2797 | struct timespec dtim = {1, 0}; |
2676 | int estat = 0; | 2798 | int estat = 0; |
2677 | 2799 | ||
@@ -2690,10 +2812,10 @@ make(struct name *np, int level) | |||
2690 | // as an extension, not for phony targets) | 2812 | // as an extension, not for phony targets) |
2691 | sc_cmd = getcmd(np); | 2813 | sc_cmd = getcmd(np); |
2692 | if (!sc_cmd && (posix || !(np->n_flag & N_PHONY))) { | 2814 | if (!sc_cmd && (posix || !(np->n_flag & N_PHONY))) { |
2693 | impdep = dyndep(np, &imprule); | 2815 | impdep = dyndep(np, &infrule, &tsuff); |
2694 | if (impdep) { | 2816 | if (impdep) { |
2695 | sc_cmd = imprule.r_cmd; | 2817 | sc_cmd = infrule.r_cmd; |
2696 | addrule(np, imprule.r_dep, NULL, FALSE); | 2818 | addrule(np, infrule.r_dep, NULL, FALSE); |
2697 | } | 2819 | } |
2698 | } | 2820 | } |
2699 | 2821 | ||
@@ -2715,7 +2837,7 @@ make(struct name *np, int level) | |||
2715 | for (rp = np->n_rule; rp; rp = rp->r_next) { | 2837 | for (rp = np->n_rule; rp; rp = rp->r_next) { |
2716 | if (!rp->r_cmd) { | 2838 | if (!rp->r_cmd) { |
2717 | if (posix || !(np->n_flag & N_PHONY)) | 2839 | if (posix || !(np->n_flag & N_PHONY)) |
2718 | impdep = dyndep(np, &imprule); | 2840 | impdep = dyndep(np, &infrule, &tsuff); |
2719 | if (!impdep) { | 2841 | if (!impdep) { |
2720 | if (doinclude) | 2842 | if (doinclude) |
2721 | return 1; | 2843 | return 1; |
@@ -2743,9 +2865,9 @@ make(struct name *np, int level) | |||
2743 | // If the rule has no commands use the inference rule. | 2865 | // If the rule has no commands use the inference rule. |
2744 | if (!rp->r_cmd) { | 2866 | if (!rp->r_cmd) { |
2745 | locdep = impdep; | 2867 | locdep = impdep; |
2746 | imprule.r_dep->d_next = rp->r_dep; | 2868 | infrule.r_dep->d_next = rp->r_dep; |
2747 | rp->r_dep = imprule.r_dep; | 2869 | rp->r_dep = infrule.r_dep; |
2748 | rp->r_cmd = imprule.r_cmd; | 2870 | rp->r_cmd = infrule.r_cmd; |
2749 | } | 2871 | } |
2750 | // A rule with no prerequisities is executed unconditionally. | 2872 | // A rule with no prerequisities is executed unconditionally. |
2751 | if (!rp->r_dep) | 2873 | if (!rp->r_dep) |
@@ -2776,7 +2898,7 @@ make(struct name *np, int level) | |||
2776 | if (((np->n_flag & N_PHONY) || timespec_le(&np->n_tim, &dtim))) { | 2898 | if (((np->n_flag & N_PHONY) || timespec_le(&np->n_tim, &dtim))) { |
2777 | if (!(estat & MAKE_FAILURE)) { | 2899 | if (!(estat & MAKE_FAILURE)) { |
2778 | estat |= make1(np, rp->r_cmd, oodate, allsrc, | 2900 | estat |= make1(np, rp->r_cmd, oodate, allsrc, |
2779 | dedup, locdep); | 2901 | dedup, locdep, tsuff); |
2780 | dtim = (struct timespec){1, 0}; | 2902 | dtim = (struct timespec){1, 0}; |
2781 | } | 2903 | } |
2782 | free(oodate); | 2904 | free(oodate); |
@@ -2792,7 +2914,7 @@ make(struct name *np, int level) | |||
2792 | } | 2914 | } |
2793 | } | 2915 | } |
2794 | if ((np->n_flag & N_DOUBLE) && impdep) | 2916 | if ((np->n_flag & N_DOUBLE) && impdep) |
2795 | free(imprule.r_dep); | 2917 | free(infrule.r_dep); |
2796 | 2918 | ||
2797 | np->n_flag |= N_DONE; | 2919 | np->n_flag |= N_DONE; |
2798 | np->n_flag &= ~N_DOING; | 2920 | np->n_flag &= ~N_DOING; |
@@ -2801,7 +2923,8 @@ make(struct name *np, int level) | |||
2801 | ((np->n_flag & N_PHONY) || (timespec_le(&np->n_tim, &dtim)))) { | 2923 | ((np->n_flag & N_PHONY) || (timespec_le(&np->n_tim, &dtim)))) { |
2802 | if (!(estat & MAKE_FAILURE)) { | 2924 | if (!(estat & MAKE_FAILURE)) { |
2803 | if (sc_cmd) | 2925 | if (sc_cmd) |
2804 | estat |= make1(np, sc_cmd, oodate, allsrc, dedup, impdep); | 2926 | estat |= make1(np, sc_cmd, oodate, allsrc, dedup, |
2927 | impdep, tsuff); | ||
2805 | else if (!doinclude && level == 0 && !(estat & MAKE_DIDSOMETHING)) | 2928 | else if (!doinclude && level == 0 && !(estat & MAKE_DIDSOMETHING)) |
2806 | warning("nothing to be done for %s", np->n_name); | 2929 | warning("nothing to be done for %s", np->n_name); |
2807 | } else if (!doinclude && !quest) { | 2930 | } else if (!doinclude && !quest) { |