0

I don't understand how the targets depend on each other and, most importantly, how variables travel through the target graph. I have a concrete example: The CSC target has the AddModules attribute/property. I want to set it using my .csproj file. As you'll see below, I've tried many different solutions, but I don't understand why one of them works while others don't. I've written some of my questions inside the code:

<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    <TargetFrameworkProfile>Profile88</TargetFrameworkProfile>
    <FileAlignment>512</FileAlignment>

    <!--1) Why don't I get fatal error here even though <AddModules> is invalid inside the <PropertyGroup>?"-->
    <!--2) Why doesn't this work (doesn't pass the AddModules to the CSC target unlike other properties like FileAlignment)?"-->
    <AddModules>$(OutputPath)Ark.Weak.netmodule</AddModules>

    <!--3) Why do I get the following fatal error here: "error  : The attribute "Include" in element <AddModules> is unrecognized."?-->
    <AddModules Include="$(OutputPath)Ark.Weak.netmodule" />
  </PropertyGroup>
  <ItemGroup>
    <!--4) Why do I get the following fatal error here? "error  : The reference to the built-in metadata "Extension" at position 1 is not allowed in this condition "'%(Extension)'=='netmodule'"."-->
    <AddModules Include="@(ReferencePath)" Condition="'%(Extension)'=='netmodule'" />

    <!--5) Why do I get the following fatal error here: "error  : The attribute "Remove" in element <ReferencePath> is unrecognized."?-->
    <ReferencePath Remove="@(AddModules)" />

    <!--6) Why does this work even though <AddModules> is invalid inside the <ItemGroup>?"-->
    <!--7) Why does this do the job (passes the AddModules to the CSC target)?"-->
    <AddModules Include="$(OutputPath)Ark.Weak.netmodule" />
  </ItemGroup>
</Project>
Ark-kun
  • 6,358
  • 2
  • 34
  • 70

1 Answers1

2

It's pretty complex question (about target dependency and variables travelling) and answer can be a full blown article or presentation about msbuild if we dig into details.

I'll try to answer your code-sample questions and try be as brief as possible. Feel free to ask more about details.

  1. AddModules is not invalid inside PropertyGroup - you just created a new property with the name AddModules.

  2. According to what I found - csc task looking for item with name AddModule, not property one. To be simple - Msbuild Items is kind of array, property is string. @(AddModule) syntax mean that it's expecting array of entries (which will be joined to comma-separated string with @() construction )

  3. Properties doesn't have Include attribute, Only Condition is allowed.Check this reference

  4. ReferencePath is a property in that case (I think), it doesn't contain metadata at all. There will be a item with that name after ResolveAssemblyReference target will be called. In this case I think it hadn't called yet.

  5. Remove attribute applicable only to "file"-type members, not for arbitrary string-type members. But I still suspect this error is because you don't have @(ReferencePath) item yet on that moment.Check this reference about little more details into Remove attribute.

  6. It is not invalid. It's just the name of variable. So it's completely legit there.

  7. Because csc expects item as parameter, and this statement creates it and emits as global variable. Every target that will be triggered in that same context could have access to this very item using @(AddModule) syntax

Alexey Shcherbak
  • 3,394
  • 2
  • 27
  • 44
  • 1,6: By `invalid` I meant "doesn't conform to the schema" and "sometimes produces warnings about a wrong child element". – Ark-kun Jan 08 '13 at 18:28
  • So it was strange to see that "invalid" elements are ok, but they cannot have any attributes other then `Condition`. Now I start to understand that the latter is probably enforced by MSBuild, not just the schema. – Ark-kun Jan 08 '13 at 18:30
  • 4. So, the problem with this line is with the `ReferencePath`, not `Extension` (like the error said)? – Ark-kun Jan 08 '13 at 18:30
  • 1,6 and following comment: Check this full schema reference for all allowed tags and attributes - http://msdn.microsoft.com/en-us/library/5dy88c2e.aspx . Property Item have exact one attribute allowed - "Condition" (this why you have 3.) – Alexey Shcherbak Jan 09 '13 at 08:44
  • 4. This is a bit trickier one. I make some tests and studies and also found this http://stackoverflow.com/questions/3265632/. Looks like Rory (from mentioned link) is right and here we hit same problem - % is for batching and batching is not allowed in global scope. But it will work fine in target's scope. Move your declaration inside the target, where you need it and it will work. I think you can simplify it a little by using , so you can get rid of intermediate collection – Alexey Shcherbak Jan 09 '13 at 08:46
  • Thanks for a thorough answer! – Ark-kun Jan 10 '13 at 12:44