Conditional Directive Blocks

Use of conditional directive blocks is optional and in some sections of the EDK II meta-data files, conditional directive blocks may be prohibited. Refer to the individual EDK II meta-data file specifications for specific restrictions.

Syntax

<Conditional> := <IfStatement>
<ElseIfConditional>
[<ElseConditional>]
<TS> "!endif" <EOL>
<IfStatement> := {<TS> "!if" <MTS> <ExpressionStatement>}
{<TS> "!ifdef" <MTS> <MACRO> <EOL>}
{<TS> "!ifndef" <MTS> <MACRO> <EOL>}
<Statements>
<Statements> := {<Statements>} {<Conditional>}
<ElseIfConditional> := <TS> "!elseif" <MTS> <ExpressionStatement> <EOL>
<Statements>
<ElseConditional> := <TS> "!else" <EOL> <Statements>
<ExpressionStatement> := <Expression> <EOL>

Restrictions

MACRO and PCD Values

When a MACRO is used in conditional directives !if or !elseif, the <MACROVAL> - $(MACRO) - format is used. When a PCD is used in a conditional directive (or in an expression) the <PCDVAL> - $(PcdName) - format is used.

Number values

For Numeric expressions, numbers must not be encapsulated by double quotation marks

Strings

Strings in <PCDVAL> elements must be NULL terminated. The NULL character is not part of the string that is tested. All other string comparisons do not include the double quotation marks encapsulating the string. If the string is "myapple", the only characters that would be tested are myapple. When using strings in the expression statements, there must be a comparison operator.

Parameters

Statements

Any valid section, section statement or set of statements defined in this specification may be within the scope of the conditional statements. The encapsulated statements must not break the integrity of the file. All statements within the encapsulation must end with <EOL>.

MACRO Usage in Expression Statements

If a MACRO is used in expression statements, the MACRO must be encapsulated between $( and ) character sets (matching C format). String comparisons are case sensitive and must exactly equal, character for character - leading and trailing white space characters included.

PcdFeatureFlag

The FeatureFlag PCD is a boolean PCD that is set to either True (1) or False (0). The PCD datum type for a FeatureFlag PCD is always BOOLEAN. It may be used in a logical expression.

FixedPcdName

A FixedAtBuild PCD will have a set value at build time, and that cannot be modified in the binary image, nor modified at runtime. For directives, the PCD datum type is limited to UINT8, UINT16, UINT32, UINT64, UINTN and BOOLEAN. Using a FixedAtBuild PCD that has a datum type of VOID* is limited to text-based comparisons in directives. Using a PCD that has a value of a byte array is not permitted. FixedAtBuild PCDs may be used in a logical expression.

Numeric Expression

This is a test of numbers, using relational or equality operators, that evaluates to TRUE or FALSE.

Logical Expression

This is a test where the expression, MACRO value or PCD value (include

<MACROVAL> or <PCDVAL> used in an expression) must evaluate to either TRUE (1) or FALSE (0), no operators are required, however logical operators, as well full expressions can be used. (expressions that do not evaluate to TRUE or FALSE must break the build).

String Expressions

The strings must be exactly identical in order to match. Literal strings must be encapsulated by double quotation marks. There must be a comparison operator between two strings (using a string without an operator is not permitted). Also permitted are the membership expressions, for architectures, targets and tool chain tag names.

All Expressions

C-style expression using C relational, equality and logical numeric and bitwise operators that evaluate to either TRUE (1) or FALSE (0). Values other than zero or one are invalid. Precedence and associativity follow C standards. Along with absolute values, macro names and PCDs may be used within an expression. For both macro names and PCDs, the element must be previously defined before it can be used. A new operator, "in" is also permitted for testing membership of an item in a list of one or more items.

Example:

if $(MyPlatformTspGuid.IPF_VERSION_1) && NOT $(MyPlatformTspGuid.IPF_VERSION_2)
[VTF.IPF.MyBsf]
ifdef IA32RESET
# IPF_VERSIONis 1 and IA32RESET defined
IA32_RST_BIN = IA32_RST.BIN
!endif
COMP_NAME = PAL_A
COMP_LOC = MyVtfVF | F
COMP_TYPE = 0xF
COMP_VER = 7.01
COMP_CS = 1
!if ($(PROCESSOR_NAME) == "M1")
COMP_BIN = M1PalCode/PAL_A_M1.BIN
COMP_SYM = M1PalCode/PAL_A_M1.SYM
!elseif ($(PROCESSOR_NAME) == "M2")
COMP_BIN = M2PalCode/PAL_A_M2.BIN
COMP_SYM = M2PalCode/PAL_A_M2.SYM
!else
COMP_BIN = GenPal/PAL_A_GEN.bin
COMP_SYM = GenPal/PAL_A_GEN.sym
!endif
COMP_SIZE = -
!elseif $(MyPlatformTspGuid.IPF_VERSION_2)
[VTF.IPF.MyBsf]
ifdef IA32RESET
IA32_RST_BIN = IA32_RST.BIN
!endif
COMP_NAME = PAL_A
COMP_LOC = MyVtfFv | F
COMP_TYPE = 0xF
COMP_VER = 7.01
COMP_CS = 1
OMP_BIN = GenPal/PAL_A_GEN.bin
COMP_SYM = GenPal/PAL_A_GEN.sym
COMP_SIZE = -
COMP_NAME = PAL_B
COMP_LOC = MyVtfFv | S
COMP_TYPE = 0x01
COMP_VER = -
COMP_CS = 1
COMP_BIN = GenPal/PAL_B_GEN.bin
COMP_SYM = GenPal/PAL_B_GEN.sym
COMP_SIZE = !else
[VTF.X64.MyVtf]
IA32_RST_BIN = IA32\_RST.BIN
!endif
!ifndef MY_MACRO
DEFINE MY_MACRO
!endif