Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When does MSBuild set the $(ProjectName) property?

I'm fairly new to MSBuild, and I've done some customization on a WPF project file that I'm building both in Visual Studio 2010 and TFS 2010. I've customized the output path as follows:

<OutputPath Condition=" '$(TeamBuildOutDir)' == '' ">$(SolutionDir)build\binaries\$(ProjectName)\$(Configuration)\$(Platform)</OutputPath>
<OutputPath Condition=" '$(TeamBuildOutDir)' != '' ">$(TeamBuildOutDir)binaries\$(ProjectName)\$(Configuration)\$(Platform)</OutputPath>

This allows me to build to a centralized binaries directory when building on the desktop, and allows TFS to find the binaries when CI builds are running.

However, it seems that in both cases, the $(ProjectDir) property is evaluating to '' at build time, which creates strange results. Doing some debugging, it appears as if $(ProjectName) is set by the time BeforeBuild executes, but that my OutputPath property is evaluating it prior to that point.

<ProjectNameUsedTooEarly Condition=" '$(ProjectName)' == '' ">true</ProjectNameUsedTooEarly>

The preceding property is in the same property group as my OutputPath property. In the BeforeBuild target, $(ProjectNameUsedTooEarly) evaluates to true, but $(ProjectName) evaluates to the project name as normal by that point.

What can I do to ensure that $(ProjectName) has got a value when I use it?

I just used Attrice's MSBuild Sidekick to debug through my build file, and in the very first target available for breakpoint (_CheckForInvalidConfigurationAndPlatform) all the properties seem to be set already. ProjectName is already set correctly, but my OutputPath property has already been set using the blank value of ProjectName.

like image 440
bwerks Avatar asked Apr 15 '10 17:04

bwerks


People also ask

Where are MSBuild properties set?

MSBuild lets you set properties on the command line by using the -property (or -p) switch. These global property values override property values that are set in the project file. This includes environment properties, but does not include reserved properties, which cannot be changed.

What is $( TargetPath?

$(TargetPath)The absolute path name of the primary output file for the build (defined as drive + path + base name + file extension).

Where is $( MSBuildProjectDirectory?

MSBuild has reserved property called MSBuildProjectDirectory , which is to the absolute path of the directory where you project or script file is located, C:\Dev in your case. Therefore "$(MSBuildProjectDirectory)\temp" is exactly what you're looking for.

How do I set environment variables in MSBuild?

Click on System and Security and then on System. In the left pane, click on Advanced system settings. At the very bottom of the pop up, click on Environment Variables. Edit the Path variable and append the folder's path that contains the MSBuild.exe to it (e.g., ;C:\Windows\Microsoft.NET\Framework64\v4.


1 Answers

Hmm - bit of confusion going on there which I'll try to sort out

  1. Don't use $(ProjectDir) - use $(MSBuildProjectDir) - that's the location of your csproj in the source tree and is set by MSBuild.exe as a reserved property. I don't think $(ProjectDir) is available until after Microsoft.Common.Targets has been imported (which is done by Microsoft.Csharp.targets). Property evaluation is always carried out "in-place" within the file, and not when all the Imports have completed. This may explain why you are seeing the property as valid in the SideKick tool

  2. Likewise use $(MSBuildProjectName) (which I think will address your problem)

  3. I'm unsure about VS2010 and TFS2010 (as that uses MSBuild 4.0 and no doubt a new TeamBuild), but in 2008, it's pretty hard within a .csproj to figure out if your build was called from a command line/IDE build or from within TeamBuild. What I'm trying to say is that I don't think $(TeamBuildOutDir) is available within your csproj. I normally test $(TeamBuildConstants) property, as that property is passed down when teambuild calls your proj file. YMMV as I haven't played with 2010 yet..

like image 75
Peter McEvoy Avatar answered Oct 01 '22 01:10

Peter McEvoy