MSBuild - 如何将%(Compile.Identity)转换为带有其他扩展名的文件名?

时间:2018-05-10 18:10:36

标签: msbuild transformation

我正在研究MsBuild。作为一项实际工作,我准备了一个* .proj文件来构建简单的“hello,world”C ++应用程序。事情进展顺利,但在我向“编译”目标添加一行后失败了 - 我找不到如何准备链接器使用的* .obj文件列表。

注意:* Microsoft(R)Build Engine版本4.7.2558.0(这只是来自“C:\ Windows \ Microsoft.NET \ Framework \ v4.0.30319”dir的MsBuild.exe)

这是我的* .proj文件:

    <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">

        <PropertyGroup>
            <SourceDir>D:\BuildProc\cpp1</SourceDir>

            <OutputPath>$(MSBuildProjectDirectory)\Bin\</OutputPath>
            <ExecutableName>MyCppSample</ExecutableName>
            [...]       
        </PropertyGroup>

        <ItemGroup>
            <Compile Include="hello.cpp"/>
            <Compile Include="main.cpp"/>
        </ItemGroup>

        <Target Name="Build" DependsOnTargets="CopyFiles;Compile;Link"
            Inputs="@(Compile)" 
            Outputs="$(OutputPath)$(ExecutableName).exe">

            <MakeDir Directories="$(OutputPath)" Condition="!Exists('$(OutputPath)')" />
        </Target>

        <Target Name="CopyFiles" 
            Inputs="@(Compile->'$(SourceDir)\%(Filename)%(Extension)')" 
            Outputs="@(Compile->'$(OutputPath)\%(Filename)%(Extension)')">

            <Copy SourceFiles="@(Compile->'$(SourceDir)\%(Filename)%(Extension)')" DestinationFolder="$(OutputPath)" />
        </Target>

        <Target Name="Compile" 
            Inputs="@(Compile->'$(OutputPath)\%(Filename)%(Extension)')" 
            Outputs="@(Compile->'$(OutputPath)\%(Filename).obj')">

            <Exec Command="@echo === %(Compile.Identity)" />
            <ExecEx Filename="cl" Arguments="%(Compile.Identity) $(CLOptions) -I$(SourceDir)" WorkingDir="bin" />

            <!-- here it fail! :-( -->
            <Exec Command="echo %(Compile.Identity->'%(Filename).obj') >> $(OutputPath)\$(ExecutableName).link " />

        </Target>

        <Target Name="Link" 
            Inputs="@(Compile->'$(OutputPath)\%(Filename).obj')" 
            Outputs="$(OutputPath)\$(ExecutableName).exe">      

            <Exec Command="@echo === Linking..." />
            <ExecEx Filename="link" Arguments="$(LibPath) $(Libs) $(LinkOptions) @$(ExecutableName).link" WorkingDir="bin" />
        </Target>

    </Project>

注意:是我开发的一个简单的MsBuild任务。这只是.NET ProcessStartInfo和Process类的简单包装器。它工作正常。

目标清洁,CopeFiles工作正常。在我添加echo命令并重定向到* .link文件之前,Target Compile工作正常。

问题是 - 在我将echo添加到* .link文件后,它开始报告编译目标中的错误:

错误讯息:

D:\ BuildProc \ msbld06 \ build06.proj(73,9):错误MSB4095:正在引用项目元数据%(文件名)而没有项目名称。指定th 项目名称使用%(itemname.Filename)。

这是我的* .proj文件中的一行,导致提到错误:

<Exec Command="echo %(Compile.Identity->'%(Filename).obj') >> $(OutputPath)\$(ExecutableName).link " />

所以,我需要以某种方式将{filename} .obj输出到$(OutputPath)\ $(ExecutableName).link文件中,然后将该文件用作链接器的@ -parameter。我尝试使用其他形式,但都失败了。所以,寻找提示......

在这种情况下对我来说理解更重要 - 如果可能的话,如何通过%(Compile.Identity)完全转换来实现这一点。 并且只作为第二步,也许你可以推荐其他方式来做同样的事情(我的想法是不使用Microsoft.Cpp.targets或其他包含文件,我想只使用空/干净的MsBuild设置来执行此操作)。

感谢。

1 个答案:

答案 0 :(得分:1)

编译是ItemGroup所以你应该用@而不是%引用它。 试试以下

error: incompatible types: Object cannot be converted to T