xref: /freebsd-13-stable/share/mk/bsd.sys.mk (revision da72456591eee5b6bea590080a05f593b118a6a9)
1#
2# This file contains common settings used for building FreeBSD
3# sources.
4
5# Enable various levels of compiler warning checks.  These may be
6# overridden (e.g. if using a non-gcc compiler) by defining MK_WARNS=no.
7
8# for GCC:   https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
9# for clang: https://clang.llvm.org/docs/DiagnosticsReference.html
10
11.include <bsd.compiler.mk>
12
13# the default is gnu99 for now
14CSTD?=		gnu99
15
16.if ${CSTD} == "c89" || ${CSTD} == "c90"
17CFLAGS+=	-std=iso9899:1990
18.elif ${CSTD} == "c94" || ${CSTD} == "c95"
19CFLAGS+=	-std=iso9899:199409
20.elif ${CSTD} == "c99"
21CFLAGS+=	-std=iso9899:1999
22.else # CSTD
23CFLAGS+=	-std=${CSTD}
24.endif # CSTD
25
26.if !empty(CXXSTD)
27CXXFLAGS+=	-std=${CXXSTD}
28.endif
29
30# This gives the Makefile we're evaluating at the top-level a chance to set
31# WARNS.  If it doesn't do so, we may freely pull a DEFAULTWARNS if it's set
32# and use that.  This allows us to default WARNS to 6 for src builds without
33# needing to set the default in various Makefile.inc.
34.if !defined(WARNS) && defined(DEFAULTWARNS)
35WARNS=	${DEFAULTWARNS}
36.endif
37
38# -pedantic is problematic because it also imposes namespace restrictions
39#CFLAGS+=	-pedantic
40.if defined(WARNS)
41.if ${WARNS} >= 1
42CWARNFLAGS+=	-Wsystem-headers
43.if ${MK_WERROR} != "no" && ${MK_WERROR.${COMPILER_TYPE}:Uyes} != "no"
44CWARNFLAGS+=	-Werror
45.endif # ${MK_WERROR} != "no" && ${MK_WERROR.${COMPILER_TYPE}:Uyes} != "no"
46.endif # WARNS >= 1
47.if ${WARNS} >= 2
48CWARNFLAGS+=	-Wall -Wno-format-y2k
49.endif # WARNS >= 2
50.if ${WARNS} >= 3
51CWARNFLAGS+=	-W -Wno-unused-parameter
52.if ${COMPILER_TYPE} == "clang" && ${COMPILER_VERSION} < 150000
53CWARNFLAGS+=	-Wstrict-prototypes
54.endif
55CWARNFLAGS+=	-Wmissing-prototypes -Wpointer-arith
56.endif # WARNS >= 3
57.if ${WARNS} >= 4
58CWARNFLAGS+=	-Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wshadow\
59		-Wunused-parameter
60.if !defined(NO_WCAST_ALIGN) && !defined(NO_WCAST_ALIGN.${COMPILER_TYPE})
61CWARNFLAGS+=	-Wcast-align
62.endif # !NO_WCAST_ALIGN !NO_WCAST_ALIGN.${COMPILER_TYPE}
63.endif # WARNS >= 4
64.if ${WARNS} >= 5
65.if ${COMPILER_TYPE} == "clang" && ${COMPILER_VERSION} >= 150000
66CWARNFLAGS+=	-Wstrict-prototypes
67.endif
68.endif # WARNS >= 4
69.if ${WARNS} >= 6
70CWARNFLAGS+=	-Wchar-subscripts -Wnested-externs \
71		-Wold-style-definition
72.if !defined(NO_WMISSING_VARIABLE_DECLARATIONS)
73CWARNFLAGS.clang+=	-Wmissing-variable-declarations
74.endif
75.if !defined(NO_WTHREAD_SAFETY)
76CWARNFLAGS.clang+=	-Wthread-safety
77.endif
78.endif # WARNS >= 6
79.if ${WARNS} >= 2 && ${WARNS} <= 4
80# XXX Delete -Wuninitialized by default for now -- the compiler doesn't
81# XXX always get it right.
82CWARNFLAGS+=	-Wno-uninitialized
83.endif # WARNS >=2 && WARNS <= 4
84CWARNFLAGS+=	-Wno-pointer-sign
85# Clang has more warnings enabled by default, and when using -Wall, so if WARNS
86# is set to low values, these have to be disabled explicitly.
87.if ${WARNS} <= 6
88CWARNFLAGS.clang+=	-Wno-empty-body -Wno-string-plus-int
89CWARNFLAGS.clang+=	-Wno-unused-const-variable
90.if ${COMPILER_TYPE} == "clang" && ${COMPILER_VERSION} >= 130000
91CWARNFLAGS.clang+=	-Wno-error=unused-but-set-variable
92.endif
93.if ${COMPILER_TYPE} == "clang" && ${COMPILER_VERSION} >= 150000
94CWARNFLAGS.clang+=	-Wno-error=array-parameter
95CWARNFLAGS.clang+=	-Wno-error=deprecated-non-prototype
96CWARNFLAGS.clang+=	-Wno-error=unused-but-set-parameter
97.endif
98.if ${COMPILER_TYPE} == "clang" && ${COMPILER_VERSION} >= 190000
99# Similar to gcc >= 8.1 -Wno-error=cast-function-type below
100CWARNFLAGS.clang+=	-Wno-error=cast-function-type-mismatch
101.endif
102.endif # WARNS <= 6
103.if ${WARNS} <= 3
104CWARNFLAGS.clang+=	-Wno-tautological-compare -Wno-unused-value\
105		-Wno-parentheses-equality -Wno-unused-function -Wno-enum-conversion
106CWARNFLAGS.clang+=	-Wno-unused-local-typedef
107CWARNFLAGS.clang+=	-Wno-address-of-packed-member
108.if ${COMPILER_TYPE} == "gcc" && ${COMPILER_VERSION} >= 90100
109CWARNFLAGS.gcc+=	-Wno-address-of-packed-member
110.endif
111.if ${COMPILER_TYPE} == "clang" && ${COMPILER_VERSION} >= 70000 && \
112    ${MACHINE_CPUARCH} == "arm" && !${MACHINE_ARCH:Marmv[67]*}
113CWARNFLAGS.clang+=	-Wno-atomic-alignment
114.endif
115.endif # WARNS <= 3
116.if ${WARNS} <= 2
117CWARNFLAGS.clang+=	-Wno-switch -Wno-switch-enum -Wno-knr-promoted-parameter
118.endif # WARNS <= 2
119.if ${WARNS} <= 1
120CWARNFLAGS.clang+=	-Wno-parentheses
121.endif # WARNS <= 1
122.if defined(NO_WARRAY_BOUNDS)
123CWARNFLAGS.clang+=	-Wno-array-bounds
124.endif # NO_WARRAY_BOUNDS
125.if defined(NO_WMISLEADING_INDENTATION) && \
126    ((${COMPILER_TYPE} == "clang" && ${COMPILER_VERSION} >= 100000) || \
127      ${COMPILER_TYPE} == "gcc")
128CWARNFLAGS+=		-Wno-misleading-indentation
129.endif # NO_WMISLEADING_INDENTATION
130.if ${COMPILER_TYPE} == "clang" && ${COMPILER_VERSION} >= 140000
131NO_WBITWISE_INSTEAD_OF_LOGICAL=	-Wno-bitwise-instead-of-logical
132.endif
133.if ${COMPILER_TYPE} == "clang" && ${COMPILER_VERSION} >= 150000
134NO_WDEPRECATED_NON_PROTOTYPE=-Wno-deprecated-non-prototype
135.endif
136.if ${COMPILER_TYPE} == "gcc" && ${COMPILER_VERSION} >= 100100
137NO_WZERO_LENGTH_BOUNDS=	-Wno-zero-length-bounds
138.endif
139.if ${COMPILER_TYPE} == "gcc" && ${COMPILER_VERSION} >= 110100
140NO_WARRAY_PARAMETER=	-Wno-array-parameter
141.endif
142.if ${COMPILER_TYPE} == "gcc" && ${COMPILER_VERSION} >= 120100
143NO_WUSE_AFTER_FREE=	-Wno-use-after-free
144NO_WDANGLING_POINTER=	-Wno-dangling-pointer
145.endif
146.endif # WARNS
147
148.if defined(FORMAT_AUDIT)
149WFORMAT=	1
150.endif # FORMAT_AUDIT
151.if defined(WFORMAT)
152.if ${WFORMAT} > 0
153#CWARNFLAGS+=	-Wformat-nonliteral -Wformat-security -Wno-format-extra-args
154CWARNFLAGS+=	-Wformat=2 -Wno-format-extra-args
155.if ${WARNS} <= 3
156CWARNFLAGS.clang+=	-Wno-format-nonliteral
157.endif # WARNS <= 3
158.if ${MK_WERROR} != "no" && ${MK_WERROR.${COMPILER_TYPE}:Uyes} != "no"
159CWARNFLAGS+=	-Werror
160.endif # ${MK_WERROR} != "no" && ${MK_WERROR.${COMPILER_TYPE}:Uyes} != "no"
161.endif # WFORMAT > 0
162.endif # WFORMAT
163.if defined(NO_WFORMAT) || defined(NO_WFORMAT.${COMPILER_TYPE})
164CWARNFLAGS+=	-Wno-format
165.endif # NO_WFORMAT || NO_WFORMAT.${COMPILER_TYPE}
166
167# GCC
168# We should clean up warnings produced with these flags.
169# They were originally added as a quick hack to enable gcc5/6.
170# The base system requires at least GCC 6.4, but some ports
171# use this file with older compilers.  Request an exprun
172# before changing these.
173.if ${COMPILER_TYPE} == "gcc"
174# GCC 5.2.0
175.if ${COMPILER_VERSION} >= 50200
176CWARNFLAGS+=	-Wno-error=address			\
177		-Wno-error=array-bounds			\
178		-Wno-error=attributes			\
179		-Wno-error=bool-compare			\
180		-Wno-error=cast-align			\
181		-Wno-error=clobbered			\
182		-Wno-error=deprecated-declarations	\
183		-Wno-error=enum-compare			\
184		-Wno-error=extra			\
185		-Wno-error=logical-not-parentheses	\
186		-Wno-error=strict-aliasing		\
187		-Wno-error=uninitialized		\
188		-Wno-error=unused-but-set-variable	\
189		-Wno-error=unused-function		\
190		-Wno-error=unused-value
191.endif
192
193# GCC 6.1.0
194.if ${COMPILER_VERSION} >= 60100
195CWARNFLAGS+=	-Wno-error=empty-body			\
196		-Wno-error=maybe-uninitialized		\
197		-Wno-error=nonnull-compare		\
198		-Wno-error=shift-negative-value		\
199		-Wno-error=tautological-compare		\
200		-Wno-error=unused-const-variable
201.endif
202
203# GCC 7.1.0
204.if ${COMPILER_VERSION} >= 70100
205CWARNFLAGS+=	-Wno-error=bool-operation		\
206		-Wno-error=deprecated			\
207		-Wno-error=expansion-to-defined		\
208		-Wno-error=format-overflow		\
209		-Wno-error=format-truncation		\
210		-Wno-error=implicit-fallthrough		\
211		-Wno-error=int-in-bool-context		\
212		-Wno-error=memset-elt-size		\
213		-Wno-error=noexcept-type		\
214		-Wno-error=nonnull			\
215		-Wno-error=pointer-compare		\
216		-Wno-error=stringop-overflow
217.endif
218
219# GCC 8.1.0
220.if ${COMPILER_VERSION} >= 80100
221CWARNFLAGS+=	-Wno-error=aggressive-loop-optimizations	\
222		-Wno-error=cast-function-type			\
223		-Wno-error=catch-value				\
224		-Wno-error=multistatement-macros		\
225		-Wno-error=restrict				\
226		-Wno-error=sizeof-pointer-memaccess		\
227		-Wno-error=stringop-truncation
228CXXWARNFLAGS+=	-Wno-error=class-memaccess
229.endif
230
231# GCC 9.2.0
232.if ${COMPILER_VERSION} >= 90200
233.if ${MACHINE_ARCH} == "i386"
234CWARNFLAGS+=	-Wno-error=overflow
235.endif
236.endif
237
238# GCC 12.1.0
239.if ${COMPILER_VERSION} >= 120100
240# These warnings are raised by headers in libc++ so are disabled
241# globally for all C++
242CXXWARNFLAGS+=	-Wno-literal-suffix 			\
243		-Wno-error=unknown-pragmas
244.endif
245
246# GCC 13.1.0
247.if ${COMPILER_VERSION} >= 130100
248# These warnings are raised by headers in libc++ so are disabled
249# globally for all C++
250CXXWARNFLAGS+=	-Wno-dangling-reference
251.endif
252
253# GCC produces false positives for functions that switch on an
254# enum (GCC bug 87950)
255CWARNFLAGS+=	-Wno-return-type
256
257# GCC's own arm_neon.h triggers various warnings
258.if ${MACHINE_CPUARCH} == "aarch64"
259CWARNFLAGS+=	-Wno-system-headers
260.endif
261.endif	# gcc
262
263# How to handle FreeBSD custom printf format specifiers.
264.if ${COMPILER_TYPE} == "clang" || \
265    (${COMPILER_TYPE} == "gcc" && ${COMPILER_VERSION} >= 120100)
266FORMAT_EXTENSIONS=	-D__printf__=__freebsd_kprintf__
267.else
268FORMAT_EXTENSIONS=	-fformat-extensions
269.endif
270
271.if defined(IGNORE_PRAGMA)
272CWARNFLAGS+=	-Wno-unknown-pragmas
273.endif # IGNORE_PRAGMA
274
275# This warning is utter nonsense
276CFLAGS+=	-Wno-format-zero-length
277
278.if ${COMPILER_TYPE} == "clang"
279# The headers provided by clang are incompatible with the FreeBSD headers.
280# If the version of clang is not one that has been patched to omit the
281# incompatible headers, we need to compile with -nobuiltininc and add the
282# resource dir to the end of the search paths. This ensures that headers such as
283# immintrin.h are still found but stddef.h, etc. are picked up from FreeBSD.
284#
285# XXX: This is a hack to support complete external installs of clang while
286# we work to synchronize our decleration guards with those in the clang tree.
287.if ${MK_CLANG_BOOTSTRAP:Uno} == "no" && \
288    ${COMPILER_RESOURCE_DIR} != "unknown" && !defined(BOOTSTRAPPING)
289CFLAGS+=-nobuiltininc -idirafter ${COMPILER_RESOURCE_DIR}/include
290.endif
291.endif
292
293CLANG_OPT_SMALL= -mstack-alignment=8 -mllvm -inline-threshold=3
294.if ${COMPILER_VERSION} < 130000
295CLANG_OPT_SMALL+= -mllvm -simplifycfg-dup-ret
296.endif
297CLANG_OPT_SMALL+= -mllvm -enable-load-pre=false
298CFLAGS.clang+=	 -Qunused-arguments
299# The libc++ headers use c++11 extensions.  These are normally silenced because
300# they are treated as system headers, but we explicitly disable that warning
301# suppression when building the base system to catch bugs in our headers.
302# Eventually we'll want to start building the base system C++ code as C++11,
303# but not yet.
304CXXFLAGS.clang+=	 -Wno-c++11-extensions
305
306.if ${MK_SSP} != "no"
307# Don't use -Wstack-protector as it breaks world with -Werror.
308SSP_CFLAGS?=	-fstack-protector-strong
309CFLAGS+=	${SSP_CFLAGS}
310.endif # SSP
311
312# Additional flags passed in CFLAGS and CXXFLAGS when MK_DEBUG_FILES is
313# enabled.
314DEBUG_FILES_CFLAGS?= -g
315
316# Allow user-specified additional warning flags, plus compiler and file
317# specific flag overrides, unless we've overridden this...
318.if ${MK_WARNS} != "no"
319CFLAGS+=	${CWARNFLAGS:M*} ${CWARNFLAGS.${COMPILER_TYPE}}
320CFLAGS+=	${CWARNFLAGS.${.IMPSRC:T}}
321CXXFLAGS+=	${CXXWARNFLAGS:M*} ${CXXWARNFLAGS.${COMPILER_TYPE}}
322CXXFLAGS+=	${CXXWARNFLAGS.${.IMPSRC:T}}
323.endif
324
325CFLAGS+=	 ${CFLAGS.${COMPILER_TYPE}}
326CXXFLAGS+=	 ${CXXFLAGS.${COMPILER_TYPE}}
327
328AFLAGS+=	${AFLAGS.${.IMPSRC:T}}
329AFLAGS+=	${AFLAGS.${.TARGET:T}}
330ACFLAGS+=	${ACFLAGS.${.IMPSRC:T}}
331ACFLAGS+=	${ACFLAGS.${.TARGET:T}}
332CFLAGS+=	${CFLAGS.${.IMPSRC:T}}
333CXXFLAGS+=	${CXXFLAGS.${.IMPSRC:T}}
334
335LDFLAGS+=	${LDFLAGS.${LINKER_TYPE}}
336
337# Only allow .TARGET when not using PROGS as it has the same syntax
338# per PROG which is ambiguous with this syntax. This is only needed
339# for PROG_VARS vars.
340#
341# Some directories (currently just clang) also need to disable this since
342# CFLAGS.${COMPILER_TYPE}, CFLAGS.${.IMPSRC:T} and CFLAGS.${.TARGET:T} all live
343# in the same namespace, meaning that, for example, GCC builds of clang pick up
344# CFLAGS.clang via CFLAGS.${.TARGET:T} and thus try to pass Clang-specific
345# flags. Ideally the different sources of CFLAGS would be namespaced to avoid
346# collisions.
347.if !defined(_RECURSING_PROGS) && !defined(NO_TARGET_FLAGS)
348.if ${MK_WARNS} != "no"
349CFLAGS+=	${CWARNFLAGS.${.TARGET:T}}
350.endif
351CFLAGS+=	${CFLAGS.${.TARGET:T}}
352CXXFLAGS+=	${CXXFLAGS.${.TARGET:T}}
353LDFLAGS+=	${LDFLAGS.${.TARGET:T}}
354LDADD+=		${LDADD.${.TARGET:T}}
355LIBADD+=	${LIBADD.${.TARGET:T}}
356.endif
357
358.if defined(SRCTOP)
359# Prevent rebuilding during install to support read-only objdirs.
360.if ${.TARGETS:M*install*} == ${.TARGETS} && empty(.MAKE.MODE:Mmeta)
361CFLAGS+=	ERROR-tried-to-rebuild-during-make-install
362.endif
363.endif
364
365# Please keep this if in sync with kern.mk
366.if ${LD} != "ld" && (${CC:[1]:H} != ${LD:[1]:H} || ${LD:[1]:T} != "ld")
367# Add -fuse-ld=${LD} if $LD is in a different directory or not called "ld".
368.if ${COMPILER_TYPE} == "clang"
369# Note: Clang does not like relative paths for ld so we map ld.lld -> lld.
370.if ${COMPILER_VERSION} >= 120000
371LDFLAGS+=	--ld-path=${LD:[1]:S/^ld.//1W}
372.else
373LDFLAGS+=	-fuse-ld=${LD:[1]:S/^ld.//1W}
374.endif
375.elif ${COMPILER_TYPE} == "gcc"
376# GCC does not support an absolute path for -fuse-ld so we just print this
377# warning instead and let the user add the required symlinks.
378# However, we can avoid this warning if -B is set appropriately (e.g. for
379# CROSS_TOOLCHAIN=...-gcc).
380.if !(${LD:[1]:T} == "ld" && ${CC:tw:M-B${LD:[1]:H}/})
381.warning LD (${LD}) is not the default linker for ${CC} but -fuse-ld= is not supported
382.endif
383.endif
384.endif
385
386# Tell bmake not to mistake standard targets for things to be searched for
387# or expect to ever be up-to-date.
388PHONY_NOTMAIN = analyze afterdepend afterinstall all beforedepend beforeinstall \
389		beforelinking build build-tools buildconfig buildfiles \
390		buildincludes check checkdpadd clean cleandepend cleandir \
391		cleanobj configure depend distclean distribute exe \
392		files html includes install installconfig installdirs \
393		installfiles installincludes lint obj objlink objs objwarn \
394		realinstall tags whereobj
395
396# we don't want ${PROG} to be PHONY
397.PHONY: ${PHONY_NOTMAIN:N${PROG:U}}
398.NOTMAIN: ${PHONY_NOTMAIN:Nall}
399
400.if ${MK_STAGING} != "no"
401.if defined(_SKIP_BUILD) || (!make(all) && !make(clean*) && !make(*clean))
402_SKIP_STAGING?= yes
403.endif
404.if ${_SKIP_STAGING:Uno} == "yes"
405staging stage_libs stage_files stage_as stage_links stage_symlinks:
406.else
407# allow targets like beforeinstall to be leveraged
408DESTDIR= ${STAGE_OBJTOP}
409.export DESTDIR
410
411.if target(beforeinstall)
412.if !empty(_LIBS) || (${MK_STAGING_PROG} != "no" && !defined(INTERNALPROG))
413staging: beforeinstall
414.endif
415.endif
416
417# normally only libs and includes are staged
418.if ${MK_STAGING_PROG} != "no" && !defined(INTERNALPROG)
419STAGE_DIR.prog= ${STAGE_OBJTOP}${BINDIR}
420
421.if !empty(PROG)
422.if defined(PROGNAME)
423STAGE_AS_SETS+= prog
424STAGE_AS_${PROG}= ${PROGNAME}
425stage_as.prog: ${PROG}
426.else
427STAGE_SETS+= prog
428stage_files.prog: ${PROG}
429STAGE_TARGETS+= stage_files
430.endif
431.endif
432.endif
433
434.if !empty(_LIBS) && !defined(INTERNALLIB)
435.if defined(SHLIBDIR) && ${SHLIBDIR} != ${LIBDIR} && ${_LIBS:Uno:M*.so.*} != ""
436STAGE_SETS+= shlib
437STAGE_DIR.shlib= ${STAGE_OBJTOP}${SHLIBDIR}
438STAGE_FILES.shlib+= ${_LIBS:M*.so.*}
439stage_files.shlib: ${_LIBS:M*.so.*}
440.endif
441
442.if defined(SHLIB_LINK) && commands(${SHLIB_LINK:R}.ld)
443STAGE_AS_SETS+= ldscript
444STAGE_AS.ldscript+= ${SHLIB_LINK:R}.ld
445stage_as.ldscript: ${SHLIB_LINK:R}.ld
446STAGE_DIR.ldscript = ${STAGE_LIBDIR}
447STAGE_AS_${SHLIB_LINK:R}.ld:= ${SHLIB_LINK}
448NO_SHLIB_LINKS=
449.endif
450
451.if target(stage_files.shlib)
452stage_libs: ${_LIBS}
453.if defined(DEBUG_FLAGS) && target(${SHLIB_NAME}.symbols)
454stage_files.shlib: ${SHLIB_NAME}.symbols
455.endif
456.else
457stage_libs: ${_LIBS}
458.endif
459.if defined(SHLIB_NAME) && defined(DEBUG_FLAGS) && target(${SHLIB_NAME}.symbols)
460stage_libs: ${SHLIB_NAME}.symbols
461.endif
462
463.endif
464
465.if !empty(INCS) || !empty(INCSGROUPS) && target(buildincludes)
466.if !defined(NO_BEFOREBUILD_INCLUDES)
467stage_includes: buildincludes
468beforebuild: stage_includes
469.endif
470.endif
471
472.for t in stage_libs stage_files stage_as
473.if target($t)
474STAGE_TARGETS+= $t
475.endif
476.endfor
477
478.if !empty(STAGE_AS_SETS)
479STAGE_TARGETS+= stage_as
480.endif
481
482.if !empty(STAGE_TARGETS) || (${MK_STAGING_PROG} != "no" && !defined(INTERNALPROG))
483
484.if !empty(LINKS)
485STAGE_TARGETS+= stage_links
486.if ${MAKE_VERSION} < 20131001
487stage_links.links: ${_LIBS} ${PROG}
488.endif
489STAGE_SETS+= links
490STAGE_LINKS.links= ${LINKS}
491.endif
492
493.if !empty(SYMLINKS)
494STAGE_TARGETS+= stage_symlinks
495STAGE_SETS+= links
496STAGE_SYMLINKS.links= ${SYMLINKS}
497.endif
498
499.endif
500
501.include <meta.stage.mk>
502.endif
503.endif
504
505.if defined(META_TARGETS)
506.for _tgt in ${META_TARGETS}
507.if target(${_tgt})
508${_tgt}: ${META_DEPS}
509.endif
510.endfor
511.endif
512