2

I have an MSBuild target which transforms a file in place, that is the input and output file is the same file. How do I get Visual Studio to handle the integration build properly in this case? Must I necessarily move the file?

1 Answer 1

1

A short answer: never transform file in place during the build. Any transformation should necessarily create a new file in some other location, or with a different name.

Long answer. MSBuild tracks if file is up-to-date based on time stamps. This is the same mechanism used by make and most of other build systems. This allows your incremental builds perform a partial rebuild of only necessary build steps. Note, that in order to make incremental builds work, you have to declare all input and output files in target's Inputs and Outputs attributes. If you have the same file in Inputs as well as in Outputs, it will be considered up-to-date and target would not be executed, which breaks your build.

If you don't care about incremental build, you can actually make it work, by simply creating a target that has no Inputs and Outputs. In this case target will always be executed. That comes with a price that you are doing full build every time.

Sign up to request clarification or add additional context in comments.

9 Comments

I found this: github.com/Fody/Fody/blob/master/NuGet/Fody.targets, it looks like Simon Cropp decided to make the inputs be the inputs of the post-compile build steps and the outputs be the outputs of the post-compile build steps. To my understanding, he IL weaves the file in place directly after compilation, then the subsequent build steps move the intermediate assembly to the target path. Fody pretends that its output is the target path, even though the operation is actually in place. What do you think of this approach?
@BigEndian, the Fody.targets has to be considered in the context of a project it is executing. Assuming the Fody task is the only task that produces $(TargetPath), then everything would be fine. However if there is some other target that also updates $(TargetPath), this will break the build, or in worst case would make the build unpredictable.
Fody weaver doesn't change the $(TargetPath), it just specifies it as its output... It doesn't even drop a file there.
@BigEndian, does it produce any files that are used by end user, or some other target? If so, they should be declared as outputs, otherwise your incremental build will be broken.
@BigEndian, ok, it makes better sense now. As you are describing here, the Fody target is broken. One example of the scenario where it is broken is when user wants to invoke Fody target, but does not need to generate $(TargetPath). In this case Fody target will be invoked and does the right thing the first time. The next time you do incremental build without changing inputs, the Fody will detect that $(TargetPath) is still missing and would have to be executed again. So, your incremental build will do more work than needed. If you don't care about incremental builds, Fody is fine.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.