diff options
Diffstat (limited to '')
-rw-r--r-- | miscutils/make.c | 316 |
1 files changed, 237 insertions, 79 deletions
diff --git a/miscutils/make.c b/miscutils/make.c index 7316408bf..a165274aa 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. |
@@ -469,8 +471,7 @@ newcmd(struct cmd **cphead, char *str) | |||
469 | /*(*cphead)->c_next = NULL; - xzalloc did it */ | 471 | /*(*cphead)->c_next = NULL; - xzalloc did it */ |
470 | (*cphead)->c_cmd = xstrdup(str); | 472 | (*cphead)->c_cmd = xstrdup(str); |
471 | /*(*cphead)->c_refcnt = 0; */ | 473 | /*(*cphead)->c_refcnt = 0; */ |
472 | if (makefile) | 474 | (*cphead)->c_makefile = xstrdup(makefile); |
473 | (*cphead)->c_makefile = xstrdup(makefile); | ||
474 | (*cphead)->c_dispno = dispno; | 475 | (*cphead)->c_dispno = dispno; |
475 | } | 476 | } |
476 | 477 | ||
@@ -993,38 +994,27 @@ suffix(const char *name) | |||
993 | } | 994 | } |
994 | 995 | ||
995 | /* | 996 | /* |
996 | * Dynamic dependency. This routine applies the suffix rules | 997 | * 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 | 998 | * to the target suffix 'tsuff'. The basename of the prerequisite |
998 | * target. NULL is returned on failure. On success the name of | 999 | * is 'base'. |
999 | * the implicit prerequisite is returned and the details are | ||
1000 | * placed in the imprule structure provided by the caller. | ||
1001 | */ | 1000 | */ |
1002 | static struct name * | 1001 | static struct name * |
1003 | dyndep(struct name *np, struct rule *imprule) | 1002 | dyndep0(char *base, const char *tsuff, struct rule *infrule) |
1004 | { | 1003 | { |
1005 | char *suff, *newsuff; | 1004 | char *psuff; |
1006 | char *base, *name, *member; | ||
1007 | struct name *xp; // Suffixes | 1005 | struct name *xp; // Suffixes |
1008 | struct name *sp; // Suffix rule | 1006 | struct name *sp; // Suffix rule |
1009 | struct name *pp = NULL; // Implicit prerequisite | ||
1010 | struct rule *rp; | 1007 | struct rule *rp; |
1011 | struct depend *dp; | 1008 | struct depend *dp; |
1012 | bool chain = FALSE; | 1009 | bool chain = FALSE; |
1013 | 1010 | ||
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"); | 1011 | xp = newname(".SUFFIXES"); |
1022 | retry: | 1012 | retry: |
1023 | for (rp = xp->n_rule; rp; rp = rp->r_next) { | 1013 | for (rp = xp->n_rule; rp; rp = rp->r_next) { |
1024 | for (dp = rp->r_dep; dp; dp = dp->d_next) { | 1014 | for (dp = rp->r_dep; dp; dp = dp->d_next) { |
1025 | // Generate new suffix rule to try | 1015 | // Generate new suffix rule to try |
1026 | newsuff = dp->d_name->n_name; | 1016 | psuff = dp->d_name->n_name; |
1027 | sp = findname(auto_concat(newsuff, suff)); | 1017 | sp = findname(auto_concat(psuff, tsuff)); |
1028 | if (sp && sp->n_rule) { | 1018 | if (sp && sp->n_rule) { |
1029 | struct name *ip; | 1019 | struct name *ip; |
1030 | int got_ip; | 1020 | int got_ip; |
@@ -1032,9 +1022,8 @@ dyndep(struct name *np, struct rule *imprule) | |||
1032 | // Has rule already been used in this chain? | 1022 | // Has rule already been used in this chain? |
1033 | if ((sp->n_flag & N_MARK)) | 1023 | if ((sp->n_flag & N_MARK)) |
1034 | continue; | 1024 | continue; |
1035 | |||
1036 | // Generate a name for an implicit prerequisite | 1025 | // Generate a name for an implicit prerequisite |
1037 | ip = newname(auto_concat(base, newsuff)); | 1026 | ip = newname(auto_concat(base, psuff)); |
1038 | if ((ip->n_flag & N_DOING)) | 1027 | if ((ip->n_flag & N_DOING)) |
1039 | continue; | 1028 | continue; |
1040 | 1029 | ||
@@ -1045,20 +1034,19 @@ dyndep(struct name *np, struct rule *imprule) | |||
1045 | got_ip = ip->n_tim.tv_sec || (ip->n_flag & N_TARGET); | 1034 | got_ip = ip->n_tim.tv_sec || (ip->n_flag & N_TARGET); |
1046 | } else { | 1035 | } else { |
1047 | sp->n_flag |= N_MARK; | 1036 | sp->n_flag |= N_MARK; |
1048 | got_ip = dyndep(ip, NULL) != NULL; | 1037 | got_ip = dyndep(ip, NULL, NULL) != NULL; |
1049 | sp->n_flag &= ~N_MARK; | 1038 | sp->n_flag &= ~N_MARK; |
1050 | } | 1039 | } |
1051 | 1040 | ||
1052 | if (got_ip) { | 1041 | if (got_ip) { |
1053 | // Prerequisite exists or we know how to make it | 1042 | // Prerequisite exists or we know how to make it |
1054 | if (imprule) { | 1043 | if (infrule) { |
1055 | dp = NULL; | 1044 | dp = NULL; |
1056 | newdep(&dp, ip); | 1045 | newdep(&dp, ip); |
1057 | imprule->r_dep = dp; | 1046 | infrule->r_dep = dp; |
1058 | imprule->r_cmd = sp->n_rule->r_cmd; | 1047 | infrule->r_cmd = sp->n_rule->r_cmd; |
1059 | } | 1048 | } |
1060 | pp = ip; | 1049 | return ip; |
1061 | goto finish; | ||
1062 | } | 1050 | } |
1063 | } | 1051 | } |
1064 | } | 1052 | } |
@@ -1069,9 +1057,87 @@ dyndep(struct name *np, struct rule *imprule) | |||
1069 | chain = TRUE; | 1057 | chain = TRUE; |
1070 | goto retry; | 1058 | goto retry; |
1071 | } | 1059 | } |
1072 | finish: | 1060 | return NULL; |
1073 | free(suff); | 1061 | } |
1062 | |||
1063 | /* | ||
1064 | * If 'name' ends with 'suffix' return an allocated string containing | ||
1065 | * the name with the suffix removed, else return NULL. | ||
1066 | */ | ||
1067 | static char * | ||
1068 | has_suffix(const char *name, const char *suffix) | ||
1069 | { | ||
1070 | ssize_t delta = strlen(name) - strlen(suffix); | ||
1071 | char *base = NULL; | ||
1072 | |||
1073 | if (delta > 0 && strcmp(name + delta, suffix) == 0) { | ||
1074 | base = xstrdup(name); | ||
1075 | base[delta] = '\0'; | ||
1076 | } | ||
1077 | |||
1078 | return base; | ||
1079 | } | ||
1080 | |||
1081 | /* | ||
1082 | * Dynamic dependency. This routine applies the suffix rules | ||
1083 | * to try and find a source and a set of rules for a missing | ||
1084 | * target. NULL is returned on failure. On success the name of | ||
1085 | * the implicit prerequisite is returned and the rule used is | ||
1086 | * placed in the infrule structure provided by the caller. | ||
1087 | */ | ||
1088 | static struct name * | ||
1089 | dyndep(struct name *np, struct rule *infrule, const char **ptsuff) | ||
1090 | { | ||
1091 | const char *tsuff; | ||
1092 | char *base, *name, *member; | ||
1093 | struct name *pp = NULL; // Implicit prerequisite | ||
1094 | |||
1095 | member = NULL; | ||
1096 | name = splitlib(np->n_name, &member); | ||
1097 | |||
1098 | // POSIX only allows inference rules with one or two periods. | ||
1099 | // As an extension this restriction is lifted, but not for | ||
1100 | // targets of the form lib.a(member.o). | ||
1101 | if (!posix && member == NULL) { | ||
1102 | struct name *xp = newname(".SUFFIXES"); | ||
1103 | int found_suffix = FALSE; | ||
1104 | |||
1105 | for (struct rule *rp = xp->n_rule; rp; rp = rp->r_next) { | ||
1106 | for (struct depend *dp = rp->r_dep; dp; dp = dp->d_next) { | ||
1107 | tsuff = dp->d_name->n_name; | ||
1108 | base = has_suffix(name, tsuff); | ||
1109 | if (base) { | ||
1110 | found_suffix = TRUE; | ||
1111 | pp = dyndep0(base, tsuff, infrule); | ||
1112 | free(base); | ||
1113 | if (pp) { | ||
1114 | goto done; | ||
1115 | } | ||
1116 | } | ||
1117 | } | ||
1118 | } | ||
1119 | |||
1120 | if (!found_suffix) { | ||
1121 | // The name didn't have a known suffix. Try single-suffix rule. | ||
1122 | tsuff = ""; | ||
1123 | pp = dyndep0(name, tsuff, infrule); | ||
1124 | if (pp) { | ||
1125 | done: | ||
1126 | if (ptsuff) { | ||
1127 | *ptsuff = tsuff; | ||
1128 | } | ||
1129 | } | ||
1130 | } | ||
1131 | } else { | ||
1132 | tsuff = xstrdup(suffix(name)); | ||
1133 | base = member ? member : name; | ||
1134 | *suffix(base) = '\0'; | ||
1135 | |||
1136 | pp = dyndep0(base, tsuff, infrule); | ||
1137 | free((void *)tsuff); | ||
1138 | } | ||
1074 | free(name); | 1139 | free(name); |
1140 | |||
1075 | return pp; | 1141 | return pp; |
1076 | } | 1142 | } |
1077 | 1143 | ||
@@ -1789,9 +1855,10 @@ readline(FILE *fd, int want_command) | |||
1789 | } | 1855 | } |
1790 | 1856 | ||
1791 | /* | 1857 | /* |
1792 | * Return TRUE if the argument is a known suffix. | 1858 | * Return a pointer to the suffix name if the argument is a known suffix |
1859 | * or NULL if it isn't. | ||
1793 | */ | 1860 | */ |
1794 | static int | 1861 | static const char * |
1795 | is_suffix(const char *s) | 1862 | is_suffix(const char *s) |
1796 | { | 1863 | { |
1797 | struct name *np; | 1864 | struct name *np; |
@@ -1802,7 +1869,39 @@ is_suffix(const char *s) | |||
1802 | for (rp = np->n_rule; rp; rp = rp->r_next) { | 1869 | for (rp = np->n_rule; rp; rp = rp->r_next) { |
1803 | for (dp = rp->r_dep; dp; dp = dp->d_next) { | 1870 | for (dp = rp->r_dep; dp; dp = dp->d_next) { |
1804 | if (strcmp(s, dp->d_name->n_name) == 0) { | 1871 | if (strcmp(s, dp->d_name->n_name) == 0) { |
1805 | return TRUE; | 1872 | return dp->d_name->n_name; |
1873 | } | ||
1874 | } | ||
1875 | } | ||
1876 | return NULL; | ||
1877 | } | ||
1878 | |||
1879 | /* | ||
1880 | * Return TRUE if the argument is formed by concatenating two | ||
1881 | * known suffixes. | ||
1882 | */ | ||
1883 | static int | ||
1884 | is_inference_target(const char *s) | ||
1885 | { | ||
1886 | struct name *np; | ||
1887 | struct rule *rp1, *rp2; | ||
1888 | struct depend *dp1, *dp2; | ||
1889 | |||
1890 | np = newname(".SUFFIXES"); | ||
1891 | for (rp1 = np->n_rule; rp1; rp1 = rp1->r_next) { | ||
1892 | for (dp1 = rp1->r_dep; dp1; dp1 = dp1->d_next) { | ||
1893 | const char *suff1 = dp1->d_name->n_name; | ||
1894 | size_t len = strlen(suff1); | ||
1895 | |||
1896 | if (strncmp(s, suff1, len) == 0) { | ||
1897 | for (rp2 = np->n_rule; rp2; rp2 = rp2->r_next) { | ||
1898 | for (dp2 = rp2->r_dep; dp2; dp2 = dp2->d_next) { | ||
1899 | const char *suff2 = dp2->d_name->n_name; | ||
1900 | if (strcmp(s + len, suff2) == 0) { | ||
1901 | return TRUE; | ||
1902 | } | ||
1903 | } | ||
1904 | } | ||
1806 | } | 1905 | } |
1807 | } | 1906 | } |
1808 | } | 1907 | } |
@@ -1824,7 +1923,6 @@ enum { | |||
1824 | static int | 1923 | static int |
1825 | target_type(char *s) | 1924 | target_type(char *s) |
1826 | { | 1925 | { |
1827 | char *sfx; | ||
1828 | int ret; | 1926 | int ret; |
1829 | static const char *s_name = | 1927 | static const char *s_name = |
1830 | ".DEFAULT\0" | 1928 | ".DEFAULT\0" |
@@ -1854,9 +1952,6 @@ target_type(char *s) | |||
1854 | T_SPECIAL, | 1952 | T_SPECIAL, |
1855 | }; | 1953 | }; |
1856 | 1954 | ||
1857 | if (*s != '.') | ||
1858 | return T_NORMAL; | ||
1859 | |||
1860 | // Check for one of the known special targets | 1955 | // Check for one of the known special targets |
1861 | ret = index_in_strings(s_name, s); | 1956 | ret = index_in_strings(s_name, s); |
1862 | if (ret >= 0) | 1957 | if (ret >= 0) |
@@ -1864,16 +1959,23 @@ target_type(char *s) | |||
1864 | 1959 | ||
1865 | // Check for an inference rule | 1960 | // Check for an inference rule |
1866 | ret = T_NORMAL; | 1961 | ret = T_NORMAL; |
1867 | sfx = suffix(s); | 1962 | if (!posix) { |
1868 | if (is_suffix(sfx)) { | 1963 | if (is_suffix(s) || is_inference_target(s)) { |
1869 | if (s == sfx) { // Single suffix rule | ||
1870 | ret = T_INFERENCE | T_NOPREREQ | T_COMMAND; | 1964 | ret = T_INFERENCE | T_NOPREREQ | T_COMMAND; |
1871 | } else { | 1965 | } |
1872 | // Suffix is valid, check that prefix is too | 1966 | } else { |
1873 | *sfx = '\0'; | 1967 | // In POSIX inference rule targets must contain one or two dots |
1874 | if (is_suffix(s)) | 1968 | char *sfx = suffix(s); |
1969 | if (*s == '.' && is_suffix(sfx)) { | ||
1970 | if (s == sfx) { // Single suffix rule | ||
1875 | ret = T_INFERENCE | T_NOPREREQ | T_COMMAND; | 1971 | ret = T_INFERENCE | T_NOPREREQ | T_COMMAND; |
1876 | *sfx = '.'; | 1972 | } else { |
1973 | // Suffix is valid, check that prefix is too | ||
1974 | *sfx = '\0'; | ||
1975 | if (is_suffix(s)) | ||
1976 | ret = T_INFERENCE | T_NOPREREQ | T_COMMAND; | ||
1977 | *sfx = '.'; | ||
1978 | } | ||
1877 | } | 1979 | } |
1878 | } | 1980 | } |
1879 | return ret; | 1981 | return ret; |
@@ -2069,6 +2171,20 @@ pragmas_from_env(void) | |||
2069 | #endif | 2171 | #endif |
2070 | 2172 | ||
2071 | /* | 2173 | /* |
2174 | * Determine if a line is a target rule with an inline command. | ||
2175 | * Return a pointer to the semicolon separator if it is, else NULL. | ||
2176 | */ | ||
2177 | static char * | ||
2178 | inline_command(char *line) | ||
2179 | { | ||
2180 | char *p = find_char(line, ':'); | ||
2181 | |||
2182 | if (p) | ||
2183 | p = strchr(p, ';'); | ||
2184 | return p; | ||
2185 | } | ||
2186 | |||
2187 | /* | ||
2072 | * Parse input from the makefile and construct a tree structure of it. | 2188 | * Parse input from the makefile and construct a tree structure of it. |
2073 | */ | 2189 | */ |
2074 | static void | 2190 | static void |
@@ -2287,9 +2403,9 @@ input(FILE *fd, int ilevel) | |||
2287 | cp = NULL; | 2403 | cp = NULL; |
2288 | s = strchr(q, ';'); | 2404 | s = strchr(q, ';'); |
2289 | if (s) { | 2405 | if (s) { |
2290 | // Retrieve command from expanded copy of line | 2406 | // Retrieve command from original or expanded copy of line |
2291 | char *copy3 = expand_macros(copy, FALSE); | 2407 | char *copy3 = expand_macros(copy, FALSE); |
2292 | if ((p = find_colon(copy3)) && (p = strchr(p, ';'))) | 2408 | if ((p = inline_command(copy)) || (p = inline_command(copy3))) |
2293 | newcmd(&cp, process_command(p + 1)); | 2409 | newcmd(&cp, process_command(p + 1)); |
2294 | free(copy3); | 2410 | free(copy3); |
2295 | *s = '\0'; | 2411 | *s = '\0'; |
@@ -2585,9 +2701,34 @@ docmds(struct name *np, struct cmd *cp) | |||
2585 | return estat; | 2701 | return estat; |
2586 | } | 2702 | } |
2587 | 2703 | ||
2704 | /* | ||
2705 | * Remove the suffix from a name, either the one provided in 'tsuff' | ||
2706 | * or, if 'tsuff' is NULL, one of the known suffixes. | ||
2707 | */ | ||
2708 | static char * | ||
2709 | remove_suffix(const char *name, const char *tsuff) | ||
2710 | { | ||
2711 | char *base = NULL; | ||
2712 | |||
2713 | if (tsuff != NULL) { | ||
2714 | base = has_suffix(name, tsuff); | ||
2715 | } else { | ||
2716 | struct name *xp = newname(".SUFFIXES"); | ||
2717 | for (struct rule *rp = xp->n_rule; rp; rp = rp->r_next) { | ||
2718 | for (struct depend *dp = rp->r_dep; dp; dp = dp->d_next) { | ||
2719 | base = has_suffix(name, dp->d_name->n_name); | ||
2720 | if (base) { | ||
2721 | return base; | ||
2722 | } | ||
2723 | } | ||
2724 | } | ||
2725 | } | ||
2726 | return base; | ||
2727 | } | ||
2728 | |||
2588 | static int | 2729 | static int |
2589 | make1(struct name *np, struct cmd *cp, char *oodate, char *allsrc, | 2730 | make1(struct name *np, struct cmd *cp, char *oodate, char *allsrc, |
2590 | char *dedup, struct name *implicit) | 2731 | char *dedup, struct name *implicit, const char *tsuff) |
2591 | { | 2732 | { |
2592 | char *name, *member = NULL, *base = NULL, *prereq = NULL; | 2733 | char *name, *member = NULL, *base = NULL, *prereq = NULL; |
2593 | 2734 | ||
@@ -2603,7 +2744,7 @@ make1(struct name *np, struct cmd *cp, char *oodate, char *allsrc, | |||
2603 | char *s; | 2744 | char *s; |
2604 | 2745 | ||
2605 | // As an extension, if we're not dealing with an implicit | 2746 | // As an extension, if we're not dealing with an implicit |
2606 | // rule set $< to the first out-of-date prerequisite. | 2747 | // prerequisite set $< to the first out-of-date prerequisite. |
2607 | if (implicit == NULL) { | 2748 | if (implicit == NULL) { |
2608 | if (oodate) { | 2749 | if (oodate) { |
2609 | s = strchr(oodate, ' '); | 2750 | s = strchr(oodate, ' '); |
@@ -2614,15 +2755,26 @@ make1(struct name *np, struct cmd *cp, char *oodate, char *allsrc, | |||
2614 | } else | 2755 | } else |
2615 | prereq = implicit->n_name; | 2756 | prereq = implicit->n_name; |
2616 | 2757 | ||
2617 | base = member ? member : name; | 2758 | if (!posix && member == NULL) { |
2618 | s = suffix(base); | 2759 | // As an extension remove a suffix that doesn't necessarily |
2619 | // As an extension, if we're not dealing with an implicit | 2760 | // start with a period from a target, but not for targets |
2620 | // rule and the target ends with a known suffix, remove it | 2761 | // of the form lib.a(member.o). |
2621 | // and set $* to the stem, else to an empty string. | 2762 | base = remove_suffix(name, tsuff); |
2622 | if (implicit == NULL && !is_suffix(s)) | 2763 | if (base) { |
2623 | base = NULL; | 2764 | free(name); |
2624 | else | 2765 | name = base; |
2625 | *s = '\0'; | 2766 | } |
2767 | } else { | ||
2768 | base = member ? member : name; | ||
2769 | s = suffix(base); | ||
2770 | // As an extension, if we're not dealing with an implicit | ||
2771 | // prerequisite and the target ends with a known suffix, | ||
2772 | // remove it and set $* to the stem, else to an empty string. | ||
2773 | if (implicit == NULL && !is_suffix(s)) | ||
2774 | base = NULL; | ||
2775 | else | ||
2776 | *s = '\0'; | ||
2777 | } | ||
2626 | } | 2778 | } |
2627 | setmacro("<", prereq, 0 | M_VALID); | 2779 | setmacro("<", prereq, 0 | M_VALID); |
2628 | setmacro("*", base, 0 | M_VALID); | 2780 | setmacro("*", base, 0 | M_VALID); |
@@ -2667,11 +2819,12 @@ make(struct name *np, int level) | |||
2667 | struct depend *dp; | 2819 | struct depend *dp; |
2668 | struct rule *rp; | 2820 | struct rule *rp; |
2669 | struct name *impdep = NULL; // implicit prerequisite | 2821 | struct name *impdep = NULL; // implicit prerequisite |
2670 | struct rule imprule; | 2822 | struct rule infrule; |
2671 | struct cmd *sc_cmd = NULL; // commands for single-colon rule | 2823 | struct cmd *sc_cmd = NULL; // commands for single-colon rule |
2672 | char *oodate = NULL; | 2824 | char *oodate = NULL; |
2673 | char *allsrc = NULL; | 2825 | char *allsrc = NULL; |
2674 | char *dedup = NULL; | 2826 | char *dedup = NULL; |
2827 | const char *tsuff = NULL; | ||
2675 | struct timespec dtim = {1, 0}; | 2828 | struct timespec dtim = {1, 0}; |
2676 | int estat = 0; | 2829 | int estat = 0; |
2677 | 2830 | ||
@@ -2690,10 +2843,10 @@ make(struct name *np, int level) | |||
2690 | // as an extension, not for phony targets) | 2843 | // as an extension, not for phony targets) |
2691 | sc_cmd = getcmd(np); | 2844 | sc_cmd = getcmd(np); |
2692 | if (!sc_cmd && (posix || !(np->n_flag & N_PHONY))) { | 2845 | if (!sc_cmd && (posix || !(np->n_flag & N_PHONY))) { |
2693 | impdep = dyndep(np, &imprule); | 2846 | impdep = dyndep(np, &infrule, &tsuff); |
2694 | if (impdep) { | 2847 | if (impdep) { |
2695 | sc_cmd = imprule.r_cmd; | 2848 | sc_cmd = infrule.r_cmd; |
2696 | addrule(np, imprule.r_dep, NULL, FALSE); | 2849 | addrule(np, infrule.r_dep, NULL, FALSE); |
2697 | } | 2850 | } |
2698 | } | 2851 | } |
2699 | 2852 | ||
@@ -2708,14 +2861,15 @@ make(struct name *np, int level) | |||
2708 | } | 2861 | } |
2709 | impdep = np; | 2862 | impdep = np; |
2710 | } | 2863 | } |
2711 | } | 2864 | } else { |
2712 | else { | ||
2713 | // If any double-colon rule has no commands we need | 2865 | // If any double-colon rule has no commands we need |
2714 | // an inference rule (but, as an extension, not for phony targets) | 2866 | // an inference rule. |
2715 | for (rp = np->n_rule; rp; rp = rp->r_next) { | 2867 | for (rp = np->n_rule; rp; rp = rp->r_next) { |
2716 | if (!rp->r_cmd) { | 2868 | if (!rp->r_cmd) { |
2717 | if (posix || !(np->n_flag & N_PHONY)) | 2869 | // Phony targets don't need an inference rule. |
2718 | impdep = dyndep(np, &imprule); | 2870 | if (!posix && (np->n_flag & N_PHONY)) |
2871 | continue; | ||
2872 | impdep = dyndep(np, &infrule, &tsuff); | ||
2719 | if (!impdep) { | 2873 | if (!impdep) { |
2720 | if (doinclude) | 2874 | if (doinclude) |
2721 | return 1; | 2875 | return 1; |
@@ -2741,11 +2895,14 @@ make(struct name *np, int level) | |||
2741 | // Each double-colon rule is handled separately. | 2895 | // Each double-colon rule is handled separately. |
2742 | if ((np->n_flag & N_DOUBLE)) { | 2896 | if ((np->n_flag & N_DOUBLE)) { |
2743 | // If the rule has no commands use the inference rule. | 2897 | // If the rule has no commands use the inference rule. |
2898 | // Unless there isn't one, as allowed for phony targets. | ||
2744 | if (!rp->r_cmd) { | 2899 | if (!rp->r_cmd) { |
2745 | locdep = impdep; | 2900 | if (impdep) { |
2746 | imprule.r_dep->d_next = rp->r_dep; | 2901 | locdep = impdep; |
2747 | rp->r_dep = imprule.r_dep; | 2902 | infrule.r_dep->d_next = rp->r_dep; |
2748 | rp->r_cmd = imprule.r_cmd; | 2903 | rp->r_dep = infrule.r_dep; |
2904 | rp->r_cmd = infrule.r_cmd; | ||
2905 | } | ||
2749 | } | 2906 | } |
2750 | // A rule with no prerequisities is executed unconditionally. | 2907 | // A rule with no prerequisities is executed unconditionally. |
2751 | if (!rp->r_dep) | 2908 | if (!rp->r_dep) |
@@ -2776,7 +2933,7 @@ make(struct name *np, int level) | |||
2776 | if (((np->n_flag & N_PHONY) || timespec_le(&np->n_tim, &dtim))) { | 2933 | if (((np->n_flag & N_PHONY) || timespec_le(&np->n_tim, &dtim))) { |
2777 | if (!(estat & MAKE_FAILURE)) { | 2934 | if (!(estat & MAKE_FAILURE)) { |
2778 | estat |= make1(np, rp->r_cmd, oodate, allsrc, | 2935 | estat |= make1(np, rp->r_cmd, oodate, allsrc, |
2779 | dedup, locdep); | 2936 | dedup, locdep, tsuff); |
2780 | dtim = (struct timespec){1, 0}; | 2937 | dtim = (struct timespec){1, 0}; |
2781 | } | 2938 | } |
2782 | free(oodate); | 2939 | free(oodate); |
@@ -2792,7 +2949,7 @@ make(struct name *np, int level) | |||
2792 | } | 2949 | } |
2793 | } | 2950 | } |
2794 | if ((np->n_flag & N_DOUBLE) && impdep) | 2951 | if ((np->n_flag & N_DOUBLE) && impdep) |
2795 | free(imprule.r_dep); | 2952 | free(infrule.r_dep); |
2796 | 2953 | ||
2797 | np->n_flag |= N_DONE; | 2954 | np->n_flag |= N_DONE; |
2798 | np->n_flag &= ~N_DOING; | 2955 | np->n_flag &= ~N_DOING; |
@@ -2801,7 +2958,8 @@ make(struct name *np, int level) | |||
2801 | ((np->n_flag & N_PHONY) || (timespec_le(&np->n_tim, &dtim)))) { | 2958 | ((np->n_flag & N_PHONY) || (timespec_le(&np->n_tim, &dtim)))) { |
2802 | if (!(estat & MAKE_FAILURE)) { | 2959 | if (!(estat & MAKE_FAILURE)) { |
2803 | if (sc_cmd) | 2960 | if (sc_cmd) |
2804 | estat |= make1(np, sc_cmd, oodate, allsrc, dedup, impdep); | 2961 | estat |= make1(np, sc_cmd, oodate, allsrc, dedup, |
2962 | impdep, tsuff); | ||
2805 | else if (!doinclude && level == 0 && !(estat & MAKE_DIDSOMETHING)) | 2963 | else if (!doinclude && level == 0 && !(estat & MAKE_DIDSOMETHING)) |
2806 | warning("nothing to be done for %s", np->n_name); | 2964 | warning("nothing to be done for %s", np->n_name); |
2807 | } else if (!doinclude && !quest) { | 2965 | } else if (!doinclude && !quest) { |