aboutsummaryrefslogtreecommitdiff
path: root/miscutils/make.c
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2024-10-17 11:27:35 +0100
committerRon Yorston <rmy@pobox.com>2024-10-17 11:27:35 +0100
commit030d8f8ea9d4c2a896efad2b327a3308f7fd8c1b (patch)
treec69d60d369f0f590d8d052ba175fe3721bb97d4b /miscutils/make.c
parent4f13a5c9ea4994bd44ff91d3a6200113f863977b (diff)
downloadbusybox-w32-030d8f8ea9d4c2a896efad2b327a3308f7fd8c1b.tar.gz
busybox-w32-030d8f8ea9d4c2a896efad2b327a3308f7fd8c1b.tar.bz2
busybox-w32-030d8f8ea9d4c2a896efad2b327a3308f7fd8c1b.zip
make: improve chaining of implicit rules
Running 'make thing.z' with the following makefile: .SUFFIXES: .x .y .z .x.y: cp $< $@ .y.x: cp $< $@ .y.z: cp $< $@ resulted in infinite recursion and a segfault. Follow GNU make and don't allow any implicit rule to appear more than once in a chain. Adds 16-32 bytes.
Diffstat (limited to 'miscutils/make.c')
-rw-r--r--miscutils/make.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/miscutils/make.c b/miscutils/make.c
index 868cab5e2..4a8643a83 100644
--- a/miscutils/make.c
+++ b/miscutils/make.c
@@ -1016,14 +1016,30 @@ dyndep(struct name *np, struct rule *imprule)
1016 newsuff = dp->d_name->n_name; 1016 newsuff = dp->d_name->n_name;
1017 sp = findname(auto_concat(newsuff, suff)); 1017 sp = findname(auto_concat(newsuff, suff));
1018 if (sp && sp->n_rule) { 1018 if (sp && sp->n_rule) {
1019 struct name *ip;
1020 int got_ip;
1021
1022 // Has rule already been used in this chain?
1023 if ((sp->n_flag & N_MARK))
1024 continue;
1025
1019 // Generate a name for an implicit prerequisite 1026 // Generate a name for an implicit prerequisite
1020 struct name *ip = newname(auto_concat(base, newsuff)); 1027 ip = newname(auto_concat(base, newsuff));
1021 if ((ip->n_flag & N_DOING)) 1028 if ((ip->n_flag & N_DOING))
1022 continue; 1029 continue;
1030
1023 if (!ip->n_tim.tv_sec) 1031 if (!ip->n_tim.tv_sec)
1024 modtime(ip); 1032 modtime(ip);
1025 if (!chain ? ip->n_tim.tv_sec || (ip->n_flag & N_TARGET) : 1033
1026 dyndep(ip, NULL) != NULL) { 1034 if (!chain) {
1035 got_ip = ip->n_tim.tv_sec || (ip->n_flag & N_TARGET);
1036 } else {
1037 sp->n_flag |= N_MARK;
1038 got_ip = dyndep(ip, NULL) != NULL;
1039 sp->n_flag &= ~N_MARK;
1040 }
1041
1042 if (got_ip) {
1027 // Prerequisite exists or we know how to make it 1043 // Prerequisite exists or we know how to make it
1028 if (imprule) { 1044 if (imprule) {
1029 dp = NULL; 1045 dp = NULL;