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:
- I came out with the below workaround consisting in managing $(OutDir) separately like this:
<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.
- I also tried something like this:
<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.
6
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.
From looking at your property sheet, it seems you want to copy somefile.bin
to your custom path. I copied your property sheet (You said the one is not working) to my local c++ project for test and it worked fine. It can recognize $(CustomDestination)
defined in PropertyGroup.
Here is my test result:
ENV: Visual Studio 2022(17.10.4)
But the below one is not working
Do you mean the task CopyFileToFolders
is unable to copy somefile.bin
file to your custom destination or it can not evaluate $(CustomDestination)
? And could you see warning/error messages during the build process?
If you want to make sure whether “CustomDestination” property is evaluated before “CopyFileToFolders” item, you can directly print their values.
<Target Name="test">
<Message Text="'%(CopyFileToFolders.FileType)'" />
<Message Text="'%(CopyFileToFolders.DestinationFolders)'" />
</Target>
1