views:

57

answers:

2

I want to use MSBuild to grab and create the relevent elements for 2 files. If it was just a single file extension, I would use:

<ItemGroup>
    <Compile Include="\Pages\*.cs" /> 
</ItemGroup>

In a .csproj file for a Silverlight build, each UserControl is set like with it's own <Compile> element and a child <DependentUpon> element:

<ItemGroup>
    <Compile Include="Pages\SilverlightControl1.xaml.cs">
        <DependentUpon>SilverlightControl1.xaml</DependentUpon>
    </Compile>
    <Compile Include="Pages\SilverlightControl2.xaml.cs">
        <DependentUpon>SilverlightControl2.xaml</DependentUpon>
    </Compile>
</ItemGroup>

In the MSBuild file, I'd like to specify:

grab all the .cs files and put those in the Include attribute and get the same file name - minus the .cs and put that in the <DependentUpon> element.

So that it would just be something like (pseudo) to match the file pairs:

<ItemGroup>
    <Compile Include="Pages\*.cs">
        <DependentUpon>Pages\*.xaml</DependentUpon>
    </Compile>
</ItemGroup>

Is there a way to do put the above in MSBuild?

+2  A: 

In MsBuild you can do like the below :

<ItemGroup>
        <ClassFiles Include="**\*.cs"/>
        <XamlFiles Include="**\*.xaml"/>
        <Compile  Include="@(ClassFiles)" > 
            <DependentUpon>"@(XamlFiles)"</DependentUpon>
        </Compile>
     </ItemGroup>

Is this what you want or i am far from your question?

Malcolm
Thanks Malcolm, I'll see if I can get this to work.
Otaku
+4  A: 

MSBuild has two separate metadata properties called %(Filename) (which is the filename without the extension) and %(Extension) which would be the ".cs" in your example. So, I wonder if this is possible:

<ItemGroup>
    <Compile Include="Pages\*.cs">
        <DependentUpon>%(Directory)%(Filename)</DependentUpon>
    </Compile>
</ItemGroup>

But, I don't think you will like what it's gonna do or even do what you want it to do.

You really should only ever have "glob" type items (*.cs) within a target - you should not declare it as a top level item group, otherwise it will do funny things in visual studio and (for example) will add all the .cs files to version control and maybe even expand the *.cs into individual items in your project.

Here's what I would suggest in a NON Visual Studio msbuild project:

<Target Name="PrepareCompileItems">
    <XamlFiles Include="Pages\*.cs">
        <DependentUpon>%(Directory)%(Filename)</DependentUpon>
    </XamlFiles>

    <Compile Include="@(XamlFiles)" />
</Target>

If you were doing this within a VS project, then it's tricker - cos you want to add metadata to an already existing itemgroup to force the dependentUpon association before compile:

<Target Name="AddDependentUponMetadata">
    <CsFiles Include="Pages\*.cs" />

    <XamlFiles Include="@(CsFiles)">
        <DependentUpon>%(Directory)%(Filename)</DependentUpon>
    </XamlFiles>

    <Compile Remove="@(CsFiles)" />    
    <Compile Include="@(XamlFiles)" />
</Target>

Although, I'm typing this without actually testing my assertions so YMMV...

Peter McEvoy
Thanks Peter, I'll toy around with this and see if I can get it to work.
Otaku