如何从外部列表设置链接器的输出文件(在 .vcxproj 中)

How to set linker's OutputFile (in .vcxproj) from external list

我有一堆用于 VS2017 的 C++ 项目 (.vcxproj),它们生成动态库 (DLL),它们的处理方式类似于 "plugins"(即它们由应用程序动态加载)。

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

ProjName1;DLL1
ProjName2;DLL2
...

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

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

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

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

我想,msbuild 的某些功能可以用于此(例如,ReadLinesFromFile task and FindInList task),但我不确定如何将这些部分组合在一起。

有一些此类自动化的示例需要考虑,但我怀疑它们是否与 .vcxproj 格式相关:

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

还有其他选择吗?


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

使用 属性 工作表,在我的情况下很容易 'inject' 修复所有项目:

<?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>

虽然效果很好,但该方法不能完全满足我的需求 - 我希望将所有模块名称放在一个文件中。

经过一些调查和尝试,我终于设法为我的案例制定了一个可行的解决方案。基本上它是建立在我之前的部分解决方案之上的,使用了 Regex. The hint how to handle regex in my context was found in another answer to similar question.

的魔力

我还根据自己的喜好调整了列表格式:

DLL1=ProjName1
DLL2=ProjName2
...

我已将更改放在 属性 sheet 中,因此所有相关项目都可以轻松获取它们:

<?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 v.15.9.15)在检测[中的更改方面相当"lazy" =12=] 当解决方案打开时,您必须将其关闭并重新打开。更改列表后很有可能需要重建。