MSBuild是微软自Visual Studio 2005开始提供的构建平台,既可以用于VC#项目,也可用于VC++项目。
通常情况下,我们采用IDE本身进行项目的构建,有时,也会采用命令行方式调用IDE程序Build我们的项目。(对于VC++项目来说,就是通过命令行调用devenv进行构建)
然而,当我们希望在持续集成工具当中实现项目的自动构建时,尤其是当依赖情况或者部署情况较为复杂时,我们希望有一个简单、易维护的工具实现构建——MSBuild就是我们所需要的工具。
采用MSBuild进行构建,需要我们编写MSBuild脚本——一种规定格式的XML文件。
MSBuild基本组成部分包括:Target(目标),ItemGroup(项),PropertyGroup(属性),Task(任务)。
其中:Target目标是MSBuild执行的基本单元。
我们在命令行中调用MSBuild /t:TargetName指定需要执行的目标。
每个Target中可以包含若干Task。
Task是基本的功能单元:例如拷贝文件,删除文件,创建/删除目录,使用Exec调用外部程序,调用VCBuild构建.vcproj项目,调用Csc编译.cs文件,等等。此外,你还可以通过实现ITask接口,创建自定义的Task。
PropertyGroup作为属性,起着类似于变量一样的作用,可以定义一个属性,并在后续的位置使用该属性,例如:
<PropertyGroup> <ProjFile>C:\Test\test.vcproj</ProjFile> <Rebuild>true</Rebuild> </PropertyGroup> <Target Name=”Build”> <VCBuild Projects=”$(ProjFile)” Rebuild=”$(Rebuild)” /> </Target>
ItemGroup往往作为输入,例如:
<ItemGroup> <IncFiles Include=”C:\Test\*.h” /> </ItemGroup> <Target Name=”Build”> <Copy SourceFiles=”@(IncFiles)” DestinationFolder=”c:\output\include” /> </Target>
实例:
假设我们有一个项目A,依赖一个动态连接库B,我们需要先构建B,将B的头文件和lib文件拷贝到A的包含头文件路径和Lib路径下,再构建A,然后将A发布到指定的路径下。
B的项目结构如下:
C:\B\B.vcproj
A的项目结构如下:
C:\A
\DepInclude
\DepLib
\Src\A.vcproj
\Output
对应的MSBuild脚本如下:
<ItemGroup> <BIncFiles Include=”C:\B\*.h” /> <BLibFiles Include=”C:\B\Release\*.lib” /> <BDllFiles Include=”C:\B\Release\*.dll” /> </ItemGroup> <TargetName=”Build_B”> <VCBuild Projects=”C:\B\B.vcproj” Configuration=”Release” Rebuild=”true” /> <Copy SourceFiles=”@(BIncFiles)” DestinationFolder=”C:\A\DepInclude” /> <Copy SourceFiles=”@(BLibFiles)” DestinationFolder=”C:\A\DepLib” /> </Target> <Target Name=“Build_A” DependOnTargets=“Build_B”> <VCBuild Projects=”C:\A\Src\A.vcproj“ Configuration=“Release” Rebuild=”true” /> </Target>
Build_A的Target使用了一个DependOnTargets属性,该属性的含义是当前Target要依赖前续的某些Targets,那些依赖的Targets必须先执行,然后才能执行当前的Target。
在本例中Build_B会rebuild整个B工程,并将结果的头文件和lib文件拷贝到A项目的依赖路径当中。