views:

426

answers:

3

Please go easy I am new to msbuild and msbuildtasks!

How can I set a property which represents a relative file path to a targets file which I want to import? I need relative references so it will work on all dev machines. But the target for import is trying to use the relative file path internally, which won't work as it is re-evaluated relative to the imported target!

Effectively I am trying to work around the documented behaviour of imported projects:

All relative paths in imported projects are interpreted relative to the directory of the imported 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 imported project.

+1  A: 

There was a similar question at http://stackoverflow.com/questions/1776962/msbuild-extension-pack. That question was how to do the same with the MSBuild Extension Pack, both of which are similar in this aspect. For the Extension Pack you have to declare the property ExtensionTasksPath,and for the Community tasks you have to declare a similar property named MSBuildCommunityTasksLib. So in your case it should look like:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt;
  <PropertyGroup>
    <MSBuildCommunityTasksLibCondition="'$(MSBuildCommunityTasksLib)' == ''">E:\Data\Development\My Code\Community\MSBuild\CommunityTasks\</MSBuildCommunityTasksLib>
  </PropertyGroup>

  <Import Project="$(MSBuildCommunityTasksLib)MSBuild.Community.Tasks.Targets"/>

  <Target Name="Demo">
    <!-- Use the tasks here -->
  </Target>

</Project>
Sayed Ibrahim Hashimi
But these are absolute file paths no? Or am I missunderstanding? I need to reference it with a relative file path, or at least to be able to convert the relative file path at runtime.
Noel Kennedy
Most of the tools require a full path to work properly. I've set up a couple of variables in a .proj that I incude in all of my 'working' .proj files. These variables contain the fixed part of paths for various things. In a Property Group: <SolutionRoot>$(WorkingDrive)$(SolutionFolder)\$(Branch)\NET\BuildOut$(Configuration)</SolutionRoot> $(SolutionFolder) is built from other things, like the Major-Minor build number etc. (Specific to our setup) Then the other .proj files import it: <Import Project="AlliantBuildProperties.proj"/>
DaveE
You should be able to build a full path from relative path. You can use properties like MSBuildProjectDirectory.
Sayed Ibrahim Hashimi
A: 

This appears to be one answer:

http://social.msdn.microsoft.com/forums/en-US/msbuild/thread/feb782e3-72ae-4476-9011-617796f217b6

But this (if I understand it correctly) appears to be a ridiculous solution. To get the paths to work I need to change the imported project references? What would happen if I wanted to reference the imported project from third project in another folder?!?

Noel Kennedy
A: 

Ok, I've found the answer. Essentially you have to set the property MSBuildCommunityTasksPath as a relative path back to the original containing directory.

For example, given a folder structure like this:

Root---project---Build---{My msbuild project}
           |
           |-Tools---MSBuildCommunityTasks---{Binaries and Targets}
Where :
{My msbuild project} is in Root\Project\Build\
{MSbuildCommunityTasks} is in Root\Project\Tools\MsBuildCommunityTasks

To get the targets project to reference its binaries via the property MSBuildCommunityTasksPath, it will find the tasks file like this:

<PropertyGroup>
    <MSBuildCommunityTasksPath>..\MSBuildCommunityTasks\</MSBuildCommunityTasksPath> <!--Relative path back to yourself-->
</PropertyGroup>

Then you can import the targets file with another relative file reference :

  <Import Project="..\..\Tools\MSBuildCommunityTasks\MsBuild.Community.Tasks.Targets"/>
Noel Kennedy