xref: /freebsd/contrib/bmake/unit-tests/directive-ifmake.mk (revision d5e0a182cf153f8993a633b93d9220c99a89e760)
1*d5e0a182SSimon J. Gerraty# $NetBSD: directive-ifmake.mk,v 1.12 2023/11/19 21:47:52 rillig Exp $
22c3632d1SSimon J. Gerraty#
32c3632d1SSimon J. Gerraty# Tests for the .ifmake directive, which provides a shortcut for asking
42c3632d1SSimon J. Gerraty# whether a certain target is requested to be made from the command line.
5e2eeea75SSimon J. Gerraty#
6e2eeea75SSimon J. Gerraty# TODO: Describe why the shortcut may be useful (if it's useful at all),
71d3f2ddcSSimon J. Gerraty# instead of using the more general '.if make(target)'.
8e2eeea75SSimon J. Gerraty
99f45a3c8SSimon J. Gerraty.MAKEFLAGS: first second
102c3632d1SSimon J. Gerraty
112c3632d1SSimon J. Gerraty# This is the most basic form.
122c3632d1SSimon J. Gerraty.ifmake first
13148ee845SSimon J. Gerraty# expect+1: ok: positive condition works
142c3632d1SSimon J. Gerraty.  info ok: positive condition works
152c3632d1SSimon J. Gerraty.else
162c3632d1SSimon J. Gerraty.  warning positive condition fails
172c3632d1SSimon J. Gerraty.endif
182c3632d1SSimon J. Gerraty
199f45a3c8SSimon J. Gerraty# The '!' is interpreted as 'not'.  A possible alternative interpretation of
209f45a3c8SSimon J. Gerraty# this condition is whether the target named "!first" was requested.  To
219f45a3c8SSimon J. Gerraty# distinguish these cases, see the next test.
222c3632d1SSimon J. Gerraty.ifmake !first
232c3632d1SSimon J. Gerraty.  warning unexpected
242c3632d1SSimon J. Gerraty.else
25148ee845SSimon J. Gerraty# expect+1: ok: negation works
262c3632d1SSimon J. Gerraty.  info ok: negation works
272c3632d1SSimon J. Gerraty.endif
282c3632d1SSimon J. Gerraty
292c3632d1SSimon J. Gerraty# See if the exclamation mark really means "not", or if it is just part of
30e2eeea75SSimon J. Gerraty# the target name.  Since it means 'not', the two exclamation marks are
31e2eeea75SSimon J. Gerraty# effectively ignored, and 'first' is indeed a requested target.  If the
32e2eeea75SSimon J. Gerraty# exclamation mark were part of the name instead, the name would be '!!first',
33e2eeea75SSimon J. Gerraty# and such a target was not requested to be made.
342c3632d1SSimon J. Gerraty.ifmake !!first
35148ee845SSimon J. Gerraty# expect+1: ok: double negation works
362c3632d1SSimon J. Gerraty.  info ok: double negation works
372c3632d1SSimon J. Gerraty.else
382c3632d1SSimon J. Gerraty.  warning double negation fails
392c3632d1SSimon J. Gerraty.endif
402c3632d1SSimon J. Gerraty
412c3632d1SSimon J. Gerraty# Multiple targets can be combined using the && and || operators.
422c3632d1SSimon J. Gerraty.ifmake first && second
43148ee845SSimon J. Gerraty# expect+1: ok: both mentioned
442c3632d1SSimon J. Gerraty.  info ok: both mentioned
452c3632d1SSimon J. Gerraty.else
462c3632d1SSimon J. Gerraty.  warning && does not work as expected
472c3632d1SSimon J. Gerraty.endif
482c3632d1SSimon J. Gerraty
492c3632d1SSimon J. Gerraty# Negation also works in complex conditions.
502c3632d1SSimon J. Gerraty.ifmake first && !unmentioned
51148ee845SSimon J. Gerraty# expect+1: ok: only those mentioned
522c3632d1SSimon J. Gerraty.  info ok: only those mentioned
532c3632d1SSimon J. Gerraty.else
542c3632d1SSimon J. Gerraty.  warning && with ! does not work as expected
552c3632d1SSimon J. Gerraty.endif
562c3632d1SSimon J. Gerraty
572c3632d1SSimon J. Gerraty# Using the .MAKEFLAGS special dependency target, arbitrary command
582c3632d1SSimon J. Gerraty# line options can be added at parse time.  This means that it is
592c3632d1SSimon J. Gerraty# possible to extend the targets to be made.
602c3632d1SSimon J. Gerraty.MAKEFLAGS: late-target
612c3632d1SSimon J. Gerraty.ifmake late-target
62148ee845SSimon J. Gerraty# expect+1: Targets can even be added at parse time.
632c3632d1SSimon J. Gerraty.  info Targets can even be added at parse time.
642c3632d1SSimon J. Gerraty.else
652c3632d1SSimon J. Gerraty.  info No, targets cannot be added at parse time anymore.
662c3632d1SSimon J. Gerraty.endif
672c3632d1SSimon J. Gerraty
68e2eeea75SSimon J. Gerraty# Numbers are interpreted as numbers, no matter whether the directive is
69e2eeea75SSimon J. Gerraty# a plain .if or an .ifmake.
70e2eeea75SSimon J. Gerraty.ifmake 0
71e2eeea75SSimon J. Gerraty.  error
72e2eeea75SSimon J. Gerraty.endif
73e2eeea75SSimon J. Gerraty.ifmake 1
74e2eeea75SSimon J. Gerraty.else
75e2eeea75SSimon J. Gerraty.  error
76e2eeea75SSimon J. Gerraty.endif
77e2eeea75SSimon J. Gerraty
78*d5e0a182SSimon J. Gerraty# A condition that consists of an expression only (without any
79e2eeea75SSimon J. Gerraty# comparison operator) can be used with .if and the other .ifxxx directives.
80e2eeea75SSimon J. Gerraty.ifmake ${:Ufirst}
81148ee845SSimon J. Gerraty# expect+1: ok
82e2eeea75SSimon J. Gerraty.  info ok
83e2eeea75SSimon J. Gerraty.else
84e2eeea75SSimon J. Gerraty.  error
85e2eeea75SSimon J. Gerraty.endif
86e2eeea75SSimon J. Gerraty
87e2eeea75SSimon J. Gerraty
889f45a3c8SSimon J. Gerraty# As an edge case, a target can actually be named "!first" on the command
899f45a3c8SSimon J. Gerraty# line.  There is no way to define a target of this name though since in a
909f45a3c8SSimon J. Gerraty# dependency line, a plain '!' is interpreted as a dependency operator.
919f45a3c8SSimon J. Gerraty
929f45a3c8SSimon J. Gerraty.MAKEFLAGS: !edge
939f45a3c8SSimon J. Gerraty.ifmake edge
949f45a3c8SSimon J. Gerraty.  error
959f45a3c8SSimon J. Gerraty.endif
969f45a3c8SSimon J. Gerraty
979f45a3c8SSimon J. Gerraty# The '\!edge' in the following condition is parsed as a bare word.  For such
989f45a3c8SSimon J. Gerraty# a bare word, there is no escaping mechanism so the backslash passes through.
999f45a3c8SSimon J. Gerraty# Since the condition function 'make' accepts a pattern instead of a plain
1009f45a3c8SSimon J. Gerraty# target name, the '\' is finally discarded in Str_Match.
1019f45a3c8SSimon J. Gerraty.ifmake \!edge
1029f45a3c8SSimon J. Gerraty.else
1039f45a3c8SSimon J. Gerraty.  error
1049f45a3c8SSimon J. Gerraty.endif
1059f45a3c8SSimon J. Gerraty
1069f45a3c8SSimon J. Gerraty# In a dependency line, a plain '!' is interpreted as a dependency operator
1079f45a3c8SSimon J. Gerraty# (the other two are ':' and '::').  If the '!' is escaped by a '\', as
1089f45a3c8SSimon J. Gerraty# implemented in ParseDependencyTargetWord, the additional backslash is never
1099f45a3c8SSimon J. Gerraty# removed though.  The target name thus becomes '\!edge' instead of the
1109f45a3c8SSimon J. Gerraty# intended '!edge'.  Defining a target whose name contains a '!' will either
1119f45a3c8SSimon J. Gerraty# require additional tricks, or it may even be impossible.
1129f45a3c8SSimon J. Gerraty
1139f45a3c8SSimon J. Gerratyfirst second unmentioned late-target \!edge:
1142c3632d1SSimon J. Gerraty	: $@
115