Using Visual Studio 2022 with a C++ solution.
The below property sheet is working fine:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<CopyFileToFolders Include="$(MSBuildThisFileDirectory)somefile.bin">
<DeploymentContent>true</DeploymentContent>
<FileType>Document</FileType>
<DestinationFolders>$(OutDir)</DestinationFolders>
</CopyFileToFolders>
</ItemGroup>
</Project>
But the below one is not working (when output directory is changed in project properties):
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<CustomDestination>$(OutDir)</CustomDestination>
</PropertyGroup>
<ItemGroup>
<CopyFileToFolders Include="$(MSBuildThisFileDirectory)somefile.bin">
<DeploymentContent>true</DeploymentContent>
<FileType>Document</FileType>
<DestinationFolders>$(CustomDestination)</DestinationFolders>
</CopyFileToFolders>
</ItemGroup>
</Project>
This makes sense as "CustomDestination" property is evaluated before "OutDir" is well-defined from VS IDE, on the contrary to the "CopyFileToFolder"->"DestinationFolders" item metadata which is evaluated after all properties.
Is there an elegant way to predefine "CustomDestination" with any value including some $(X) before the "CopyFileToFolders" item, so I can move both on separate property sheets ?
_
Additional note:
<PropertyGroup>
<CustomDestination>$(ProjectDir);$(SolutionDir)SomeDirectory</CustomDestination>
<UseOutDir>Yes</UseOutDir>
</PropertyGroup>
<ItemGroup>
<CopyFileToFolders Include="$(MSBuildThisFileDirectory)somefile.bin">
<DeploymentContent>true</DeploymentContent>
<FileType>Document</FileType>
<DestinationFolders Condition="'$(UseOutDir)' == ''">$(CustomDestination) </DestinationFolders>
<DestinationFolders Condition="'$(UseOutDir)' != ''">$(OutDir);$(CustomDestination) </DestinationFolders>
</CopyFileToFolders>
</ItemGroup>
But I was wondering if someone would come out with a more generic solution.
<PropertyGroup>
<CustomDestination>%24(OutDir);%24(ProjectDir)</CustomDestination>
</PropertyGroup>
<ItemGroup>
<CopyFileToFolders Include="$(MSBuildThisFileDirectory)somefile.bin">
<DeploymentContent>true</DeploymentContent>
<FileType>Document</FileType>
<DestinationFolders>$(CustomDestination)</DestinationFolders>
</CopyFileToFolders>
</ItemGroup>
But I don't know how to make VS/MSBuild to replace $(X) contents into $(CustomDestination) property value.
I found a solution !
Defining "CustomDestination" as a custom item value instead of a property makes it evaluated after properties, then with the latest $(OutDir) value.
<!--Define CustomDestination-->
<ItemGroup>
<CustomDestination Include="$(OutDir)" />
</ItemGroup>
<!--Print CustomDestination value in build output-->
<Target Name="PrintDestTarget" BeforeTargets="Build">
<Message Importance="high" Text="PrintDestTarget: CustomDestination = '@(CustomDestination)'" />
</Target>
<!--Use CustomDestination value to copy file-->
<ItemGroup>
<CopyFileToFolders Include="$(MSBuildThisFileDirectory)somefile.bin">
<DeploymentContent>true</DeploymentContent>
<FileType>Document</FileType>
<DestinationFolders>@(CustomDestination)</DestinationFolders>
</CopyFileToFolders>
</ItemGroup>
Note that the setup logic of items is different than properties:
<ItemGroup>
<CustomDestination Include="Smith" />
</ItemGroup>
<ItemGroup>
<CustomDestination Include="Adams" />
</ItemGroup>
<Target Name="PrintDestTarget" BeforeTargets="Build">
<Message Importance="high" Text="PrintDestTarget: CustomDestination = '@(CustomDestination)'" />
</Target>
Will output "Smith;Adams".
I am not shure if it is possible to modify an item value, but one can still define new ones as needed.