美文网首页
Vcpkg免配置实现分析

Vcpkg免配置实现分析

作者: 长不胖的Garfield | 来源:发表于2016-12-16 18:10 被阅读0次

概述

通过Vcpkg安装library,能够不设定include、library的路径,而且可以自动复制依赖库,是利用到了Visual Studio,链接器,还有附带工具达成的。

Vcpkg的目录结构

vcpkg的目录结构
  • ports 可用包配置信息
  • downloads 库源代码包下载存放路径
  • buildtrees 库构造路径
  • packages 库编译结果
  • installed 库安装目录

其中installed存放了已安装信息,并且按照规则集中存放库内容

  • x86-windows 32位windows库
  • x64-windows
  • x86-windows-static 32位windows静态库
  • x64-windows-static
  • x86-uwp 32位uwp库
  • x64-uwp
  • arm-uwp

目录结构如下:

bin
debug
  bin
  lib
include
lib
share

也就是说,通过这种方式安装的库,是有统一的存放规则的,通过这些规则可以合并出对应的include、library、binary文件路径。

targets文件

Visual Studio的构建系统使用的是MSBuild,配置及构建目标定义都可以存放在.props和.targets文件中,由于安装的库遵循统一规则,因而在vcpkg\scripts\buildsystems\msbuild下可以找到完成上述统一配置的targets文件vcpkg.targets.

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup Condition="'$(Platform)|$(ApplicationType)|$(ApplicationTypeRevision)' == 'Win32||'">
    <VcpkgEnabled Condition="'$(VcpkgEnabled)' == ''">true</VcpkgEnabled>
    <VcpkgTriplet Condition="'$(VcpkgTriplet)' == ''">x86-windows</VcpkgTriplet>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Platform)|$(ApplicationType)|$(ApplicationTypeRevision)' == 'Win32|Windows Store|10.0'">
    <VcpkgEnabled Condition="'$(VcpkgEnabled)' == ''">true</VcpkgEnabled>
    <VcpkgTriplet Condition="'$(VcpkgTriplet)' == ''">x86-uwp</VcpkgTriplet>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Platform)|$(ApplicationType)|$(ApplicationTypeRevision)' == 'x64||'">
    <VcpkgEnabled Condition="'$(VcpkgEnabled)' == ''">true</VcpkgEnabled>
    <VcpkgTriplet Condition="'$(VcpkgTriplet)' == ''">x64-windows</VcpkgTriplet>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Platform)|$(ApplicationType)|$(ApplicationTypeRevision)' == 'x64|Windows Store|10.0'">
    <VcpkgEnabled Condition="'$(VcpkgEnabled)' == ''">true</VcpkgEnabled>
    <VcpkgTriplet Condition="'$(VcpkgTriplet)' == ''">x64-uwp</VcpkgTriplet>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Platform)|$(ApplicationType)|$(ApplicationTypeRevision)' == 'arm|Windows Store|10.0'">
    <VcpkgEnabled Condition="'$(VcpkgEnabled)' == ''">true</VcpkgEnabled>
    <VcpkgTriplet Condition="'$(VcpkgTriplet)' == ''">arm-uwp</VcpkgTriplet>
  </PropertyGroup>

  <PropertyGroup Condition="'$(VcpkgEnabled)' == 'true'">
    <VcpkgConfiguration Condition="'$(VcpkgConfiguration)' == ''">$(Configuration)</VcpkgConfiguration>
    <VcpkgRoot Condition="'$(VcpkgRoot)' == ''">$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), .vcpkg-root))\installed\$(VcpkgTriplet)\</VcpkgRoot>
  </PropertyGroup>

  <ItemDefinitionGroup Condition="'$(VcpkgEnabled)' == 'true'">
    <Link>
      <AdditionalDependencies Condition="'$(VcpkgConfiguration)' == 'Debug' and '$(VcpkgAutoLink)' != 'false'">%(AdditionalDependencies);$(VcpkgRoot)debug\lib\*.lib</AdditionalDependencies>
      <AdditionalDependencies Condition="'$(VcpkgConfiguration)' == 'Release' and '$(VcpkgAutoLink)' != 'false'">%(AdditionalDependencies);$(VcpkgRoot)lib\*.lib</AdditionalDependencies>
      <AdditionalLibraryDirectories Condition="'$(VcpkgConfiguration)' == 'Release'">%(AdditionalLibraryDirectories);$(VcpkgRoot)lib;$(VcpkgRoot)lib\manual-link</AdditionalLibraryDirectories>
      <AdditionalLibraryDirectories Condition="'$(VcpkgConfiguration)' == 'Debug'">%(AdditionalLibraryDirectories);$(VcpkgRoot)debug\lib;$(VcpkgRoot)debug\lib\manual-link</AdditionalLibraryDirectories>
    </Link>
    <ClCompile>
      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(VcpkgRoot)include</AdditionalIncludeDirectories>
    </ClCompile>
  </ItemDefinitionGroup>

  <Target Name="AppLocalFromInstalled" AfterTargets="CopyFilesToOutputDirectory" BeforeTargets="CopyLocalFilesOutputGroup" Condition="'$(VcpkgEnabled)' == 'true' and '$(OutputType)' == 'exe'">
    <WriteLinesToFile
    File="$(TLogLocation)$(ProjectName).write.1u.tlog"
    Lines="^$(OutputPath)$(TargetName).$(OutputType);" Encoding="Unicode"/>
    <Exec Condition="'$(VcpkgConfiguration)' == 'Debug'"
      Command="powershell.exe -ExecutionPolicy Unrestricted -noprofile -File %22$(MSBuildThisFileDirectory)applocal.ps1%22 %22$(OutputPath)$(TargetName).$(OutputType)%22 %22$(VcpkgRoot)debug\bin%22 %22$(TLogLocation)$(ProjectName).write.1u.tlog%22"
      ConsoleToMSBuild="true">
        <Output TaskParameter="ConsoleOutput" ItemName="ReferenceCopyLocalPaths" />
    </Exec>
    <Exec Condition="'$(VcpkgConfiguration)' == 'Release'"
      Command="powershell.exe -ExecutionPolicy Unrestricted -noprofile -File %22$(MSBuildThisFileDirectory)applocal.ps1%22 %22$(OutputPath)$(TargetName).$(OutputType)%22 %22$(VcpkgRoot)bin%22 %22$(TLogLocation)$(ProjectName).write.1u.tlog%22"
      ConsoleToMSBuild="true">
        <Output TaskParameter="ConsoleOutput" ItemName="ReferenceCopyLocalPaths" />
    </Exec>
  </Target>
</Project>

可以看到,根据不同的配置信息,配置完成了include、library以及binary路径及对应的处理。

与Visual Studio 2015的整合

现在我们知道在Visual Studio 2015中免配置,是通过导入统一的targets来实现的,整合方式是什么样的?

在Visual Studio 2015中支持导入默认的配置,具体路径为:

$(MSBUILDLOCATION)/Microsoft.Cpp/v4.0/V140/ImportBefore/Default/

其中$(MSBUILDLOCATION)通常为C:/Program Files (x86)/MSBuild/.

Vcpkg在执行整合时,会在该路径下创建vcpkg.system.targets文件,内容如下:


<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <!-- version 1 -->
  <PropertyGroup>
    <VCLibPackagePath Condition="'$(VCLibPackagePath)' == ''">$(LOCALAPPDATA)\vcpkg\vcpkg.user</VCLibPackagePath>
  </PropertyGroup>
  <Import Condition="'$(VCLibPackagePath)' != '' and Exists('$(VCLibPackagePath).targets')" Project="$(VCLibPackagePath).targets" />
</Project>

$(LOCALAPPDATA)\vcpkg\下会创建vcpkg.user.targets来导入vcpkg路径下的.targets文件,譬如:


<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Condition="Exists('D:\vcpkg\scripts\buildsystems\msbuild\vcpkg.targets') and '$(VCPkgLocalAppDataDisabled)' == ''" Project="D:\vcpkg\scripts\buildsystems\msbuild\vcpkg.targets" />
</Project>

这种方式无论是通过Visual Studio 2015还是MSBuild构造工程都可以正确识别,但是Visual Studio 2010无法采用这种方式导入全局配置。

library免配置

常规的library配置会指定依赖的library名称,但是link实际上识别如下方式的lib依赖配置:

$(LibraryPath)/*.lib

采用这种方式,可以避免单独配置对应的库依赖,但是不适用于同一路径下存放了库的debug和release版本。

自动复制依赖的动态库

link.exe /dump /imports $(target)

以上的命令会输出目标导入的dll和所有符号,譬如:

输出动态库依赖

根据该命令能够得到所有依赖的动态库,然后根据binary路径进行复制。

vcpkg采用的方法:

dumpbin.exe /DEPENDENTS $(target)

输出如下:

dumpbin输出动态库依赖

相关文章

  • Vcpkg免配置实现分析

    概述 通过Vcpkg安装library,能够不设定include、library的路径,而且可以自动复制依赖库,是...

  • 如何实现对Visual Studio 2010的库管理支持

    概述 Vcpkg使用起来确实比较方便,基本上是免工程配置,但是现在只支持Visual Studio 2015及以上...

  • Hadoop用户配置免密登陆

    Hadoop用户配置免密登陆,参考其他免密配置方法自己总结的更简洁的步骤。要实现A免密登陆B,需要把A生成的公钥放...

  • pkgUser-提供给Visual Studio使用的C++工程

    pkgUser 提供给Visual Studio使用的C++工程配置工具Inspired by Vcpkg 功能 ...

  • Centos下“ssh免密码登录不生效”问题

    摘要 一般为了方便运维管理都会配置ssh免密登录,ssh免密登录实现也很方便。今天遇到一个完成了配置了却不能生效的...

  • 常用Git命令

    设置本机绑定SSH公钥,实现免密码登录 git config -l 查看配置 git config --syste...

  • mac下clion通过vcpkg配置catch2

    安装vcpkg git clone https://github.com/microsoft/vcpkg[http...

  • rsync 推送

    rsync 同步推送网上看过很多方法,实现免密同步只可以通过添加ssh-key免登录或者以配置文件启动的守护进程启...

  • Vcpkg: 总览

    Vcpkg: 总览 English Overview[README.md] Vcpkg 可帮助您在 Windows...

  • HDP搭建

    基础环境配置 a.修改主机名配置hosts 配置ambaer-server免密登录其他节点 a. 配置免密登录 b...

网友评论

      本文标题:Vcpkg免配置实现分析

      本文链接:https://www.haomeiwen.com/subject/xvonmttx.html