1# $NetBSD: directive-ifmake.mk,v 1.9 2022/01/22 16:23:56 rillig Exp $ 2# 3# Tests for the .ifmake directive, which provides a shortcut for asking 4# whether a certain target is requested to be made from the command line. 5# 6# TODO: Describe why the shortcut may be useful (if it's useful at all), 7# instead of using the more versatile '.if make(target)'. 8 9.MAKEFLAGS: first second 10 11# This is the most basic form. 12.ifmake first 13. info ok: positive condition works 14.else 15. warning positive condition fails 16.endif 17 18# The '!' is interpreted as 'not'. A possible alternative interpretation of 19# this condition is whether the target named "!first" was requested. To 20# distinguish these cases, see the next test. 21.ifmake !first 22. warning unexpected 23.else 24. info ok: negation works 25.endif 26 27# See if the exclamation mark really means "not", or if it is just part of 28# the target name. Since it means 'not', the two exclamation marks are 29# effectively ignored, and 'first' is indeed a requested target. If the 30# exclamation mark were part of the name instead, the name would be '!!first', 31# and such a target was not requested to be made. 32.ifmake !!first 33. info ok: double negation works 34.else 35. warning double negation fails 36.endif 37 38# Multiple targets can be combined using the && and || operators. 39.ifmake first && second 40. info ok: both mentioned 41.else 42. warning && does not work as expected 43.endif 44 45# Negation also works in complex conditions. 46.ifmake first && !unmentioned 47. info ok: only those mentioned 48.else 49. warning && with ! does not work as expected 50.endif 51 52# Using the .MAKEFLAGS special dependency target, arbitrary command 53# line options can be added at parse time. This means that it is 54# possible to extend the targets to be made. 55.MAKEFLAGS: late-target 56.ifmake late-target 57. info Targets can even be added at parse time. 58.else 59. info No, targets cannot be added at parse time anymore. 60.endif 61 62# Numbers are interpreted as numbers, no matter whether the directive is 63# a plain .if or an .ifmake. 64.ifmake 0 65. error 66.endif 67.ifmake 1 68.else 69. error 70.endif 71 72# A condition that consists of a variable expression only (without any 73# comparison operator) can be used with .if and the other .ifxxx directives. 74.ifmake ${:Ufirst} 75. info ok 76.else 77. error 78.endif 79 80 81# As an edge case, a target can actually be named "!first" on the command 82# line. There is no way to define a target of this name though since in a 83# dependency line, a plain '!' is interpreted as a dependency operator. 84 85.MAKEFLAGS: !edge 86.ifmake edge 87. error 88.endif 89 90# The '\!edge' in the following condition is parsed as a bare word. For such 91# a bare word, there is no escaping mechanism so the backslash passes through. 92# Since the condition function 'make' accepts a pattern instead of a plain 93# target name, the '\' is finally discarded in Str_Match. 94.ifmake \!edge 95.else 96. error 97.endif 98 99# In a dependency line, a plain '!' is interpreted as a dependency operator 100# (the other two are ':' and '::'). If the '!' is escaped by a '\', as 101# implemented in ParseDependencyTargetWord, the additional backslash is never 102# removed though. The target name thus becomes '\!edge' instead of the 103# intended '!edge'. Defining a target whose name contains a '!' will either 104# require additional tricks, or it may even be impossible. 105 106first second unmentioned late-target \!edge: 107 : $@ 108