基于Microsoft.Common.CurrentVersion.targets:MSBuild编译Solidity扩展开发问题
给MSBuild加Solidity编译扩展的实践思路
我最近在折腾给MSBuild写个简单扩展,用来编译Solidity源文件——核心目标就是:当编译solidproj项目时,自动调用指定的Solidity编译器(比如solc或者自定义编译工具),生成对应的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="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> <!-- 这里是自定义的Solidity编译目标区域 --> ... </Project>
关键步骤拆解
1. 收集Solidity源文件
首先得让MSBuild识别项目里的所有.sol文件,定义一个ItemGroup来收集:
<ItemGroup> <SoliditySourceFiles Include="**\*.sol" Exclude="$(OutputPath)**;$(IntermediateOutputPath)**" /> </ItemGroup>
用Exclude排除输出和中间目录,避免重复编译生成的文件。
2. 编写自定义编译目标
要在Build流程中插入自定义的Solidity编译步骤,我用了Target节点指定执行时机(比如在核心编译之后),并调用Exec任务运行编译器:
<Target Name="CompileSolidity" AfterTargets="CoreCompile" Inputs="@(SoliditySourceFiles)" Outputs="@(SolidityOutputBinFiles);@(SolidityOutputAbiFiles)"> <!-- 先确保输出目录存在 --> <MakeDir Directories="$(IntermediateOutputPath)\SolidityOutput" /> <!-- 调用Solidity编译器生成bin和abi --> <Exec Command=""$(SolcPath)" --bin --abi --output-dir $(IntermediateOutputPath)\SolidityOutput @(SoliditySourceFiles->'"%(FullPath)"', ' ')" WorkingDirectory="$(ProjectDir)" Condition="Exists('$(SolcPath)') and @(SoliditySourceFiles) != ''" /> <!-- 收集生成的bin和abi文件 --> <ItemGroup> <SolidityOutputBinFiles Include="$(IntermediateOutputPath)\SolidityOutput\*.bin" /> <SolidityOutputAbiFiles Include="$(IntermediateOutputPath)\SolidityOutput\*.abi" /> </ItemGroup> <!-- 复制产物到目标输出目录 --> <Copy SourceFiles="@(SolidityOutputBinFiles)" DestinationFolder="$(OutputPath)" SkipUnchangedFiles="true" /> <Copy SourceFiles="@(SolidityOutputAbiFiles)" DestinationFolder="$(OutputPath)" SkipUnchangedFiles="true" /> </Target>
3. 配置编译器路径变量
可以在项目文件或者.props文件里定义编译器的路径,方便灵活修改:
<PropertyGroup> <!-- 这里可以换成你的solc实际路径,或者用环境变量 --> <SolcPath>$(SolutionDir)\tools\solc.exe</SolcPath> </PropertyGroup>
踩过的坑
- 路径空格问题:调用
Exec时,编译器路径或者源文件路径如果有空格,一定要用双引号包裹,比如"$(SolcPath)",不然会触发命令行解析错误。 - 增量编译:给
Target加上Inputs和Outputs属性,MSBuild会自动追踪文件变化,只有当.sol文件修改时才重新编译,避免每次都全量执行。 - 目标执行时机:一开始我把
AfterTargets设成了Build,结果发现会在整个项目编译完成后才执行,后来改成CoreCompile,确保在C#等代码编译完成后立刻处理Solidity文件,顺序更合理。
内容的提问来源于stack exchange,提问作者Alex Zhukovskiy
相关产品推荐
相关产品推荐

