如何从外部列表设置链接器的OutputFile(在.vcxproj中)

时间:2019-09-20 15:13:05

标签: visual-studio msbuild visual-studio-2017 visual-studio-2017-build-tools vcxproj

我有很多用于VS2017的C ++项目(.vcxproj),它们生成动态库(DLL),这些库的处理方式类似于“插件”(即它们由应用程序动态加载)。

有时我想根据文本文件中的某些列表更改生成的DLL名称(格式可能会更改):

ProjName1;DLL1
ProjName2;DLL2
...

第一列指定项目名称($(ProjectName)),第二列指定所需的DLL名称($(TargetName))。

我希望在构建时解析此文件,因此每个读取的DLL名称都放入相应项目的$(OutputFile)中。

例如,ProjName1.vcxproj将具有以下片段(在构建时):

<Link>
  <OutputFile>$(OutDir)DLL1$(TargetExt)</OutputFile>
</Link>

我猜想,msbuild的某些功能可以用于此目的(例如ReadLinesFromFile taskFindInList task),但我不确定如何将这些部分放在一起)。 / p>

虽然我怀疑它们是否与.vcxproj格式相关,但仍可以考虑使用此类自动化的一些示例:

直接的方法是修改每个.vcxproj文件的内容以匹配列表(手动或使用某些脚本)。

还有其他选择吗?


更新1 :我设法实现了部分解决方案,该解决方案基于每个项目的DLL名称(模块名称)的单独文件(请参阅Property Functions以获得更多提示。

使用属性表,对于我来说很容易将修复程序“注入”到所有项目中:

<?xml version="1.0" encoding="utf-8"?> 
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
...
  <PropertyGroup Condition="exists('$(MSBuildProjectDirectory)\_MODULE.name')">
    <ModuleName>$([System.IO.File]::ReadAllText('$(MSBuildProjectDirectory)\_MODULE.name'))</ModuleName>
    <TargetName>$(ModuleName)</TargetName>
  </PropertyGroup>
...
</Project>

尽管效果很好,但是这种方法不能完全满足我的需求-我想将所有模块名称都放在一个文件中。

1 个答案:

答案 0 :(得分:0)

经过一些调查和试用,我终于设法为我的案件提供了可行的解决方案。基本上,它是通过使用Regex的魔力在我先前的部分解决方案的基础上构建的。在another answer to similar question中找到了如何在我的上下文中处理正则表达式的提示。

我也根据自己的喜好对列表格式进行了调整:

DLL1=ProjName1
DLL2=ProjName2
...

我已将更改放置在属性表中,以便所有相关项目都可以轻松提取它们:

<?xml version="1.0" encoding="utf-8"?> 
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
...
  <PropertyGroup Condition="exists('$(MSBuildThisFileDirectory)..\_MODULES.txt')">
    <ModulesNames>$([System.IO.File]::ReadAllText('$(MSBuildThisFileDirectory)..\_MODULES.txt'))</ModulesNames>
    <ModuleName>$([System.Text.RegularExpressions.Regex]::Match($(ModulesNames), '\W?(\w*)\W?=\W?$(MSBuildProjectName)\W?').get_Groups().get_Item(1))</ModuleName>
    <TargetName>$(ModuleName)</TargetName>
  </PropertyGroup>
...
</Project>

如果该项目未在_MODULES.txt中列出,则其$(TargetName)不会受到影响。

如果您在项目设置中看到$(ModuleName),则一切都已正确调整: VS2017 project settings

该解决方案似乎工作正常,除了一个小缺点:构建系统(VS2017 v.15.9.15)在检测_MODULES.txt中的更改时非常“懒惰”,而该解决方案是打开的,因此您必须将其关闭然后重新打开。更改列表后,很有可能需要重建。