Home | History | Annotate | Line # | Download | only in unit-tests
directive-include-guard.mk revision 1.1
      1  1.1  rillig # $NetBSD: directive-include-guard.mk,v 1.1 2023/06/16 09:25:13 rillig Exp $
      2  1.1  rillig #
      3  1.1  rillig # Tests for multiple-inclusion guards in makefiles.
      4  1.1  rillig #
      5  1.1  rillig # A file that is guarded by a multiple-inclusion guard has the following form:
      6  1.1  rillig #
      7  1.1  rillig #	.ifndef GUARD_NAME
      8  1.1  rillig #	GUARD_NAME=	# any value
      9  1.1  rillig #	...
     10  1.1  rillig #	.endif
     11  1.1  rillig #
     12  1.1  rillig # When such a file is included for the second time, it has no effect as all
     13  1.1  rillig # its content is skipped.
     14  1.1  rillig #
     15  1.1  rillig # TODO: In these cases, do not include the file, to increase performance.
     16  1.1  rillig 
     17  1.1  rillig 
     18  1.1  rillig # This is the canonical form of a multiple-inclusion guard.
     19  1.1  rillig INCS+=	guarded-ifndef
     20  1.1  rillig LINES.guarded-ifndef= \
     21  1.1  rillig 	'.ifndef GUARDED_IFNDEF' \
     22  1.1  rillig 	'GUARDED_IFNDEF=' \
     23  1.1  rillig 	'.endif'
     24  1.1  rillig 
     25  1.1  rillig # Comments and empty lines have no influence on the multiple-inclusion guard.
     26  1.1  rillig INCS+=	comments
     27  1.1  rillig LINES.comments= \
     28  1.1  rillig 	'\# comment' \
     29  1.1  rillig 	'' \
     30  1.1  rillig 	'.ifndef GUARD' \
     31  1.1  rillig 	'\# comment' \
     32  1.1  rillig 	'GUARD=\#comment' \
     33  1.1  rillig 	'.endif' \
     34  1.1  rillig 	'\# comment'
     35  1.1  rillig 
     36  1.1  rillig # An alternative form uses the 'defined' function.  It is more verbose than
     37  1.1  rillig # the canonical form.  There are other possible forms as well, such as with a
     38  1.1  rillig # triple negation, but these are not recognized as they are not common.
     39  1.1  rillig INCS+=	guarded-if
     40  1.1  rillig LINES.guarded-if= \
     41  1.1  rillig 	'.if !defined(GUARDED_IF)' \
     42  1.1  rillig 	'GUARDED_IF=' \
     43  1.1  rillig 	'.endif'
     44  1.1  rillig 
     45  1.1  rillig # Triple negation is so uncommon that it's not recognized.
     46  1.1  rillig INCS+=	triple-negation
     47  1.1  rillig LINES.triple-negation= \
     48  1.1  rillig 	'.if !!!defined(TRIPLE_NEGATION)' \
     49  1.1  rillig 	'TRIPLE_NEGATION=' \
     50  1.1  rillig 	'.endif'
     51  1.1  rillig 
     52  1.1  rillig # The variable names in the '.if' and the assignment must be the same.
     53  1.1  rillig INCS+=	varname-mismatch
     54  1.1  rillig LINES.varname-mismatch= \
     55  1.1  rillig 	'.ifndef VARNAME_MISMATCH' \
     56  1.1  rillig 	'OTHER_NAME=' \
     57  1.1  rillig 	'.endif'
     58  1.1  rillig 
     59  1.1  rillig # The variable name in the assignment must only contain alphanumeric
     60  1.1  rillig # characters and underscores, in particular, it must not be a dynamically
     61  1.1  rillig # computed name.
     62  1.1  rillig INCS+=	varname-indirect
     63  1.1  rillig LINES.varname-indirect= \
     64  1.1  rillig 	'.ifndef VARNAME_INDIRECT' \
     65  1.1  rillig 	'VARNAME_$${:UINDIRECT}=' \
     66  1.1  rillig 	'.endif'
     67  1.1  rillig 
     68  1.1  rillig # The variable assignment for the guard must directly follow the conditional.
     69  1.1  rillig INCS+=	late-assignment
     70  1.1  rillig LINES.late-assignment= \
     71  1.1  rillig 	'.ifndef LATE_ASSIGNMENT' \
     72  1.1  rillig 	'OTHER=' \
     73  1.1  rillig 	'LATE_ASSIGNMENT=' \
     74  1.1  rillig 	'.endif'
     75  1.1  rillig 
     76  1.1  rillig # There must be no other condition between the guard condition and the
     77  1.1  rillig # variable assignment.
     78  1.1  rillig INCS+=	two-conditions
     79  1.1  rillig LINES.two-conditions= \
     80  1.1  rillig 	'.ifndef TWO_CONDITIONS' \
     81  1.1  rillig 	'.  if 0' \
     82  1.1  rillig 	'TWO_CONDITIONS=' \
     83  1.1  rillig 	'.  endif' \
     84  1.1  rillig 	'.endif'
     85  1.1  rillig 
     86  1.1  rillig # If the guard variable is already set before the file is included for the
     87  1.1  rillig # first time, that file is not considered to be guarded.  It's a situation
     88  1.1  rillig # that is uncommon in practice.
     89  1.1  rillig INCS+=	already-set
     90  1.1  rillig LINES.already-set= \
     91  1.1  rillig 	'.ifndef ALREADY_SET' \
     92  1.1  rillig 	'ALREADY_SET=' \
     93  1.1  rillig 	'.endif'
     94  1.1  rillig ALREADY_SET=
     95  1.1  rillig 
     96  1.1  rillig # The whole file content must be guarded by a single '.if' conditional, not by
     97  1.1  rillig # several, even if they have the same effect.
     98  1.1  rillig INCS+=	twice
     99  1.1  rillig LINES.twice= \
    100  1.1  rillig 	'.ifndef TWICE' \
    101  1.1  rillig 	'TWICE=' \
    102  1.1  rillig 	'.endif' \
    103  1.1  rillig 	'.ifndef TWICE' \
    104  1.1  rillig 	'TWICE=' \
    105  1.1  rillig 	'.endif'
    106  1.1  rillig 
    107  1.1  rillig # When multiple files use the same guard variable name, they exclude each
    108  1.1  rillig # other.  It's the responsibility of the makefile authors to choose suitable
    109  1.1  rillig # variable names.  Typical choices are ${PROJECT}_${DIR}_${FILE}_MK.
    110  1.1  rillig INCS+=	reuse
    111  1.1  rillig LINES.reuse= \
    112  1.1  rillig 	${LINES.guarded-if}
    113  1.1  rillig 
    114  1.1  rillig # The conditional must come before the assignment, otherwise the conditional
    115  1.1  rillig # is useless, as it always evaluates to false.
    116  1.1  rillig INCS+=	swapped
    117  1.1  rillig LINES.swapped= \
    118  1.1  rillig 	'SWAPPED=' \
    119  1.1  rillig 	'.ifndef SWAPPED' \
    120  1.1  rillig 	'.endif'
    121  1.1  rillig 
    122  1.1  rillig 
    123  1.1  rillig # Include each of the files twice.  The directive-include-guard.exp file
    124  1.1  rillig # contains a single entry for the files whose multiple-inclusion guard works,
    125  1.1  rillig # and two entries for the files that are not protected against multiple
    126  1.1  rillig # inclusion.
    127  1.1  rillig #
    128  1.1  rillig # Some debug output lines are suppressed in the .exp file, see ./Makefile.
    129  1.1  rillig .for i in ${INCS}
    130  1.1  rillig .  for fname in directive-include-guard-$i.tmp
    131  1.1  rillig _!=	printf '%s\n' ${LINES.$i} > ${fname}
    132  1.1  rillig .MAKEFLAGS: -dp
    133  1.1  rillig .include "${.CURDIR}/${fname}"
    134  1.1  rillig .include "${.CURDIR}/${fname}"
    135  1.1  rillig .MAKEFLAGS: -d0
    136  1.1  rillig _!=	rm ${fname}
    137  1.1  rillig .  endfor
    138  1.1  rillig .endfor
    139  1.1  rillig 
    140  1.1  rillig all:
    141