Question

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>
Was it helpful?

Solution

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

OTHER TIPS

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