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