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

C#例子

一个简单的例子:

// file: hello.cs
using 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程序了

MSBuild使用初步相关推荐

  1. [转]MSBuild入门

    如果你和我一样一直都在用NAnt管理生成过程的话,那么你一定会高度关注MSBuild.原因很简单,因为它属于微软,你可以不喜欢它,但你一定要学会用它. 在熬过了几个晚上以后,我终于让自己适应了MSBu ...

  2. TensorRT 7.2.1开发初步

    TensorRT 7.2.1开发初步 TensorRT 7.2.1开发人员指南演示了如何使用C ++和Python API来实现最常见的深度学习层.它显示了如何采用深度学习框架构建现有模型,并使用该模 ...

  3. SOC,System on-a-Chip技术初步

    SOC,System on-a-Chip技术初步 S O C(拼作S-O-C)是一种集成电路,它包含了电子系统在单个芯片上所需的所有电路和组件.它可以与传统的计算机系统形成对比,后者由许多不同的组件组 ...

  4. Jenkins配置MSBuild实现自动部署(MSBuild+SVN/Subversion+FTP+BAT)

    所要用到的主要插件: [MSBuild Plugin] 具体操作: 1.配置MSBuild的版本 [系统管理]->[Global Tool Configuration]->[MSBuild ...

  5. 《OpenCV3编程入门》学习笔记3 HighGUI图形用户界面初步

    第3章 HighGUI图形用户界面初步 3.1 图像的载入.显示和输出到文件 1.OpenCV命名空间2种访问方法 (1)代码开头加:usingnamespace cv; (2)每个类或函数前加:cv ...

  6. 初步判断内存泄漏方法

    有时候,内存泄漏不明显,或者怀疑系统有内存泄漏,我们可以通过下面介绍的方法初步确认系统是否存在内存泄漏. 首先在Java命令行中增加-verbose:gc参数, 然后重新启动java进程. 当系统运行 ...

  7. android蓝牙4.0(BLE)开发之ibeacon初步

    一个april beacon里携带的信息如下 ? 1 <code class=" hljs ">0201061AFF4C0002159069BDB88C11416BAC ...

  8. 游戏AI之初步介绍(0)

    目录 游戏AI是什么? 游戏AI和理论AI 智能的假象 (更新)游戏AI和机器学习 介绍一些游戏AI 4X游戏AI <求生之路>系列 角色扮演/沙盒游戏中的NPC 游戏AI 需要学些什么? ...

  9. 使用roslyn代替MSBuild完成解决方案编译

    原本我是使用批处理调用 MSBuild 完成解决方案编译的,新版的 MSBuild 在 Visual Studio 2015 会自带安装. 当然在Visual Studio 2015 中,MSBuil ...

最新文章

  1. 迪杰斯特拉算法c++_《算法图解》学习记录7--迪杰斯特拉算法
  2. java怎么将前端的数据存到关联的表中_MySQL数据库性能优化
  3. 一段把mp4中的音频提取并保存在原目录的python脚本
  4. 在 asp.net mvc中的简单分页算法 (续)
  5. 基于VC++开发串口通信的方法
  6. java猜单词游戏_序列应用——猜单词游戏
  7. 在PyTorch中转换数据
  8. vscode gcc debug dbg gdb c cpp c++ cuckoo monitor
  9. 被邻居偷偷拉了条网线到他家,然后在他家装WiFi,我怎么让他不能使用我的网络?
  10. Visio 2013 破解工具 - KMSpico(亲测可用)
  11. wordpress 中 erphpdown 短代码
  12. 台风怎么看内存颗粒_RGB灯效内存条怎么选,看老胡推荐
  13. python——xlwt
  14. HTML实现简单水平导航栏
  15. String 翻转字符串
  16. U3D中的常用字符串加密算法程序
  17. 阿俊带你用Kotlin刷算法(四)
  18. jython_Jython简介,第2部分:编程要点
  19. 【量子学习笔记】纯态、混合态、直积态及纠缠态的概念区分及理解
  20. 微信公众号自定义菜单栏绑定关联小程序

热门文章

  1. 达芬奇项目服务器无法在这台计算机上找到,安装达芬奇软件出现了问题哪位大神内给解决一下...
  2. SEER交易所及第三方平台充提网关接入指南
  3. TDK提供哪些不间断电源所需的可靠元件?
  4. 大话设计模式之爱你一万年:第三章 创建型模式:工厂模式:我想让你坐在宝马里笑:2.工厂模式之无工厂时代
  5. 科目三考试报告台词:
  6. 又一款新品挺进美国iOS游戏畅销榜:除了做玩法混合,三消还能怎样赢得玩家?
  7. 智能物联时代 看联想如何“不一样”
  8. 洞态 IAST v1.1.4 新版本来袭,DevSecOps 更进一步
  9. CSS 为div单个角设置弧度 border-radius
  10. 计算机应用毕业作品,计算机应用毕业设计论文参考