1

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.

Community
  • 1
  • 1
Craig Ringer
  • 307,061
  • 76
  • 688
  • 778
  • `'$(Platform)' = 'x64'` shouldn't that be `'$(Platform)' == 'x64'` ? Also in such cases it's best to add a `Message` task (in the PreBuild event for instance) to print out the value of PGBASEDIR so at least you know what it's doing – stijn Sep 17 '14 at 11:36
  • @stijn Yes it should. Correcting that doesn't change the output. A `Message` task shows the correct `PGBASEDIR` when the build is run, but outputs nothing when the project is opened and VS starts highlighting everything with complaints about missing headers - as you'd expect as IntelliSense doesn't run any build steps. – Craig Ringer Sep 17 '14 at 12:11

2 Answers2

4

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>
ThomasMcLeod
  • 7,603
  • 4
  • 42
  • 80
jessehouwing
  • 106,458
  • 22
  • 256
  • 341
0

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.

JDługosz
  • 5,592
  • 3
  • 24
  • 45