设为首页收藏本站

LUPA开源社区

 找回密码
 注册
文章 帖子 博客
LUPA开源社区 首页 业界资讯 技术文摘 查看内容

在Visual Studio构建和配置Boost(MSBuild)

2015-5-4 21:49| 发布者: joejoe0332| 查看: 5159| 评论: 0|原作者: Parser7SParser, 霍啸林, jince, king_dust, gones945, 无若, leoxu|来自: oschina

摘要: Boost 是一个非常流行地开源C++库。最近作为构建的一部分,我已经把它集成在Visual Studio中。仅仅使用Makefile项目和Command Line工具,要想完全正确地配置构建项目还是很困难的。Boost也一直指引着我发现所有相关 ...


CXXFLAGS

编译标志(Compiler flags)被定义在 CL.XML 中,该文件位于 C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\...\1033 目录中。有不少设定项虽然在构建 Boost 时用不到,但是不乏一些有用的。我们可以创建 cxxflags.xml 并将所有相关的属性复制进去。当我们完成这些操作并适当地将这个文件加入到项目中时,我们就有了下面这样的界面:


LINKFLAGS

同样我们可以将 LINK.XML 定义的链接器属性页的内容添加到项目的 linkflags.xml 文件中:


将配置传给构建工具

创建完 XML 属性页,此时只完成了整个工作的一半。现在我们需要将这些设定项传给构建工具。我们需要从变量中获取数据,适当地对其进行格式化并传给构建命令。

为此我们通常在代码里对变量进行赋值,同时对构建命令行切换配置。但其实我们有更好的办法:格式化数据已经在 XML 文件里设置了,我们所要做的只是获取它并应用到项目变量上。在这篇文章中描述了实现它的一条途径,但还存在一种更好的方式。当涉及到处理 XML 数据时,没有什么能胜过 XSLT,所以我们借助 XSLT 来完成这个任务。


选项集成

到这个地方,事情就变得简单了。 属性页,开关,命令行。。。。。。现在,我们需要使用C/C++和链接选项创建分层结构,其中链接选项以下面的格式作为cxxflags和linkflags的命令行参数:

1
... cxxflags="/cxx1 /cxx2='Some dir here' ... " linkflags="/L1 /L2='Some dir here' ... "

我们可以通过遍历页面来实现,为每个页面创建配置选项,并通过合适的前缀(cxxflags, linkflags)--需要则添加,来连接结果。我们通过配置 PrepareForBuild来处理:

1
2
3
4
5
6
7
8
9
10
11
12
13
<Target Name="PrepareForBuild" Returns="@(boost-options)" >
  ...    
  <MSBuild Targets="ConfigHelper" 
           BuildInParallel="true"
           Properties="PropertyPageSchema=%(PropertyPageSchema.Identity);
                       Context=%(PropertyPageSchema.Context)" >
     
    <Output ItemName="boost-options" TaskParameter="TargetOutputs"/>
  </MSBuild>
     
    <ItemGroup Label="Build Settings">
      <boost-options Condition="&apos;$(AdditionalOptions)&apos;!=&apos;&apos;" Include="$(AdditionalOptions)" />
    </ItemGroup>

在代码里面,我们使用MSBuild为 选项PropertyPageSchema中的每个元素调用ConfigHelper,传递路径到xml文件,同时将存储在Metadata Context中的数据作为参数。返回值存储在选项boost-options之中。 接下来的代码中,增加了在其它选项(Additional Options)框中定义的所有开关,返回由空格分隔的所有开关的字符串。

ConfigHelper是一切之源。只需要几个步骤,它就处理了所有的XML文件。首先,它获取所有属性的列表:

1
2
3
4
<XmlPeek XmlInputPath="$(File)" Query="/ns:Rule/*[not(contains(@IncludeInCommandLine, &apos;false&apos;))]/@Name|
           /ns:ProjectSchemaDefinitions/ns:Rule/*[not(contains(@IncludeInCommandLine, &apos;false&apos;))]/@Name">
    <Output TaskParameter="Result" ItemName="Names" />
</XmlPeek>

然后,它创建包含属性值的属性列表:

1
2
3
<data-name-map Include="$(%(Names.Identity))" Condition="&apos;%(%(Names.Identity))&apos;!=&apos;&apos;" >
    <Name>%(Names.Identity)</Name>
</data-name-map>

注意这个标记: $(%(Names.Identity)) 。它告知系统,返回变量名存储在%(Names.Identity)之中的变量的值。如果变量包含逗号分隔的一系列值,它会将变量当作一个列表,并单独添加这些值。例如,如果我们在名为xxList的变量中包含val1;val2;val3,它将像这样增加数据:

1
2
3
4
5
6
7
8
9
<data-name-map Include="val1" >
   <Name>xxList<Name>
</data-name-map>
<data-name-map Include="val2" >
   <Name>xxList<Name>
</data-name-map>
<data-name-map Include="val3" >
   <Name>xxList<Name>
</data-name-map>

这为数据创建了有效的外部连接。 接下来,它将以 <Property Name="name" >value</Property> 的格式生成数据:

1
2
<temp-data Condition="&apos;@(data-name-map)&apos;!=&apos;&apos; And &apos;%(data-name-map.Identity)&apos;!=&apos;&apos;"
    Include="<Prop Name=&#34;%(data-name-map.Name)&#34;   >%(data-name-map.Identity)</Prop>"/>

同时,像这样将它们添加到XSL样式表:

1
<xsl:variable name="Data" >@(temp-data, &apos;&apos;)</xsl:variable>

只要数据添加了,它就执行XSL转换:

1
2
<XslTransformation Condition="&apos;@(temp-data)&apos;!=&apos;&apos;" Parameters="@(xslParameters, &apos;&apos;)"
             XmlInputPaths="$(PropertyPageSchema)" XslContent="$(raw-xsl)" OutputPaths="$(TempFile)" />

接下来就变得简单了:它从文件读取转换结果,如果需要则增加前缀,然后返回选项。在所有的处理完毕后,当构建工具调用的时候,它们就会被添加到命令行。


利用代码

被包含的归档中含有构建项目所需要的完整文件集合. 你可以将它复制到任何的目录中去,指定Boost根路径以及构建的位置.


针对 cxxflags 和 linkflags 的设置没有通通测试过,因此请悠着点进行处理. 如果你发现有些东西不起作用了,记得告诉我. 或者也可以在 GitHub 给我发一条请求.


下载源代码 - 29.8 KB


酷毙

雷人

鲜花

鸡蛋

漂亮
  • 快毕业了,没工作经验,
    找份工作好难啊?
    赶紧去人才芯片公司磨练吧!!

最新评论

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187 浙公网安备 33010602006705号   

返回顶部