inno-setuppreprocessor

How to nest #if and #elif definitions inside #ifdef macro in Inno Setup


I'm trying to to do the following:

[Code]
#define TextMacro "Hello2"

procedure InitializeWizard();
var
  Mode: Integer;
begin
  #ifdef TextMacro
    #if TextMacro == "Hello"
      Mode := 1;
    #elif TextMacro == "Hello2"
      Mode := 2;
    #else
      #error "Unknown mode"
    #endif
  #else
    Mode := 0;
  #endif
  Log('Mode = ' + IntToStr(Mode));
end;

It works correctly when TextMacro is defined, but fails when TextMacro is not defined. The error is on line #elif TextMacro == "Hello2":

Undeclared identifier: TextMacro.

How to fix that?

Here is the full compiler output:

Starting compile.  [Tuesday, May 20 2025 at 21:19:37]
Compiling script with Inno Setup 6.3.3 [ISDLLCompileScriptW]

[PreCompile] Processing.
[PreCompile] Processing is still being tested.
[PreCompile] Processing finished.

Preprocessing
   Reading file: C:\Dev\Inno Setup 6\ISPPBuiltins.iss
Compiler Error!
Line 52: Column 20: Undeclared identifier: TextMacro.

Line 52 is above mentioned line with #elif TextMacro == "Hello2".


Solution

  • Imo, according to the preprocessor documentation your code is correct:

    The if, elif, else, and endif directives can be nested. Each nested else, elif, or endif directive belongs to the closest preceding if directive.

    This looks like a bug in the parser to me.

    But you can structure the code like this instead:

    procedure InitializeWizard();
    var
      Mode: Integer;
    begin
      #ifndef TextMacro
        Mode := 0;
      #elif TextMacro == "Hello"
        Mode := 1;
      #elif TextMacro == "Hello2"
        Mode := 2;
      #else
        #error "Unknown mode"
      #endif
      Log('Mode = ' + IntToStr(Mode));
    end;