sourcenouveau
sourcenouveau

Reputation: 30554

Forcing a build when properties change in MSBuild

I have set up my build so that I can pass in a number as a build property:

msbuild MyProject.sln /t:Build /p:Configuration="Debug" /p:SomeNumber="123"

The MSBuild project generates a file and adds it via:

<Compile Include="$(SomeFileContainingSomeNumber)" />

This file is only generated if SomeNumber is specified.

When I change or omit the number and build a second time, the MSBuild projects do not get rebuilt with the new value. I believe this is because none of the project files have changed.

How can I set up my project so that changing the SomeNumber property triggers a rebuild?

Upvotes: 0

Views: 887

Answers (1)

sourcenouveau
sourcenouveau

Reputation: 30554

I'm using MSBuild 3.5. It seems that putting a Condition on a BeforeBuild Target interferes with its execution. When I moved the Condition from the Target to the individual actions within the target, I was able to get the desired behavior.

Using the following I was able to get MSBuild to compile properly every time, whether or not the SomeNumber property changed. The project may be rebuilding SomeFile.cs every time, whether or not its contents has changed, because its timestamp is changing.

<PropertyGroup>
    <SomeFile>SomeFile.cs</SomeFile>
</PropertyGroup>
<Target Name="BeforeClean">
    <Delete Files="$(SomeFile)" />
</Target>
<Target Name="BeforeBuild">
    <WriteLinesToFile Condition="'$(SomeNumber)' == ''" File="$(SomeFile)" Lines="//" Overwrite="true" />
    <WriteLinesToFile Condition="'$(SomeNumber)' != ''" File="$(SomeFile)" Lines="$(SomeNumber)" Overwrite="true" />
</Target>
<ItemGroup>
    <Compile Include="$(SomeFile)" />
</ItemGroup>

The Lines="//" is required because WriteLinesToFile will delete the file if you put nothing or whitespace there.

Upvotes: 1

Related Questions