Search code examples
msbuildenvironment-variablesvcbuild

set vcbuild environment through msbuild


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!


Solution

  • 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 )