Page MenuHomeFeedback Tracker

Nested #if statements with __has_include keyword result in 'Preprocessor failed with error - invalid filename(empty filename)'
Closed, DuplicatePublic

Description

My goal is a mod that will include various extra assets when certain combinations of mods/DLCs are present, but without having any of these as a "hard" dependency. I've been using #if __has_include() ... #endif to accomplish this for the simplest situations like the following config.cpp structures, which work fine...

...in these examples, I'm trying to avoid having the CSLA CDLC, and the GMX Takistan and GMX ChDKZ mods as "hard" dependencies...

class CfgPatches {
 <some code>
};

class CfgVehicles {
 class O_MBT_02_cannon_F;   // or any classname from a "hard" dependency

  #if __has_include("\gmx\gmx_tak\gmx_tak_core\data\gmx_tak_icon_ca.paa")
   class my_tak_mbt : O_MBT_02_cannon_F {};
  #endif

  #if __has_include("\gmx\gmx_chdkz\gmx_chdkz_core\data\logos\gmx_chdkz_logo_ca.paa")
   class my_chdkz_mbt : O_MBT_02_cannon_F {};
  #endif

};
#if __has_include("\csla_cfg\images\logos\csla_dlc_logo_ca.paa")

class CfgPatches {
  <some code>
  requiredAddons[] = {"CSLA"};
  <some more code>
};

class CfgVehicles {
    class CSLA_T72;
    class my_t72 : CSLA_T72 {};
};

#endif

However, if the extra assets are dependent on more than one of these "soft" dependencies, then I get the following error message on startup.
Preprocessor failed with error - invalid filename(empty filename)
Here's an example of dual "soft" dependency which results in the error...

#if __has_include("\csla_cfg\images\logos\csla_dlc_logo_ca.paa")

class CfgPatches {
  <some code>
  requiredAddons[] = {"CSLA"};
  <some more code>
};

class CfgVehicles {
    class CSLA_T72;

  #if __has_include("\gmx\gmx_tak\gmx_tak_core\data\gmx_tak_icon_ca.paa")
   class my_tak_t72 : CSLA_T72 {
     <change faction, crew, etc. to gmx_tak>
   };
  #endif

};

#endif

...And for good measure, I tried adding an #else statement, hoping it might force the first #if to step over the second #if; but it still errored.

#if __has_include("\csla_cfg\images\logos\csla_dlc_logo_ca.paa")

class CfgPatches {
  <some code>
  requiredAddons[] = {"CSLA"};
  <some more code>
};

class CfgVehicles {
    class CSLA_T72;

  #if __has_include("\gmx\gmx_tak\gmx_tak_core\data\gmx_tak_icon_ca.paa")
   class my_tak_t72 : CSLA_T72 {
     <change faction, crew, etc. to gmx_tak>
   };
  #endif

};

#else
#endif

Details

Severity
None
Resolution
Open
Reproducibility
Always
Operating System
Windows 10 x64
Operating System Version
n/a
Category
Modding
Steps To Reproduce

as above

Event Timeline

dmorchard created this task.Sep 7 2021, 3:57 AM
dmorchard added a comment.EditedSep 30 2021, 5:08 PM

I found a work-around: pull the nested #if... #endif structures out of the config.cpp into a separate HPP file.

...config.cpp contains this...

#if __has_include("\csla_cfg\images\logos\csla_dlc_logo_ca.paa")

class CfgPatches {
  <some code>
  requiredAddons[] = {"CSLA"};
  <some more code>
};

class CfgVehicles {
    class CSLA_T72;

  #include  "\dmo_dcx\_csla\t72\companions.hpp"

};

#endif

...and companions.hpp contains this...

#if __has_include("\gmx\gmx_tak\gmx_tak_core\data\gmx_tak_icon_ca.paa")
 class my_tak_t72 : CSLA_T72 {
   <change faction, crew, etc. to gmx_tak>
 };
#endif

The result is no preprocessor warning at startup. It seems like in the original configuration, nested #if...#endif structures, all within a single file, the top-level #if responds to the negative condition by searching for the next #endif, without regard to any nested #ifs that it encounters along the way. It should recognize that for every additional #if it encounters it needs to "hop over" the next #endif, but it seems to not be doing that.

I'm still getting this error in v2.06.

When I revert to the configuration described in my initial post, i.e. a second #if...#endif block nested inside an initial #if...#endif, and the initial block encounters its negative condition (in my case, the absence of the CSLA logo because that CDLC is not loaded) I still get Preprocessor failed with error - invalid filename(empty filename)