Conditional properties for include paths break IntelliSense editing?

1.2k Views Asked by At

I have a build where some include and library paths must differ based on whether the build is 32-bit or 64-bit, and must be parameterised for easy editing by the user. I'm using property sheets to deal with that requirement.

After learning of conditional properties I thought I'd try to get rid of the hack of using per-platform property sheets to set macros based on values from the master property sheet (e.g. set PGBASEDIR from $(PGBASEDIR_x64) on x64, and $(PGBASEDIR_x86) on x86; for details see the answer to the question linked above).

I switched to using conditional properties in my msbuild target file instead, but found that while the build its self worked, VS's editor couldn't find the include files whose path is specified by the conditional properties. The same is true if I set the properties in a conditional property group in the property sheet .props file, or add individual conditional properties to the main property group.

So I've tried this in both the msbuild target file:

<PropertyGroup Condition="'$(Platform)' == 'x64'">
  <PGBASEDIR>$(PGBASEDIR_x64)</PGBASEDIR>
</PropertyGroup>
<PropertyGroup Condition="'$(Platform)' == 'Win32'">
  <PGBASEDIR>$(PGBASEDIR_x86)</PGBASEDIR>
</PropertyGroup>

and have also tried adding the same to the property sheet file that's included in all build configurations/platforms. Same result. I also tried using individual conditional properties within the main <PropertyGroup Label="UserMacros"> block for the property sheet; again, same effect.

When I examine the macros list in a Visual Studio by going to a project property, editing it, and tabbing open the MACROS> list in the UI, I see the macros that're defined statically in the property sheet, but not the conditional macros.

I tried adding <BuildMacro> entries to the master property sheet's <ItemGroup> in case that was the issue, e.g.:

<BuildMacro Include="PGBASEDIR">
  <Value>$(PGBASEDIR)</Value>
</BuildMacro>

... but saw no change.

In all cases the build its self runs fine, but Visual Studio's editor complains that it can't find the headers (and therefore anything defined within them).

If I stick with stacked property sheets it works, e.g.:

  • pg_sysdatetime project

    • Release | win32
    • pg_sysdatetime.props

        <PropertyGroup Label="UserMacros">
          <PGMAJORVERSION>9.2</PGMAJORVERSION>
          <PGBASEDIR_x64>$(PROGRAMW6432)\PostgreSQL\$(PGMAJORVERSION)</PGBASEDIR_x64>
          <PGBASEDIR_x86>$(MSBUILDPROGRAMFILES32)\PostgreSQL\$(PGMAJORVERSION)</PGBASEDIR_x86>
        </PropertyGroup>
        <PropertyGroup />
        <ItemDefinitionGroup />
        <ItemGroup>
          <BuildMacro Include="PGMAJORVERSION">
            <Value>$(PGMAJORVERSION)</Value>
          </BuildMacro>
          <BuildMacro Include="PGBASEDIR_x64">
            <Value>$(PGBASEDIR_x64)</Value>
          </BuildMacro>
          <BuildMacro Include="PGBASEDIR_x86">
            <Value>$(PGBASEDIR_x86)</Value>
          </BuildMacro>
        </ItemGroup>
      
    • pg_sysdatetime_x86.props

      • defines <PGBASEDIR>$(PGBASEDIR_x86)</PGBASEDIR>
    • Release | x64
    • pg_sysdatetime.props
      • ... same as above ...
    • pg_sysdatetime_x64.props
      • defines <PGBASEDIR>$(PGBASEDIR_x64)</PGBASEDIR>

I'm using Visual Studio 2012 Express.

2

There are 2 best solutions below

1
jessehouwing On

In these cases it's usually best to use the <CHOOSE><WHEN> construct.

So you'd probably end up with:

 <Choose>
    <When Condition="'$(Platform)' == 'x64'">
       <PropertyGroup>
         <PGBASEDIR>$(PGBASEDIR_x64)</PGBASEDIR>
       </PropertyGroup>
    </When>

    <When Condition="'$(Platform)' == 'win32'">
       <PropertyGroup>
         <PGBASEDIR>$(PGBASEDIR_x86)</PGBASEDIR>
       </PropertyGroup>
    </When>

    <Otherwise> <!-- Default -->
       <PropertyGroup>
         <PGBASEDIR>$(PGBASEDIR)</PGBASEDIR>
       </PropertyGroup>
    </Otherwise>
 </Choose>
0
JDługosz On

Hmm, I recall a property that is used to indicate a normal build vs a partial build for things like intellisence and design-time editors to use. Maybe there is some short circuit that skips over your path settings in this case. Using MSBuild Explorer 3, I see some properties with names like ProjectDesignTime* so maybe a different include path is used by Intellisense.

I think what you really want is to find out how MSBuild is being called for Intellisense processing. I wonder if it could log to a file so you could see what was happening and when it was processed?

Try using the unsupported feature of debugging MSBuild evaluation. “Do a Bing search on "Debugging MSBuild" and be sure to locate all three parts of the blog posting.” by Dan Moseley of the MSBuild team at Microsoft.