posix1.mk revision 1.4 1 # $NetBSD: posix1.mk,v 1.4 2020/08/10 18:19:58 rillig Exp $
2
3 # Keep the default suffixes from interfering, just in case.
4 .SUFFIXES:
5
6 all: line-continuations suffix-substitution localvars
7
8 # we need to clean for repeatable results
9 .BEGIN: clean
10 clean:
11 @rm -f lib.a dir/* dummy obj*
12 .END:
13 @rm -f lib.a dir/* dummy obj*
14
15 #
16 # Line continuations
17 #
18
19 # Escaped newlines and leading whitespace from the next line are replaced
20 # with single space, except in commands, where the escape and the newline
21 # are retained, but a single leading tab (if any) from the next line is
22 # removed. (PR 49085)
23 # Expect:
24 # ${VAR} = "foo bar baz"
25 # a
26 # b
27 # c
28 VAR = foo\
29 \
30 bar\
31 baz
32
33 line-continuations:
34 @echo '$${VAR} = "${VAR}"'
35 @echo 'aXbXc' | sed -e 's/X/\
36 /g'
37
38
39 #
40 # Suffix substitution
41 #
42
43 # The only variable modifier accepted by POSIX.
44 # ${VAR:s1=s2}: replace s1, if found, with s2 at end of each word in
45 # ${VAR}. s1 and s2 may contain macro expansions.
46 # Expect: foo baR baz, bar baz, foo bar baz, fooadd baradd bazadd
47 suffix-substitution:
48 @echo '${VAR:r=R}, ${VAR:foo=}, ${VAR:not_there=wrong}, ${VAR:=add}'
49
50
51 #
52 # Local variables: regular forms, D/F forms and suffix substitution.
53 #
54
55 # In the past substitutions did not work with the D/F forms and those
56 # forms were not available for $?. (PR 49085)
57
58 ARFLAGS = -rcv
59
60 localvars: lib.a
61
62 # $@ = target or archive name $< = implied source
63 # $* = target without suffix $? = sources newer than target
64 # $% = archive member name
65 LOCALS = \
66 "Local variables\n\
67 \$${@}=\"${@}\" \$${<}=\"${<}\"\n\
68 \$${*}=\"${*}\" \$${?}=\"${?}\"\n\
69 \$${%%}=\"${%}\"\n\n"
70
71 # $XD = directory part of X $XF = file part of X
72 # X is one of the local variables.
73 LOCAL_ALTERNATIVES = \
74 "Directory and filename parts of local variables\n\
75 \$${@D}=\"${@D}\" \$${@F}=\"${@F}\"\n\
76 \$${<D}=\"${<D}\" \$${<F}=\"${<F}\"\n\
77 \$${*D}=\"${*D}\" \$${*F}=\"${*F}\"\n\
78 \$${?D}=\"${?D}\" \$${?F}=\"${?F}\"\n\
79 \$${%%D}=\"${%D}\" \$${%%F}=\"${%F}\"\n\n"
80
81 # Do all kinds of meaningless substitutions on local variables to see
82 # if they work. Add, remove and replace things.
83 VAR2 = .o
84 VAR3 = foo
85 LOCAL_SUBSTITUTIONS = \
86 "Local variable substitutions\n\
87 \$${@:.o=}=\"${@:.o=}\" \$${<:.c=.C}=\"${<:.c=.C}\"\n\
88 \$${*:=.h}=\"${*:=.h}\" \$${?:.h=.H}=\"${?:.h=.H}\"\n\
89 \$${%%:=}=\"${%:=}\"\n\n"
90
91 LOCAL_ALTERNATIVE_SUBSTITUTIONS = \
92 "Target with suffix transformations\n\
93 \$${@D:=append}=\"${@D:=append}\"\n\
94 \$${@F:.o=.O}=\"${@F:.o=.O}\"\n\
95 \n\
96 Implied source with suffix transformations\n\
97 \$${<D:r=rr}=\"${<D:r=rr}\"\n\
98 \$${<F:.c=.C}=\"${<F:.c=.C}\"\n\
99 \n\
100 Suffixless target with suffix transformations\n\
101 \$${*D:.=dot}=\"${*D:.=dot}\"\n\
102 \$${*F:.a=}=\"${*F:.a=}\"\n\
103 \n\
104 Out-of-date dependencies with suffix transformations\n\
105 \$${?D:ir=}=\"${?D:ir=}\"\n\
106 \$${?F:.h=.H}=\"${?F:.h=.H}\"\n\
107 \n\
108 Member with suffix transformations\n\
109 \$${%%D:.=}=\"${%D:.=}\"\n\
110 \$${%%F:\$${VAR2}=\$${VAR}}=\"${%F:${VAR2}=${VAR}}\"\n\n"
111
112 .SUFFIXES: .c .o .a
113
114 # The system makefiles make the .c.a rule .PRECIOUS with a special source,
115 # but such a thing is not POSIX compatible. It's also somewhat useless
116 # in a test makefile.
117 .c.a:
118 @printf ${LOCALS}
119 @printf ${LOCAL_ALTERNATIVES}
120 @printf ${LOCAL_SUBSTITUTIONS}
121 @printf ${LOCAL_ALTERNATIVE_SUBSTITUTIONS}
122 cc -c -o '${%}' '${<}'
123 ar ${ARFLAGS} '${@}' '${%}'
124 rm -f '${%}'
125
126 .c.o:
127 @printf ${LOCALS}
128 @printf ${LOCAL_ALTERNATIVES}
129 @printf ${LOCAL_SUBSTITUTIONS}
130 @printf ${LOCAL_ALTERNATIVE_SUBSTITUTIONS}
131 cc -c -o '${@}' '${<}'
132
133 # Some of these rules are padded with useless extra dependencies just so
134 # that ${?} has more than one file.
135
136 lib.a: lib.a(obj1.o) lib.a(obj2.o) lib.a(obj3.o)
137 ar -s '${@}'
138
139 # Explicit rule where the dependency is an inferred file. The dependency
140 # object's name differs from the member's because there was a bug which
141 # forced a dependency on member even when no such dependency was specified
142 # (PR 49086).
143 lib.a(obj1.o): dir/obj_1.o dummy
144 @printf ${LOCALS}
145 @printf ${LOCAL_ALTERNATIVES}
146 @printf ${LOCAL_SUBSTITUTIONS}
147 @printf ${LOCAL_ALTERNATIVE_SUBSTITUTIONS}
148 cp 'dir/obj_1.o' '$%'
149 ar ${ARFLAGS} '${@}' '$%'
150 rm -f '$%'
151
152 # Excplicit rule where the dependency also has an explicit rule.
153 lib.a(obj2.o): obj2.o
154 ar ${ARFLAGS} '${@}' '${%}'
155
156 # Use .c.a inference with an extra dependency.
157 lib.a(obj3.o): obj3.h dir/dummy
158
159 # Use .c.o inference with an extra dependency.
160 dir/obj_1.o: dir/obj_1.h
161
162 # According to POSIX, $* is only required for inference rules and $<'s
163 # value is unspecified outside of inference rules. Strictly speaking
164 # we shouldn't be expanding them here but who cares. At least we get
165 # to check that the program does nothing stupid (like crash) with them.
166 # The C file is named differently from the object file because there
167 # was a bug which forced dependencies based on inference rules on all
168 # applicable targets (PR 49086).
169 obj2.o: obj_2.c obj_2.h dir/obj_1.h
170 @printf ${LOCALS}
171 @printf ${LOCAL_ALTERNATIVES}
172 @printf ${LOCAL_SUBSTITUTIONS}
173 @printf ${LOCAL_ALTERNATIVE_SUBSTITUTIONS}
174 cc -c -o '${@}' 'obj_2.c'
175
176 # Hey, this is make, we can make our own test data setup! obj1.c
177 # and obj2.c are not used, so they should not get created. They're here
178 # as a bait for a regression into the forced dependencies discussed earlier.
179 obj1.c dir/obj_1.c obj2.c obj_2.c obj3.c:
180 mkdir -p '${@D}'
181 printf '#include "${@F:.c=.h}"\nconst char* ${@F:.c=} = "${@}";\n' \
182 >'${@}'
183
184 dir/obj_1.h obj_2.h obj3.h dummy dir/dummy:
185 mkdir -p '${@D}'
186 touch '${@}'
187