usethesametargetinmultipleprojectfiles

Cancel Edit [WikiEntry.PreviewButtonText] Save

Use the Same Target in Multiple Project Files

If you have authored several MSBuild project files, you might have discovered that you need to use the same tasks and targets in different project files. Instead of including the complete description of those tasks or targets in every project file, you can save a target in a separate project file and then import that project into any other project that needs to use the target.
In this example, the Build target is saved as a separate file (*MyCommon.targets*) and the "MyApp" project file imports that target.

Import Element

The Import element is used to insert one project file into another project file. The project file that is being imported must be a valid MSBuild project file and contain well-formed XML. The Project attribute specifies the path to the imported project file. The path can be either the full path

<Import Project="C:\Shared\MyCommon.targets"/>

or the path relative to the importing project:

<Import Project="..\..\Shared\MyCommon.targets"/>

A project file can contain any number of Import elements. The Import element must be a child element of the root element Project but can be located anywhere in the project file. In this example, the project imports the Build target that is defined in the *MyCommon.targets* file:

<Project
DefaultTargets="Build"
xmlns=”http://schemas.microsoft.com/developer/msbuild/2003”>
<Import Project="C:\Shared\MyCommon.targets"/>
</Project>

Imported Projects

Note the following information about imported projects:
* The file extension of the imported project file should be .targets. MSBuild does not prevent you from importing a project with a different file extension but the .targets file extension is recommended for consistency.
* All relative paths in imported projects are interpreted relative to the directory of the importing project. Therefore, if a project file is imported into several project files in different locations, the relative paths in the imported project file will be interpreted differently for each importing project.
* All MSBuild reserved properties that relate to the project file, for example, *MSBuildProjectDirectory* and *MSBuildProjectFilename*, that are referenced in an imported project are assigned values based on the importing project file.
* If the root Project element of the imported project has a DefaultTargets attribute, that attribute is ignored. Only the importing project can specify default targets.
* The schema of an imported project is identical to that of a standard project. It is possible that MSBuild can build an imported project but the build will probably fail because the imported project does not usually contain information about which properties to set or the order in which to run targets. The imported project depends on the project into which it is imported to provide that information.

Order of Evaluation in a Project File

When a project starts building, all the properties are evaluated first, then all the items in the project are evaluated. The order of evaluation is very important when a project imports other projects. When MSBuild reaches an Import element, the imported project is effectively inserted into the importing project at the location of the Import element. Therefore, the location of the Import element can affect the values of properties and items. This example uses the imported project *MyCommon.targets*:

<Project xmlns=”http://schemas.microsoft.com/developer/msbuild/2003”>
<PropertyGroup>
<Name>MyCommon</Name>
</PropertyGroup>

<Target Name="Go">
<Message Text="Name="$(Name)""/>
</Target>
</Project>

When this project is imported into the project *MyApp.proj* in the following location:

<Project
DefaultTargets="Go"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Name>Myapp</Name>
</PropertyGroup>
<Import Project="MyCommon.targets"/>
</Project>

the message that is displayed when *MyApp.proj* is built is:

Name="MyCommon"

Because the project is imported after the property Name has been defined in *MyApp.proj*, the definition of Name in *MyCommon.targets* overrides the definition in *MyApp.proj*. If, instead, the project is imported before the property Name is defined:

<Project
DefaultTargets="Go"
xmlns=”http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="MyCommon.targets"/>
<PropertyGroup>
<Name>MyApp</Name>
</PropertyGroup>
<Project>

the message that is displayed when *MyApp.proj* is built is:

Name="MyApp"

It is important to place the Import element in the correct location in the project file. Use the following approach when importing projects:

* Define, in the project file, all properties and items that are used as parameters for properties and items in the imported project.
* Import the project.
* Define in the project file all properties and items that must override default definitions of properties and items in the imported project

Project Files

Download Code - C#

Visual C# example


*MyCommon.targets*:

		    <Project 
	
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<PropertyGroup>
<Flavor Condition="'$(Flavor)'==''">DEBUG</Flavor>
<Optimize Condition="'$(Flavor)'=='RETAIL'">yes</Optimize>
<appname>$(MSBuildProjectName)</appname>
</PropertyGroup>

<Target Name="Build">

<Csc
Sources="hello.cs"
Optimize="$(Optimize)"
OutputAssembly="$(appname).exe"/>

</Target>

		    </Project>
	

*MyApp.proj*:

		    <Project 
	
DefaultTargets="Build"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<PropertyGroup>
<Flavor>RETAIL</Flavor>
<appname>hello</appname>
</PropertyGroup>

<Import Project="MyCommon.targets"/>

		    </Project>
	
Microsoft Communities