MSBUILD的编译过程实际上是根据一系列的targets文件定义的,当我们在IDE执行生成、批生成、清理命令的时候,VS会查找这些命令对应的Task并执行它,下面我们逐个分析这个过程。
当执行生成操作时,MSBUILD将执行一个叫”Build”的任务,在targets文件中是这样定义的:
<Target
Name="Build"
Condition=" ‘$(_InvalidConfigurationWarning)‘ !=‘true‘ "
DependsOnTargets="$(BuildDependsOn)"
Returns="@(ManagedTargetPath);@(WinMDFullPath)">
<ItemGroup>
<ManagedTargetPathInclude="$(TargetPath)" Condition="‘$(ManagedAssembly)‘ == ‘true‘" />
</ItemGroup>
</Target>
这里的BuildDependsOn定义为:
<BuildDependsOn>
_PrepareForBuild;
$(BuildSteps);
AfterBuild;
FinalizeBuildStatus;
</BuildDependsOn>
将BuildSteps扩展开:
<BuildStepsCondition="‘$(BuildSteps)‘ == ‘‘">
ResolveReferences;
PrepareForBuild;
InitializeBuildStatus;
BuildGenerateSources;
BuildCompile;
BuildLink;
</BuildSteps>
也就是说MSBUILD将依次执行这几个任务:
_PrepareForBuild;
ResolveReferences;
PrepareForBuild;
InitializeBuildStatus;
BuildGenerateSources;
BuildCompile;
BuildLink;
AfterBuild;
FinalizeBuildStatus;
但当我们的项目是使用Makefile编译的时候,并不需要让MSBUILD控制整个过程,因为这个过程已经在Makefile中完成了,我们只要重载Build这个任务就可以了。
<Target
Name="Build"
Condition=" ‘$(GNUProjectType)‘ == ‘UBoot‘ or‘$(GNUProjectType)‘ == ‘LinuxKernel‘ or ‘$(GNUProjectType)‘ == ‘LinuxMakeApp‘ "
>
<EmbedLinuxMakeTask
TargetName="Build"
ProjectDir="$(ProjectDir)"
HostIp="$(HOST_IP)"
HostUser="$(HOST_USER)"
HostPasswd="$(HOST_PASSWD)"
Python2="$(PYTHON2_EXE)"
PythonFile="$(PythonFile)"
/>
</Target>
当然,在此之前需要告诉MSBUILD,EmbedLinuxMakeTask这个任务在哪里:
<UsingTaskTaskName="EmbedLinuxMakeTask" AssemblyFile=" EmbedLinux.dll" />
这样当编译UBOOT、内核或者使用Makefile的应用程序时,MSBUILD将自动执行EmbedLinux.dll中定义的EmbedLinuxMakeTask这一任务!!
在这个任务的实现中,我们将执行由PythonFile指定的脚本,并将此脚本的输出重定向到VS的编译信息输出窗口中。这个脚本做为项目文件的一部分,需要完成编译和错误信息转换的功能。而SSH登录的操作则是一个通用的操作,放在任务的实现代码中。
EmbedLinuxMakeTask的执行过程为:
? 加载python2.exe
? 在PYTHON中写入VS中的环境变量
? 定义默认的编译和信息转换的行为
? 加载项目中指定的编译脚本,改写默认行为
? 开始执行登录操作
? 执行编译操作,在编译过程中完成错误信息的转换
? 返回Make的结果
Vs2012在Linux开发中的应用(6):改写Makefile项目的Build过程
原文地址:http://blog.csdn.net/lights_joy/article/details/41292081