MSBuild使用初步

来源:互联网 发布:淘宝联盟 淘口令 编辑:程序博客网 时间:2024/06/04 20:11

了解一下msbuild工程文件的基本结构,作为练习,用它编译一个用到Qt库的C++控制台程序

C#例子

一个简单的例子:

// file: hello.csusing System;class CSharpTest{    static void Main()    {        Console.WriteLine("Hello world not using Qt");    }}

如果直接用命令行的话,可以直接这么编译:

csc /out:hello_cs.exe hello.cs

msbuild

可是如果我想用msbuild,工程文件怎么写呢?

恩,大致可以这样:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">    <Target Name="Compile">        <CSC Sources="hello.cs" OutputAssembly="hello_cs.exe" />    </Target></Project>

而后直接

msbuild hello.csproj

即可。

一个工程中可以有多个目标(Target),如果这样的话,我们需要指定执行哪一个(和nmake是类似的)

msbuild hello.csproj /t:Compile

也可以在Project的属性中指定

<Project  DefaultTargets="Compile" 

每一个目标(Target)由若干个任务(Task)组成。比如:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">    <Target Name="Compile">        <CSC Sources="hello.cs" OutputAssembly="hello_cs.exe" />    </Target>    <Target Name="Compile2">        <Message Text="Before"/>        <CSC Sources="hello.cs" OutputAssembly="hello_cs.exe" />        <Message Text="After"/>    </Target></Project>

然后我们

msbuild hello.csproj /t:Compile2

这样在编译命令前后分别输出一条信息。其中CSC和Message都是MSBuild内置的Task

继续

前面的东西太简陋了,一般情况下,我们需要将一些东西分开设置,也就是需要变量或宏一类的东西

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">    <PropertyGroup>        <appname>hello_cs</appname>    </PropertyGroup>    <ItemGroup>        <CSSource Include="hello.cs"/>    </ItemGroup>    <Target Name="Compile">        <CSC Sources="@(CSSource)" OutputAssembly="$(appname).exe" />    </Target></Project>

这儿引入的Property(属性)和Item这两个东西。

  • 属性类似于宏,一个简单的键值对,在任务中可以直接通过 $(...)来引用
  • Item 比较复杂,在任务中通过 @(...)来引用,大致相当于一个数组吧(fixme)
    • Include和Exclude,中还支持通配符

    <ItemGroup>        <CSSource Include="hello.cs"/>        <CSSource Include="class1.cs"/>        <CSSource Include="class2.cs;class3"/>    </ItemGroup>

看个具体的?

用Visual Studio创建一个具体的C#控制台工程,然后打开看看

<?xml version="1.0" encoding="utf-8"?><Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">...  <ItemGroup>    <Compile Include="Program.cs" />    <Compile Include="Properties\AssemblyInfo.cs" />  </ItemGroup>  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />...</Project>

真够复杂的,尽管大量东西都隐藏在Microsoft.CSharp.targets中了

我想用它编译个Qt程序

简单的Qt的例子:

#include <QtGui/QLabel>#include <QtGui/QApplication>int main(int argc, char **argv){    QApplication app(argc, argv);    QLabel label("Qt Program built using MSBuild....");    label.show();    app.exec();}

使用命令行时,只需:

E:\msbuild>cl hello.cpp /ID:\Qt\4.7.3\include  /link  /libpath:D:\Qt\4.7.3\lib QtCore4.lib QtGui4.lib

现在我想试试MSBuild,可以快速写个工程文件 hello.qtproj ?

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">    <PropertyGroup>        <appname>hello_qt</appname>    </PropertyGroup>    <ItemGroup>       <QtPart Include="core;gui" />    </ItemGroup>    <ItemGroup>        <QtSource Include="hello.cpp"/>    </ItemGroup>    <Target Name="Compile">        <QTC Sources="@(QTSource)"  QtParts="@(QtPart)"  Output="$(appname).exe" />    </Target></Project>

现在,我们在里面指定了:

  • 源文件
  • 可执行程序名
  • 需要的Qt模块名

但是我们需要有一个Task来做这件事情

QTC任务

为了让我们前面的QTC能工作,需要先为MSBuild写个Task插件

using System;using System.Collections.Generic;using System.Diagnostics;using Microsoft.Build.Framework;using Microsoft.Build.Utilities;namespace Dbzhang800{    public class QTC:Task    {        public override bool Execute()        {            string qtdir = Environment.GetEnvironmentVariable("QTDIR");            var arguments = new List<string>();            foreach (string src in sourcesname)            {                arguments.Add(src);            }            arguments.Add(string.Format("/Fe{0}", outputname));            arguments.Add(string.Format("/I{0}\\include", qtdir));            arguments.Add(string.Format("/link /libpath:{0}\\lib", qtdir));            foreach (string part in partsname)            {                arguments.Add(String.Format("Qt{0}4.lib", part));            }            Process proc = new Process();            proc.StartInfo.UseShellExecute = false;            proc.StartInfo.FileName = "cl";            proc.StartInfo.Arguments = string.Join(" ", arguments.ToArray());            proc.Start();            Console.WriteLine("{0}", string.Join(" ", arguments.ToArray()));            return true;        }        private string outputname;        public string Output        {            get {return outputname;}            set {outputname = value;}        }        private string[] sourcesname;        public string[] Sources        {            get {return sourcesname;}            set {sourcesname = value;}        }        private string[] partsname;        public string[] QtParts        {            get {return partsname;}            set {partsname = value;}        }    }}

这是一个C#文件,编译成dll文件

csc /target:library /r:Microsoft.Build.Framework.dll;Microsoft.Build.Utilities.v3.5.dll qttask.cs

而后在工程 hello.qtproj 中注册一下这个Task

...    <UsingTask TaskName="QTC" AssemblyFile="qttask.dll"/>    <Target Name="Compile">        <QTC Sources="@(QTSource)"  QtParts="@(QtPart)"  Output="$(appname).exe" />    </Target>...

现在,总算可以用

msbuild test.qtproj

来生成我们的Qt程序了


原创粉丝点击