2022-04-03 19:52:08 +00:00
|
|
|
# $NetBSD: directive-ifmake.mk,v 1.10 2022/02/09 21:09:24 rillig Exp $
|
2020-09-05 16:11:04 +00:00
|
|
|
#
|
|
|
|
# Tests for the .ifmake directive, which provides a shortcut for asking
|
|
|
|
# whether a certain target is requested to be made from the command line.
|
2020-11-20 03:54:37 +00:00
|
|
|
#
|
|
|
|
# TODO: Describe why the shortcut may be useful (if it's useful at all),
|
2022-04-03 19:52:08 +00:00
|
|
|
# instead of using the more general '.if make(target)'.
|
2020-11-20 03:54:37 +00:00
|
|
|
|
2022-02-05 20:03:50 +00:00
|
|
|
.MAKEFLAGS: first second
|
2020-09-05 16:11:04 +00:00
|
|
|
|
|
|
|
# This is the most basic form.
|
|
|
|
.ifmake first
|
2020-11-20 03:54:37 +00:00
|
|
|
. info ok: positive condition works
|
2020-09-05 16:11:04 +00:00
|
|
|
.else
|
2020-11-20 03:54:37 +00:00
|
|
|
. warning positive condition fails
|
2020-09-05 16:11:04 +00:00
|
|
|
.endif
|
|
|
|
|
2022-02-05 20:03:50 +00:00
|
|
|
# The '!' is interpreted as 'not'. A possible alternative interpretation of
|
|
|
|
# this condition is whether the target named "!first" was requested. To
|
|
|
|
# distinguish these cases, see the next test.
|
2020-09-05 16:11:04 +00:00
|
|
|
.ifmake !first
|
2020-11-20 03:54:37 +00:00
|
|
|
. warning unexpected
|
2020-09-05 16:11:04 +00:00
|
|
|
.else
|
2020-11-20 03:54:37 +00:00
|
|
|
. info ok: negation works
|
2020-09-05 16:11:04 +00:00
|
|
|
.endif
|
|
|
|
|
|
|
|
# See if the exclamation mark really means "not", or if it is just part of
|
2020-11-20 03:54:37 +00:00
|
|
|
# the target name. Since it means 'not', the two exclamation marks are
|
|
|
|
# effectively ignored, and 'first' is indeed a requested target. If the
|
|
|
|
# exclamation mark were part of the name instead, the name would be '!!first',
|
|
|
|
# and such a target was not requested to be made.
|
2020-09-05 16:11:04 +00:00
|
|
|
.ifmake !!first
|
2020-11-20 03:54:37 +00:00
|
|
|
. info ok: double negation works
|
2020-09-05 16:11:04 +00:00
|
|
|
.else
|
2020-11-20 03:54:37 +00:00
|
|
|
. warning double negation fails
|
2020-09-05 16:11:04 +00:00
|
|
|
.endif
|
|
|
|
|
|
|
|
# Multiple targets can be combined using the && and || operators.
|
|
|
|
.ifmake first && second
|
2020-11-20 03:54:37 +00:00
|
|
|
. info ok: both mentioned
|
2020-09-05 16:11:04 +00:00
|
|
|
.else
|
2020-11-20 03:54:37 +00:00
|
|
|
. warning && does not work as expected
|
2020-09-05 16:11:04 +00:00
|
|
|
.endif
|
|
|
|
|
|
|
|
# Negation also works in complex conditions.
|
|
|
|
.ifmake first && !unmentioned
|
2020-11-20 03:54:37 +00:00
|
|
|
. info ok: only those mentioned
|
2020-09-05 16:11:04 +00:00
|
|
|
.else
|
2020-11-20 03:54:37 +00:00
|
|
|
. warning && with ! does not work as expected
|
2020-09-05 16:11:04 +00:00
|
|
|
.endif
|
|
|
|
|
|
|
|
# Using the .MAKEFLAGS special dependency target, arbitrary command
|
|
|
|
# line options can be added at parse time. This means that it is
|
|
|
|
# possible to extend the targets to be made.
|
|
|
|
.MAKEFLAGS: late-target
|
|
|
|
.ifmake late-target
|
2020-11-20 03:54:37 +00:00
|
|
|
. info Targets can even be added at parse time.
|
|
|
|
.else
|
|
|
|
. info No, targets cannot be added at parse time anymore.
|
|
|
|
.endif
|
|
|
|
|
|
|
|
# Numbers are interpreted as numbers, no matter whether the directive is
|
|
|
|
# a plain .if or an .ifmake.
|
|
|
|
.ifmake 0
|
|
|
|
. error
|
|
|
|
.endif
|
|
|
|
.ifmake 1
|
2020-09-05 16:11:04 +00:00
|
|
|
.else
|
2020-11-20 03:54:37 +00:00
|
|
|
. error
|
2020-09-05 16:11:04 +00:00
|
|
|
.endif
|
|
|
|
|
2020-11-20 03:54:37 +00:00
|
|
|
# A condition that consists of a variable expression only (without any
|
|
|
|
# comparison operator) can be used with .if and the other .ifxxx directives.
|
|
|
|
.ifmake ${:Ufirst}
|
|
|
|
. info ok
|
|
|
|
.else
|
|
|
|
. error
|
|
|
|
.endif
|
|
|
|
|
|
|
|
|
2022-02-05 20:03:50 +00:00
|
|
|
# As an edge case, a target can actually be named "!first" on the command
|
|
|
|
# line. There is no way to define a target of this name though since in a
|
|
|
|
# dependency line, a plain '!' is interpreted as a dependency operator.
|
|
|
|
|
|
|
|
.MAKEFLAGS: !edge
|
|
|
|
.ifmake edge
|
|
|
|
. error
|
|
|
|
.endif
|
|
|
|
|
|
|
|
# The '\!edge' in the following condition is parsed as a bare word. For such
|
|
|
|
# a bare word, there is no escaping mechanism so the backslash passes through.
|
|
|
|
# Since the condition function 'make' accepts a pattern instead of a plain
|
|
|
|
# target name, the '\' is finally discarded in Str_Match.
|
|
|
|
.ifmake \!edge
|
|
|
|
.else
|
|
|
|
. error
|
|
|
|
.endif
|
|
|
|
|
|
|
|
# In a dependency line, a plain '!' is interpreted as a dependency operator
|
|
|
|
# (the other two are ':' and '::'). If the '!' is escaped by a '\', as
|
|
|
|
# implemented in ParseDependencyTargetWord, the additional backslash is never
|
|
|
|
# removed though. The target name thus becomes '\!edge' instead of the
|
|
|
|
# intended '!edge'. Defining a target whose name contains a '!' will either
|
|
|
|
# require additional tricks, or it may even be impossible.
|
|
|
|
|
|
|
|
first second unmentioned late-target \!edge:
|
2020-09-05 16:11:04 +00:00
|
|
|
: $@
|