我有很多用于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 task和FindInList 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>
尽管效果很好,但是这种方法不能完全满足我的需求-我想将所有模块名称都放在一个文件中。
答案 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 v.15.9.15)在检测_MODULES.txt
中的更改时非常“懒惰”,而该解决方案是打开的,因此您必须将其关闭然后重新打开。更改列表后,很有可能需要重建。