MSBUILD 14.0 Visual Studio 2015 CustomBuild Command environment does not contain the result of a SetEnv even though Exec does

444 views Asked by At

I have used CoApp to create a nuget package to package some code generators (binaries). I want to be able to use these code generators in a msbuild custombuild step to generate the code

I have a targets file that defines the following (using CoApp)

<SetEnv Condition="'$(Platform.ToLower())' == 'x64' And '$(PlatformToolset.ToLower())' == 'v100' And ( $(Configuration.ToLower().IndexOf('debug')) == -1 )" Name="PATH" Prefix="true" Value="$(MSBuildThisFileDirectory)../..//build/native/bin/x64\v100\Release;">
  <Output TaskParameter="OutputEnvironmentVariable" PropertyName="PATH" />
</SetEnv>

The targets file containing this snippet is imported like so into a project (vcxproj file)

<Import Project="..\packages\habitat.id.redist.1.0.0.5\build\native\habitat.id.redist.targets" Condition="Exists('packages\habitat.id.1.0.0.1\build\native\habitat.id.targets')" />

within the project

<Exec Command="echo %PATH%"/>

returns the desired outcome i.e. that which takes the form ../..//build/native/bin/x64\v100\Release;C:\

so I can call the executable that I want to run from the project. (except for unlike a custombuild command step there is no concept of outputs. So incremental builds will thence not work)

however

<CustomBuild Include="..\directory\filename">
  <FileType>Document</FileType>
  <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
  echo $(PATH)
</Command>

does not contain the path that I want that was set through the SetEnv.

I want to do this so I can call code generators that were packaged via nuget during a custom build step.

I understand that the command inside a custombuild runs through/in a new cmd and that the environment is inherited via the user or system env's that were set. Also that I can start Msbuild using /p:useenv , and hence pump any environment that I would like. This, using /p:useenv, in my opinion amounts to hard coding the path - knowing it ahead of time.

I want to be able to update my packages and run i.e. I want the project to manage the path given that it is defined in the target file that is imported.

1

There are 1 answers

0
Janitha Jayaweera On

Looks like C++ has a little ways to go until they can support package updates for binaries. The headers (ClCompile > AdditionalIncludeDirectories) and libs (Link > Additionaldependencies) are fine

I wanted to continue to use the custom build because it is exposed through the standard visual studio property sheet, a custom target is not (until you customize the property sheet hence introducing something that not everyone is familiar with, will forget to install and then complain) So I was hoping to get a product level solution that would come through the next product update. That looks unlikely

I was looking to continue to use the environment variable approach because that's the way CoApp does it for nuget package it creates for C++ binaries. It's easy enough to change the targets file. (Not using CoApp's Write-NugetPackage but use nuget pack instead)

A custombuild command does not expand msbuild properties set like:

<PropertyGroup Condition="'$(Platform.ToLower())' == 'x64' And '$(PlatformToolset.ToLower())' == 'v90'">
    <HabitatBindir>$(MSBuildThisFileDirectory)../..//build/native/bin/x64\v90\Release</HabitatBindir>
</PropertyGroup> 

and used like

<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(HabitatBindir)aemcomp.exe -nonotice -mlf -dll %(Identity)</Command> 

The Target-Exec-Property is the best combination I could come up with.