我正在编写一个简单的扩展,以允许MSBuild编译可靠性源文件。
我的目标是当我的solidproj
被编译时,它运行特定的可执行文件,生成应该复制到目标目录的多个bin
和abi
文件。这听起来很容易,但实际上并非如此。
我目前有以下目标:
<?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上。
答案 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" />
仍然需要解决传递依赖的问题,但它是另一个问题