1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
|
# $NetBSD: Makefile,v 1.119 2021/12/12 10:53:37 rillig Exp $
# @(#)Makefile 5.2 (Berkeley) 12/28/90
PROG= make
SRCS= arch.c
SRCS+= buf.c
SRCS+= compat.c
SRCS+= cond.c
SRCS+= dir.c
SRCS+= for.c
SRCS+= hash.c
SRCS+= job.c
SRCS+= lst.c
SRCS+= main.c
SRCS+= make.c
SRCS+= make_malloc.c
SRCS+= metachar.c
SRCS+= parse.c
SRCS+= str.c
SRCS+= suff.c
SRCS+= targ.c
SRCS+= trace.c
SRCS+= var.c
SRCS+= util.c
# Whether to generate a coverage report after running the tests.
USE_COVERAGE?= no # works only with gcc; clang9 fails to link
.if ${USE_COVERAGE} == "yes"
GCOV?= gcov
COPTS+= --coverage -O0 -ggdb
GCOV_PERL= if (/^File '(?:.*\/)?(\S+)'/) {
GCOV_PERL+= $$file = $$1; $$func = "";
GCOV_PERL+= } elsif (/^Function '(\S+)'/) {
GCOV_PERL+= $$func = $$1;
GCOV_PERL+= } elsif (/^Lines executed:(\d+\.\d+)% of (\d+)/ && defined($$file)) {
GCOV_PERL+= my ($$percent, $$lines) = ($$1, $$2);
GCOV_PERL+= my $$uncovered =
GCOV_PERL+= $$percent eq '100.00' ? '0'
GCOV_PERL+= : $$file =~ /\.h$$/ ? '?'
GCOV_PERL+= : `grep -c '\#\#\#\#\#:' < \$$(basename $$file.gcov)`;
GCOV_PERL+= chomp($$uncovered);
GCOV_PERL+= printf("%7.2f %4s/%4d %s%s\n",
GCOV_PERL+= $$percent, $$uncovered, $$lines, $$file, $$func);
GCOV_PERL+= $$file = undef;
GCOV_PERL+= }
LDADD+= --coverage
.endif
CLEANFILES+= *.gcda *.gcno *.gcov
# Whether to compile using the Undefined Behavior Sanitizer (GCC, Clang).
USE_UBSAN?= no
.if ${USE_UBSAN} == "yes"
COPTS+= -fsanitize=undefined
LDADD+= -fsanitize=undefined
.endif
# Whether to compile with GCC 10 from pkgsrc, during development.
USE_GCC10?= no
.if ${USE_GCC10} == "yes"
# CC is set further down in this file
COPTS+= -Wno-attributes # for abs and labs
COPTS.arch.c+= -Wno-error=format-truncation
COPTS.dir.c+= -Wno-error=format-truncation
COPTS.main.c+= -Wno-error=format-truncation
COPTS.meta.c+= -Wno-error=format-truncation
.endif
# Whether to compile with GCC 9 from pkgsrc, during development.
USE_GCC9?= no
.if ${USE_GCC9} == "yes"
# CC is set further down in this file
COPTS+= -Wno-attributes # for abs and labs
COPTS.arch.c+= -Wno-error=format-truncation
COPTS.dir.c+= -Wno-error=format-truncation
COPTS.main.c+= -Wno-error=format-truncation
COPTS.meta.c+= -Wno-error=format-truncation
.endif
# Whether to compile with GCC 8 from pkgsrc, during development.
USE_GCC8?= no
.if ${USE_GCC8} == "yes"
# CC is set further down in this file
COPTS+= -Wno-attributes # for abs and labs
COPTS.arch.c+= -Wno-error=format-truncation
COPTS.dir.c+= -Wno-error=format-truncation
COPTS.main.c+= -Wno-error=format-truncation
COPTS.meta.c+= -Wno-error=format-truncation
.endif
USE_META?= yes
.if ${USE_META:tl} != "no"
SRCS+= meta.c
CPPFLAGS+= -DUSE_META
USE_FILEMON?= ktrace
. if ${USE_FILEMON:tl} != "no"
.PATH: ${.CURDIR}/filemon
SRCS+= filemon_${USE_FILEMON}.c
CPPFLAGS+= -DUSE_FILEMON
CPPFLAGS+= -DUSE_FILEMON_${USE_FILEMON:tu}
. if ${USE_FILEMON} == "dev"
FILEMON_H?= /usr/include/dev/filemon/filemon.h
. if exists(${FILEMON_H}) && ${FILEMON_H:T} == "filemon.h"
COPTS.filemon_dev.c+= \
-DHAVE_FILEMON_H -I${FILEMON_H:H}
. endif
. endif
. endif
.endif
SUBDIR.roff+= PSD.doc
.if make(obj) || make(clean)
SUBDIR+= unit-tests
.endif
LINTFLAGS+= -T # strict bool mode, available since 2021-01-11
LINTFLAGS+= -w # treat warnings as errors
CLEANFILES+= *.o # for filemon objects
COPTS.arch.c+= ${GCC_NO_FORMAT_TRUNCATION}
COPTS.dir.c+= ${GCC_NO_FORMAT_TRUNCATION}
COPTS.job.c+= -Wno-format-nonliteral
COPTS.main.c+= ${GCC_NO_FORMAT_TRUNCATION} ${GCC_NO_STRINGOP_TRUNCATION}
COPTS.meta.c+= ${GCC_NO_FORMAT_TRUNCATION}
COPTS.parse.c+= -Wno-format-nonliteral
COPTS.var.c+= -Wno-format-nonliteral
CPPFLAGS+= -DMAKE_NATIVE
.if ${USE_GCC10} == "yes"
GCC10BASE?= /usr/pkg/gcc10
LATE_CC= ${GCC10BASE}/bin/gcc
GCOV= ${GCC10BASE}/bin/gcov
.endif
.if ${USE_GCC9} == "yes"
GCC9BASE?= /usr/pkg/gcc9
LATE_CC= ${GCC9BASE}/bin/gcc
GCOV= ${GCC9BASE}/bin/gcov
.endif
.if ${USE_GCC8} == "yes"
GCC8BASE?= /usr/pkg/gcc8
LATE_CC= ${GCC8BASE}/bin/gcc
GCOV= ${GCC8BASE}/bin/gcov
.endif
.if defined(TOOLDIR)
# This is a native NetBSD build, use libutil rather than the local emalloc etc.
CPPFLAGS+= -DUSE_EMALLOC
LDADD+= -lutil
DPADD+= ${LIBUTIL}
.endif
COPTS+= -Wdeclaration-after-statement
# A simple unit-test driver to help catch regressions
TEST_MAKE ?= ${.OBJDIR}/${PROG:T}
test: .MAKE
cd ${.CURDIR}/unit-tests \
&& MAKEFLAGS= ${TEST_MAKE} -r -m / TEST_MAKE=${TEST_MAKE} ${TESTS:DTESTS=${TESTS:Q}} ${.TARGET}
.if ${USE_COVERAGE} == yes
${MAKE} report-coverage
.endif
accept sync-mi: .MAKE
cd ${.CURDIR}/unit-tests && ${.MAKE} ${.TARGET}
retest:
${.MAKE} -C ${.CURDIR}/unit-tests cleandir
.if ${USE_COVERAGE} == yes
rm -f *.gcov *.gcda
.endif
${.MAKE} test
# Just out of curiosity, during development.
.SUFFIXES: .cpre .casm
.c.cpre:
${COMPILE.c:S,^-c$,-E,} ${COPTS.${.IMPSRC}} ${.IMPSRC} -o ${.TARGET}
.c.casm:
${COMPILE.c:S,^-c$,-S,} ${COPTS.${.IMPSRC}} ${.IMPSRC} -o ${.TARGET}
test-coverage: .PHONY
@make -s clean cleandir
@env USE_COVERAGE=yes COPTS="-O0 -ggdb" USER_CPPFLAGS="-DCLEANUP" \
sh -c 'make -s all -j8 && make -s test'
.if ${USE_COVERAGE} == "yes"
report-coverage: .PHONY
@echo 'covered uncovered file'
@${GCOV} ${GCOV_OPTS} *.gcda \
| perl -ne ${GCOV_PERL:Q} \
| sort -nr
@sed -i 's,^\([^:]*\): *[0-9]*:,\1: ,' *.gcov
.endif
.include <bsd.prog.mk>
.include <bsd.subdir.mk>
# For -DCLEANUP and similar feature toggles.
CPPFLAGS+= ${USER_CPPFLAGS}
# For overriding -std=gnu99 or similar options.
CFLAGS+= ${USER_CFLAGS}
.if defined(LATE_CC)
CC= ${LATE_CC}
.endif
|