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