xref: /freebsd/contrib/bmake/mk/options.mk (revision 8aac90f18aef7c9eea906c3ff9a001ca7b94f375)
1# SPDX-License-Identifier: BSD-2-Clause
2#
3# $Id: options.mk,v 1.20 2024/02/17 17:26:57 sjg Exp $
4#
5#	@(#) Copyright (c) 2012, Simon J. Gerraty
6#
7#	This file is provided in the hope that it will
8#	be of use.  There is absolutely NO WARRANTY.
9#	Permission to copy, redistribute or otherwise
10#	use this file is hereby granted provided that
11#	the above copyright notice and this notice are
12#	left intact.
13#
14#	Please send copies of changes and bug-fixes to:
15#	sjg@crufty.net
16#
17
18# Inspired by FreeBSD bsd.own.mk, but intentionally simpler and more flexible.
19
20# Options are normally listed in either OPTIONS_DEFAULT_{YES,NO}
21# We convert these to ${OPTION}/{yes,no} in OPTIONS_DEFAULT_VALUES.
22# We add the OPTIONS_DEFAULT_NO first so they take precedence.
23# This allows override of an OPTIONS_DEFAULT_YES by adding it to
24# OPTIONS_DEFAULT_NO or adding ${OPTION}/no to OPTIONS_DEFAULT_VALUES.
25# An OPTIONS_DEFAULT_NO option can only be overridden by putting
26# ${OPTION}/yes in OPTIONS_DEFAULT_VALUES.
27# A makefile may set NO_* (or NO*) to indicate it cannot do something.
28# User sets WITH_* and WITHOUT_* to indicate what they want.
29# We set ${OPTION_PREFIX:UMK_}* which is then all we need care about.
30OPTIONS_DEFAULT_VALUES += \
31	${OPTIONS_DEFAULT_NO:U:O:u:S,$,/no,} \
32	${OPTIONS_DEFAULT_YES:U:O:u:S,$,/yes,}
33
34OPTION_PREFIX ?= MK_
35
36# NO_* takes precedence
37# If both WITH_* and WITHOUT_* are defined, WITHOUT_ wins unless
38# DOMINANT_* is set to "yes"
39# Otherwise WITH_* and WITHOUT_* override the default.
40.for o in ${OPTIONS_DEFAULT_VALUES:M*/*}
41.if defined(WITH_${o:H}) && ${WITH_${o:H}} == "no"
42# a common miss-use - point out correct usage
43.warning use WITHOUT_${o:H}=1 not WITH_${o:H}=no
44.endif
45.if defined(NO_${o:H}) || defined(NO${o:H})
46# we cannot do it
47${OPTION_PREFIX}${o:H} ?= no
48.elif defined(WITH_${o:H}) && defined(WITHOUT_${o:H})
49# normally WITHOUT_ wins
50DOMINANT_${o:H} ?= no
51${OPTION_PREFIX}${o:H} ?= ${DOMINANT_${o:H}}
52.elif ${o:T:tl} == "no"
53.if defined(WITH_${o:H})
54${OPTION_PREFIX}${o:H} ?= yes
55.else
56${OPTION_PREFIX}${o:H} ?= no
57.endif
58.else
59.if defined(WITHOUT_${o:H})
60${OPTION_PREFIX}${o:H} ?= no
61.else
62${OPTION_PREFIX}${o:H} ?= yes
63.endif
64.endif
65.endfor
66
67# OPTIONS_DEFAULT_DEPENDENT += FOO_UTILS/FOO
68# If neither WITH[OUT]_FOO_UTILS is set, (see rules above)
69# use the value of ${OPTION_PREFIX}FOO
70.for o in ${OPTIONS_DEFAULT_DEPENDENT:M*/*:O:u}
71.if defined(NO_${o:H}) || defined(NO${o:H})
72# we cannot do it
73${OPTION_PREFIX}${o:H} ?= no
74.elif defined(WITH_${o:H}) && defined(WITHOUT_${o:H})
75# normally WITHOUT_ wins
76DOMINANT_${o:H} ?= no
77${OPTION_PREFIX}${o:H} ?= ${DOMINANT_${o:H}}
78.elif defined(WITH_${o:H})
79${OPTION_PREFIX}${o:H} ?= yes
80.elif defined(WITHOUT_${o:H})
81${OPTION_PREFIX}${o:H} ?= no
82.else
83${OPTION_PREFIX}${o:H} ?= ${${OPTION_PREFIX}${o:T}}
84.endif
85.endfor
86
87# allow displaying/describing set options
88.set_options := ${.set_options} \
89	${OPTIONS_DEFAULT_VALUES:H:N.} \
90	${OPTIONS_DEFAULT_DEPENDENT:U:H:N.} \
91
92# this can be used in .info as well as target below
93OPTIONS_SHOW ?= ${.set_options:O:u:@o@${OPTION_PREFIX}$o=${${OPTION_PREFIX}$o}@}
94# prefix for variables describing options
95OPTION_DESCRIPTION_PREFIX ?= DESCRIPTION_
96OPTION_DESCRIPTION_SEPARATOR ?= ==
97
98OPTIONS_DESCRIBE ?= ${.set_options:O:u:@o@${OPTION_PREFIX}$o=${${OPTION_PREFIX}$o}${${OPTION_DESCRIPTION_PREFIX}$o:S,^, ${OPTION_DESCRIPTION_SEPARATOR} ,1}${.newline}@}
99
100.if !commands(show-options)
101show-options: .NOTMAIN .PHONY
102	@echo; echo "${OPTIONS_SHOW:ts\n}"; echo
103.endif
104
105.if !commands(describe-options)
106describe-options: .NOTMAIN .PHONY
107	@echo; echo "${OPTIONS_DESCRIBE}"; echo
108.endif
109
110# we expect to be included more than once
111.undef OPTIONS_DEFAULT_DEPENDENT
112.undef OPTIONS_DEFAULT_NO
113.undef OPTIONS_DEFAULT_VALUES
114.undef OPTIONS_DEFAULT_YES
115