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