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= "'$(AdditionalOptions)'!=''" 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 , ' false '))]/ @Name |
/ns:ProjectSchemaDefinitions/ns:Rule/*[not(contains( @IncludeInCommandLine , ' false '))]/ @Name ">
<Output TaskParameter= "Result" ItemName= "Names" />
</XmlPeek>
|
然后,它创建包含属性值的属性列表: 1 2 3 | <data-name-map Include= "$(%(Names.Identity))" Condition= "'%(%(Names.Identity))'!=''" >
<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= "'@(data-name-map)'!='' And '%(data-name-map.Identity)'!=''"
Include= "<Prop Name="%(data-name-map.Name)" >%(data-name-map.Identity)</Prop>" />
|
同时,像这样将它们添加到XSL样式表: 1 | <xsl:variable name= "Data" >@(temp-data, '')</xsl:variable>
|
只要数据添加了,它就执行XSL转换: 1 2 | <XslTransformation Condition= "'@(temp-data)'!=''" Parameters= "@(xslParameters, '')"
XmlInputPaths= "$(PropertyPageSchema)" XslContent= "$(raw-xsl)" OutputPaths= "$(TempFile)" />
|
接下来就变得简单了:它从文件读取转换结果,如果需要则增加前缀,然后返回选项。在所有的处理完毕后,当构建工具调用的时候,它们就会被添加到命令行。
利用代码被包含的归档中含有构建项目所需要的完整文件集合. 你可以将它复制到任何的目录中去,指定Boost根路径以及构建的位置.
针对 cxxflags 和 linkflags 的设置没有通通测试过,因此请悠着点进行处理. 如果你发现有些东西不起作用了,记得告诉我. 或者也可以在 GitHub 给我发一条请求.
下载源代码 - 29.8 KB |