xref: /freebsd/contrib/bmake/unit-tests/posix1.mk (revision d7d962ead0b6e5e8a39202d0590022082bf5bfb6)
1# $NetBSD: posix1.mk,v 1.6 2020/10/24 08:50:17 rillig Exp $
2
3# Keep the default suffixes from interfering, just in case.
4.SUFFIXES:
5
6all:	line-continuations suffix-substitution localvars
7
8# we need to clean for repeatable results
9.BEGIN: clean
10clean:
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
28VAR = foo\
29\
30	  bar\
31 baz
32
33line-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
47suffix-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
58ARFLAGS=	-rcv
59
60localvars: lib.a
61
62# $@ = target or archive name	$< = implied source
63# $* = target without suffix	$? = sources newer than target
64# $% = archive member name
65LOCALS= \
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.
73LOCAL_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.
83VAR2=	.o
84VAR3=	foo
85LOCAL_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
91LOCAL_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
136lib.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).
143lib.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.
153lib.a(obj2.o): obj2.o
154	ar ${ARFLAGS} '${@}' '${%}'
155
156# Use .c.a inference with an extra dependency.
157lib.a(obj3.o): obj3.h dir/dummy
158
159# Use .c.o inference with an extra dependency.
160dir/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).
169obj2.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.
179obj1.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
184dir/obj_1.h obj_2.h obj3.h dummy dir/dummy:
185	mkdir -p '${@D}'
186	touch '${@}'
187