Question

I currently have multiple projects being build using msbuild. I have a small customisation to the build that is handled by a .targets file. One solution is to add the snippet

<Import Project="MyTargets.targets"/>

to each project file. However, ideally I would like to not touch the project files, and be able to pass this information as a parameter to msbuild. That way I could easily control whether I run this customisation from the command line, and I don't have to touch the existing project files.

Is this possible?

Was it helpful?

Solution

You can do that easily with MSBuild 4.0 (check your version by top-level attribute ToolsVersion="4.0"):

There are multiple properties you can use to import your targets before and after Common.targets and or CSharp.targets loaded.

Simplest way is to use 2 sets of self explaining properties. First set is: $(CustomBeforeMicrosoftCommonTargets) $(CustomAfterMicrosoftCommonTargets)

and second one:

$(CustomBeforeMicrosoftCSharpTargets)
$(CustomAfterMicrosoftCSharpTargets)

Property names are pretty self-explained.

Just pass full file name to any of this properties via msbuild.exe e.g.

msbuild.exe /p:CustomBeforeMicrosoftCSharpTargets=c:\mytargets\custom.targets

You can use other "ImportByWildcard(Before|After)...." properties if you need to import multiple files. But in that case you need to pass more parameters to command-line.

OTHER TIPS

Starting from MSBuild 15.0, the following two files are auto-imported into your build in case they are found on the project path or in any parent folder on the path to the root directory:

  • Directory.Build.props
  • Directory.Build.targets

Remark: once the props or targets file is found, MSBuild will stop looking for a parent one.

Also see: https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build

Lets say you have a project file called "Project.msbuild". You would add this conditional import:

<Import Project="$(TargetToImport)" Condition="'$(TargetToImport)' != ''" />

Then pass the name of the target file you want to import as an msbuild property:

msbuild.exe Project.msbuild /p:TargetToImport="TargetFile.Target"

Make sure you use an absolute path to the target file and it works.
Source: Sayed Ibrahim Hashimi - MSBuild how to execute a target after CoreCompile part 2.

msbuild.exe /p:CustomBeforeMicrosoftCSharpTargets="c:\mytargets\custom.targets" /preprocess:out.xml

Use /preprocess[:filepath] to see the result of the imports.

You don't have to modify any csproj or vbproj files.
Of course, it only works where you can set MSBuild Properties.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top