在Microsoft.Common.CurrentVersion.targets之上定位新语言

时间:2018-03-28 13:17:08

标签: msbuild msbuild-task msbuild-target

我正在编写一个简单的扩展,以允许MSBuild编译可靠性源文件。

我的目标是当我的solidproj被编译时,它运行特定的可执行文件,生成应该复制到目标目录的多个binabi文件。这听起来很容易,但实际上并非如此。

我目前有以下目标:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  ...

  <Import Project="$(MSBuildToolsPath)\Microsoft.Common.CurrentVersion.targets" />
  <Target Name="CreateManifestResourceNames" />
  <Target Name="CoreCompile">
    <Exec Command='$(RunCommand) "-o @(OutDir) @(SolCompile)" $(RunCommandArguments)' WorkingDirectory="$(RunWorkingDirectory)" />
  </Target>
</Project>

它几乎可以工作,只是它期望单个exe文件被编译

<!-- Copy the build product (.dll or .exe). -->
<Copy
    SourceFiles="@(IntermediateAssembly)"
    DestinationFolder="$(OutDir)"
    SkipUnchangedFiles="$(SkipCopyUnchangedFiles)"
    OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)"
    Retries="$(CopyRetryCount)"
    RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"
    UseHardlinksIfPossible="$(CreateHardLinksForCopyFilesToOutputDirectoryIfPossible)"
    UseSymboliclinksIfPossible="$(CreateSymbolicLinksForCopyFilesToOutputDirectoryIfPossible)"
    Condition="'$(CopyBuildOutputToOutputDirectory)' == 'true' and '$(SkipCopyBuildProduct)' != 'true'"
        >

  <Output TaskParameter="DestinationFiles" ItemName="MainAssembly"/>
  <Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>

</Copy>
  

错误MSB3030无法复制文件“obj \ Debug \ Solidity9.exe”   因为没找到。 Solidity9 C:\ Program Files(x86)\ Microsoft   视觉   Studio \ 2017 \ Professional \ MSBuild \ 15.0 \ Bin \ Microsoft.Common.CurrentVersion.targets 4118

如何让它将此特定扩展名的所有内容复制到输出中?

整个项目都在github here上。

1 个答案:

答案 0 :(得分:0)

我最终从头开始创建所有构建步骤:

  <ItemGroup>
    <CopyUpToDateMarker Include="$([MSBuild]::NormalizePath('$(MSBuildProjectDirectory)', '$(IntermediateOutputPath)', '$(MSBuildProjectFile).CopyComplete'))" />
  </ItemGroup>

  <UsingTask
    TaskName="GetOutdatedFiles"
    TaskFactory="CodeTaskFactory"
    AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" >

    <ParameterGroup>
      <FileList ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" />
      <UpToDateMarker ParameterType="System.String" Required="true" />
      <Result ParameterType="Microsoft.Build.Framework.ITaskItem[]" Output="true" />
    </ParameterGroup>
    <Task>
      <Using Namespace="System"/>
      <Code Type="Fragment" Language="cs">
        <![CDATA[
          var modifiedFiles = new List<ITaskItem>();
          if(!File.Exists(UpToDateMarker))
          {
            Result = FileList;
          }
          else 
          {
            DateTime markerTimeStamp = File.GetLastWriteTime(UpToDateMarker);
            Result = FileList.Where(file => DateTime.Parse(file.GetMetadata("ModifiedTime")) > markerTimeStamp).ToArray();
          }
          ]]>
      </Code>
    </Task>
  </UsingTask>

  <Target Name="Build" DependsOnTargets="CoreBuild;AfterBuild" />

  <Target Name="CoreBuild">
    <Error Condition="'$(OutDir)' == ''" Text="The OutDir property is missing" />
    <Error Condition="'$(IntermediateOutputPath)' == ''" Text="The IntermediateOutputPath property is missing" />

    <GetOutdatedFiles FileList="@(SolCompile)" UpToDateMarker="@(CopyUpToDateMarker)">
      <Output TaskParameter="Result" ItemName="ChangedFiles"/>
    </GetOutdatedFiles>

    <Exec Command='$(RunCommand) "%(ChangedFiles.Identity)" -o "$(IntermediateOutputPath)" $(RunCommandArguments)' WorkingDirectory="$(RunWorkingDirectory)" Condition="'@(ChangedFiles)' != ''"/>
  </Target>

  <Target Name="AfterBuild">
    <ItemGroup>
      <BinFiles Include="$(IntermediateOutputPath)/*.bin"/>
      <AbiFiles Include="$(IntermediateOutputPath)/*.abi"/>
    </ItemGroup>

    <Copy SourceFiles="@(BinFiles)" DestinationFolder="$(OutDir)" SkipUnchangedFiles="true">
      <Output TaskParameter="CopiedFiles" ItemName="BinFilesCopiedInThisBuild"/>
    </Copy>
    <Copy SourceFiles="@(AbiFiles)" DestinationFolder="$(OutDir)" SkipUnchangedFiles="true">
      <Output TaskParameter="CopiedFiles" ItemName="AbiFilesCopiedInThisBuild"/>
    </Copy>
    <Touch Files="@(CopyUpToDateMarker)" AlwaysCreate="true" Condition="'@(BinFilesCopiedInThisBuild)'!='' or '@(AbiFilesCopiedInThisBuild)'!=''" />
  </Target>

  <Target Name="Clean">
    <Delete Files="@(CopyUpToDateMarker)" />
    <RemoveDir Directories="$(OutDir)" />
  </Target>

  <Target Name="Rebuild" DependsOnTargets="Clean;Build" />

仍然需要解决传递依赖的问题,但它是另一个问题