views:

695

answers:

2

I have an msbuild project file that is used for building several C++ projects (*.vcproj). Here's a part of a typical project file, in which global environment variables for the build are overridden as properties:

<PropertyGroup>
  <MYBINDIR>d:\buildsysroot\bin</MYBINDIR>
  <MYLIBDIR>d:\buildsysroot\lib</MYLIBDIR>
  ...
</PrpertyGroup>

<ItemGroup>
  <MyItems Include="d:\buildsysroot\myproject\myproject.vcproj"/>
</ItemGroup>

<Target Name="Release_x64">
  <VCBuild Projects="@(MyItems)" Configuration="Release_dll|x64"/>
</Target>

These environment variables are used by all vcproj files, through property sheets. Here's an excerpt of a vcproj:

<Configuration
  Name="Release_dll|x64"
  ConfigurationType="1"
  InheritedPropertySheets="$(BUILDPROPSDIR)\defaults.vsprops;$(BUILDPROPSDIR)\build_dll.vsprops"
>

And this is how the property sheets look:

<VisualStudioPropertySheet
  Name="defaults"
  OutputDirectory="$(MYBINDIR)\_$(ConfigurationName)_$(PlatformName)"
  IntermediateDirectory="$(MYBUILDDIR)_$(ProjectName)_$(ConfigurationName)_$(PlatformName)"
  >
  <Tool
    Name="VCLinkerTool"
    AdditionalLibraryDirectories="&quot;$(MYLIBDIR)&quot;"
  />
<VisualStudioPropertySheet/>

The problem is: when building, the value for the environment variables declared in the msbuild file (MYBINDIR, MYLIBDIR) do not make it into the property sheets, but seem to be local to the msbuild file only: within the msbuild project MYBINDIR expands to "d:\buildsysroot\bin", but within the vc project MYBINDIR expands to "d:\projects\bin", which is the value that I set globally (eg via MyComputer->Advanced->EnvironmentVariables) and which must stay there because it's how my main development environment is set up.

How do I pass the environment set in the msbuild file to the VCBuild task?

I know that this problem could be solved by using a batch file and declaring the environment there using 'set', and not in the msbuild file; that's how I used to do it, but I prefer the method above as it's just one call to msbuild with one argument and that's it.

EDIT

I needed a solution quickly and came up with a custom task that sets the environment in the same way a batch file would do, but with the bonus of doing it within msbuild.. The tasks's Execute() method simply does Environment.SetEnvironmentVariable( var, val ). This still requires setting the proces' environment, I'd be glad to hear if there is another way!

A: 

since nobody else answered/commented I'm going with my own answer: a custom task that sets the process' environment using Environment.SetEnvironmentVariable( var, val )

stijn
A: 

I don't know if this goes to what you're trying to do. But have you tried the "Override" attribute on the VCBuild task? It's not glaringly obvious how to use it. But I had VS create a .vsprops for me with the attributes I cared about (OutputDirectory and IntermediateDirectory). Then I edited the .vcproj file to remove the InheritedPropertySheets attribute that it had added. Then I added an Override attribute to the VCBuild task in my MSBuild file. That seems to have given me the behavior I was looking for. Might be a different problem, though...

Donnie

soccerdad
thanks for the idea: it would indeed be possible to create a custom property sheet that uses environment variables in the main msbuild project file (using WriteLinesToFile; since it gets done in the main file all vars work as exepcted). Now, each of my projects uses like 3 property sheets that use environment variables, so with this approach I'd basically be rewriting all these prop sheets before each build, possibly introducing mismatches with the original prop sheets, so I'll just stick with setting the process environment
stijn