none
MSBUILD CustomBuild Command environment does not contain the result of a SetEnv even though Exec does. Properties are not expanded either RRS feed

  • Question

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

    An Alternative is to try to user the following

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


    to be used like this

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

    But the $(HabitatBindir) is not expanded so the binary cannot be found.

    It could also be argued that a target with an exec could be used which will correct expand/resolve the property as well as the environment variable. But access to the %(Identity) Macro as well as %(FileName) Macros are lost.

    aemcomp is a code generator. The generated code is then compiled to create a dll. As stated above I would like to package the code generators as nuget packages. The need to resolve the path dynamically is so I can upgrade my packages and call the new code generators from the new packages

    This question has also been asked here

    stack exchange

    and here

    github issue 582

    It looks like the C++ support for nuget is incomplete


    • Edited by janitha_j Tuesday, April 19, 2016 11:53 PM
    Tuesday, April 19, 2016 11:51 PM

Answers

  • Hi janitha_j,

    >> The need to resolve the path dynamically is so I can upgrade my packages and call the new code generators from the new packages

    For this, you’d better use the MSBuild predefined property MSBuildProjectDirectory” to get path dynamically. Then, you’d better place your tool in the same folder with your proj file.

    https://msdn.microsoft.com/en-us/library/ms164309.aspx

    When you want to run custom build command, you’d better also specify when it would be run by using CustomBuildBeforeTargets and CustomBuildAfterTargets. Because of that if neither element is specified, your custom build tool executes at its default location, which is before the MIDL target, maybe it’s not what you want.

    https://msdn.microsoft.com/en-us/library/dd293705.aspx

    Best Regards,
    Li Wang

    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Thursday, April 21, 2016 7:13 AM