2KB项目,专业的源码交易网站 帮助 收藏 每日签到

在 Visual Studio 当地援用 Boost (MSBuild)

  • 时间:2019-05-13 11:52 编辑:2KB 来源:2KB.COM 阅读:398
  • 扫一扫,手机访问
  • 分享
摘要:
MSBuild Boost Visual Studio 英文原文:Referencing Boost natively in Visual Studio (MSBuild)

引见

这是关于将第三方Tools和库集成到 Visual Studio 系列中的第四篇文章。在第一篇文章中我说明了怎么创立 Visual Studio 属性对话框的自定义属性页。第二篇文章涵盖了属性表的外部构造和元素。第三篇文章经过构建 Boost 库的例子说明了怎么创立自定义构建。本文是第四篇,我将说明怎么集成自定义构建到 Visual Studio 项目标援用系统。

根本道理

每一个 C++ 项目由几个较小的子项目和库构成。它们在编译或运转时被用于链接,需求被恰当地援用。假如一切的项目都是在 Visual Studio(MSBuild)中被创立的,那末援用是由 MSBuild 来担任。但当一个项目或库来自内部时,我们不能不经过手动设置装备摆设来恰当地集成。

其它翻译版本 (1) 加载中

幻想状况下,我们应当能经过在 Visual Studio 中添加对某个项目标援用来将其集成到 MSBuild 中:

假如我们对任何库都能这么做,那不是很好吗?假如一切的 lib 文件会主动添加到 LINK 号令,同时一切的 DLL 文件都复制到输出目次,那末他们不就能够在运转时被链接上吗?假如既能调试我们的代码,还能调试库的代码,那又会如何呢?

在这篇文章中,我将通知你这该怎么做到。我会用库来演示怎么将它集成就任何项目,却无需手动操作库或设置途径。我假定你曾经晓得该怎么构建 Boost,不晓得的话就请读这篇文章

布景材料

当 Visual Studio 从一个项目添加援用到另外一个项目时,它会像下面如许将一笔记录添加到主项目中:

<ProjectReference Include="...oost.vcxproj">
    <Project>{9cd23c68-ba74-4c50-924f-2a609c25b7a0}</Project>
    ...
</ProjectReference>

关于援用是怎么被添加的具体信息,拜见这个链接

在构建主项目标过程当中,MSBuild 会对 ProjectReference 段中列出的一切依靠实行剖析和构建。它会定位列出的子项目,并经过对每一个子项目挪用以下 Target 来搜集需要的信息:

GetTargetPath
GetNativeManifest
GetResolvedLinkLibs
GetCopyToOutputDirectoryItems

我将简要地说明它们辨别做了甚么。

GetTargetPath

这个目的(Target)前往项目构建的顺序集/库的完好途径。在设计阶段,Visual Studio运用这个文件来判别援用能否准确,和能否可以找到输出文件。假如顺序集是托管类型,Visual Studio也会查询它以获得更多的信息。
实际上讲,只需这个途径指向曾经存在的文件,援用系统都会正常陈述援用是有效的。

关于Boost库而言,没有单一的库文件。它根据设置装备摆设,构建恣意数目的库文件,或许基本就不构建库文件。我们可使用这些来实行援用校验。我们可以前往指向恣意文件的途径,来标明援用是有效的。我决议前往文件Jamroot的途径,用来标明,本次构建是运用哪一个源代码来创立的库文件:

<Target Name="GetTargetPath" Returns="@(TargetPath)" >
  <ItemGroup>
    <TargetPath Include="$(BoostRoot)Jamroot">
      <Private>true</Private>
      <FileType>info</FileType>
      <ResolveableAssembly>false</ResolveableAssembly>
    </TargetPath>
  </ItemGroup>
</Target>

它需求在项目(Item)上设置如上所示的一些元数据( metadata)属性。FileType凡是包括如lib或dll为拓展名的文件,因为在这里不实用,所以我前往了假的类型。ResolveableAssembly标明,它是托管顺序集或许是原生的。Private包括了当地复制(Local Copy)设置。

GetNativeManifest

假如因为某种缘由,子项目必需从头宣布Manifest文件和库文件,这个目的(Target)会前往manifest文件的列表信息。父工程会容易的拷贝这些manifest文件到输出目次。

Boost无需任何manifest文件,所以它不必做任何设置:

<Target Name="GetNativeManifest" />

GetResolvedLinkLibs

这个目的(Target)前往一切链接库的列表信息。它们将会添加到LINK号令,如许这些lib文件就能够链接了。Boost库针对它创立的每一个模块都有一个lib文件。

对我们来讲,要前往准确的列表信息,起首要获得创立的库文件的列表信息,然后链接到实践的lib文件。我们需求完成两个步调:

  • 运用以后选项--show-libraries 号令挪用b2(GetBuiltLibs)

  • 处置链接库的援用,并将它们参加前往列表(GetResolvedLinkLibs)

<Target Name="GetBuiltLibs" DependsOnTargets="BuildJamTool" Returns="@(BuiltLibs)" >
  <Exec Command="b2.exe @(boost-options, &apos; &apos;) --show-libraries" ... />
    
    <ReadLinesFromFile Condition="Exists(&apos;$(TempFile)&apos;)" File="$(TempFile)">
      <Output TaskParameter="Lines" ItemName="RawOutput" />
    </ReadLinesFromFile>
    <Delete Condition="Exists(&apos;$(TempFile)&apos;)" Files="$(TempFile)"/>
    
    <ItemGroup>
      <BuiltLibs Include="$([Regex]::Match(%(RawOutput.Identity), (?<=-s)(.*) ))" />
    </ItemGroup>
  </Target>

请留意:为了明晰起见,文中一切的示例代码都做了简化处置。

<Target Name="GetResolvedLinkLibs" DependsOnTargets="GetBuiltLibs" Returns="@(LibFullPath)">
  <ItemGroup>
    <LibFullPath Include="$(OutputDir)lib*boost*%(BuiltLibs.Identity)*.lib">
      <ProjectType>StaticLibrary</ProjectType>
      <FileType>lib</FileType>
      <ResolveableAssembly>false</ResolveableAssembly>
    </LibFullPath>
  </ItemGroup>
</Target>

当库列表信息前往后,我们简直不必为每一个项目设置元属性。

GetCopyToOutputDirectoryItems

这个目的(target)前往内容文件的列表信息,这些文件需求拷贝到主工程的输出目次。 它们可所以恣意类型的文件。关于Boost库来讲,它们是构建过程当中创立的一切dll文件。我们运用,与之前一样的算法,来列出这些文件:

<Target Name="GetCopyToOutputDirectoryItems" DependsOnTargets="GetBuiltLibs" Returns="@(DLLToCopy)" 
        Condition="&apos;$(boost-link)&apos;==&apos;DynamicLibrary&apos;" >
  <ItemGroup>
    <BoostDlls Include="$(OutputDir)lib*boost*%(BuiltLibs.Identity)*.dll" />
    <DLLToCopy Include="@(BoostDlls)" Condition="&apos;%(BoostDlls.Identity)&apos;!=&apos;&apos;" >
      <TargetPath>%(FileName).dll</TargetPath>
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </DLLToCopy>
  </ItemGroup>
</Target>


在上面的代码中,每一个项目需求设置两个元数据(Metadata)属性:TargetPath和CopyToOutputDirectory。

TargetPath包括文件名和拓展名。当拷贝到目的文件夹,相似如许:$(DestinationFolder)$(TargetPath)的时分,它被用来指定文件名。

CopyToOutputDirectory包括两个可能的值:Always和PreserveNewest,此中之一。
 它告诉构建系统,要末老是拷贝文件,要末只拷贝源文件比目的文件新的文件。 

对Boost库来讲,假如是最新的,就无需拷贝DLL文件。

如今,假如我们将boost工程作为援用添加出去,它将会注册为有效的,同时供给父工程在准确构建过程当中可能需求的一切信息。

基于 Boost 实行构建

我们Start用一个十分原始的名字(Sample)来创立一个容易把持台使用顺序。鉴于每一个人都晓得怎么在 Visual Studio 中创立一个把持台使用顺序,我将跳过相干的步调阐明。

boost 项目添加至处理计划。

前去 Sample 项目标属性页,添加对 boost 项目标援用。你会看到像如许的界面:

如图所示,boost 项目已被准确地援用并指向 Boost 库安装的 D:Boost 目次。因为 Boost 不是一个托管顺序集,顺序集标识(Assembly Name)、区域性(Culture)、版本号(Version)、描绘(Description)都不成用。

值得留意的是,Copy Local 属性用来断定库能否要被复制到援用它的项目标输出目次。假如子项陌生成的是托管顺序集或只是一个lib 文件,那是不会出问题的。但假如子项陌生成的是原生 DLL 或多个库的话,全部进程就会中断。我们经过从头定义 GetCopyToOutputDirectoryItems 来修复它。我们如今要来把持能否将 DLL 复制到主项目标输出目次,那就需求向 Boost 属性页的惯例选项卡添加额定的属性:

将这个属性设置为 No 可以禁用复制。这个设定只在 Boost 库是以同享的方法被构建时才起用处,对生成静态库是无效的。

增量构建

每当我们构建的时分,b2 会反省设置装备摆设并决议它能否要构建组件的一部分。当 Boost 被用来开发其他项目时,它自身不大会发作甚么变化。所以反省能否发作变化根本上是过剩的。我曾经在属性页的惯例选项卡中增加了一个禁用这类反省的选项:

当这个选项是 Yes 或许空缺时,对从头构建的反省会被委派给 Visual Studio。它反省时会比对输出库的列表、已设置装备摆设库的列表和项目文件自身。如有任何库被删除或项目设置发作变卦,它便会实行构建。不然它会跳过构建,使得每次构建的耗时节俭大约半分钟。要从头启用这个反省,请将此选项设为 No

将这些反省委派给 Visual Studio 需具有以下要素:

构建输出

经过测试输出号令:b2 --show-libraries,可以揣度出构建的库列表。一旦我们有了列表,经过挪用Target GetBoostOutputs来验证库中所出现的工具。

<Target Name="GetBoostOutputs" DependsOnTargets="GetBuiltLibs" Returns="@(BoostOutputs)" >

  <ItemGroup>
    <BoostOutputs Include="$(OutputDir)lib*boost*%(BuiltLibs.Identity)*.lib" >
       <Library>%(BuiltLibs.Identity)</Library>
    </BoostOutputs>
    <ExistingLibs Include="%(BoostOutputs.Library)" />
    <BoostOutputs Include="@(BuiltLibs)" Exclude="@(ExistingLibs)" 
                  Condition="&apos;@(ExistingLibs->Count())&apos;!=&apos;@(BuiltLibs->Count())&apos;" />
    <BoostOutputs Include="%(BoostOutputs.RootDir)%(BoostOutputs.Directory)%(BoostOutputs.Filename).dll"                  Condition="&apos;@(BoostOutputs0>Filename->StartsWith(&#34;boost_&#34;))&apos;==&apos;true&apos; And 
                             &apos;%(BoostOutputs.Library)&apos;!=&apos;&apos; And &apos;$(boost-link)&apos;==&apos;DynamicLibrary&apos;" />
  </ItemGroup>
</Target>

正如你上面所看到的那样,我们从GetBuiltLibs目的中失掉了库的列表,并且查找到一切*boost*<library-name>*.lib模样的lib文件。既前往了包括静态链接库也前往了包括了静态库。

下一步我们将在构建的库文件的列表上创立外部衔接,运用它来查找遗漏的库。

紧接着,我们添加遗漏的库到BoostOutputs为了在需求是运用。

然后我们添加静态链接库。

列表将由Build Target来断定能否需求履行反省。

本文中的一切译文仅用于进修和交换目标,转载请务必注明文章译者、出处、和本文链接。 2KB翻译任务按照 CC 协议,假如我们的任务有进犯到您的权益,请实时联络我们。


2KB项目(www.2kb.com,源码交易平台),提供担保交易、源码交易、虚拟商品、在家创业、在线创业、任务交易、网站设计、软件设计、网络兼职、站长交易、域名交易、链接买卖、网站交易、广告买卖、站长培训、建站美工等服务

  • 全部评论(0)
资讯详情页最新发布上方横幅
最新发布的资讯信息
【计算机/互联网|】Nginx出现502错误(2020-01-20 21:02)
【计算机/互联网|】网站运营全智能软手V0.1版发布(2020-01-20 12:16)
【计算机/互联网|】淘宝这是怎么了?(2020-01-19 19:15)
【行业动态|】谷歌关闭小米智能摄像头,因为窃听器显示了陌生人家中的照片(2020-01-15 09:42)
【行业动态|】据报道谷歌新闻终止了数字杂志,退还主动订阅(2020-01-15 09:39)
【行业动态|】康佳将OLED电视带到美国与LG和索尼竞争(2020-01-15 09:38)
【行业动态|】2020年最佳AV接收机(2020-01-15 09:35)
【行业动态|】2020年最佳流媒体设备:Roku,Apple TV,Firebar,Chromecast等(2020-01-15 09:31)
【行业动态|】CES 2020预览:更多的流媒体服务和订阅即将到来(2020-01-08 21:41)
【行业动态|】从埃隆·马斯克到杰夫·贝佐斯,这30位人物定义了2010年代(2020-01-01 15:14)
联系我们

Q Q: 7090832

电话:400-0011-990

邮箱:7090832@qq.com

时间:9:00-23:00

联系客服
商家入住 服务咨询 投拆建议 联系客服
0577-67068160
手机版

扫一扫进手机版
返回顶部