如何提取 vcxproj 中每个编译单元的编译参数?

问题描述 投票:0回答:5

我正在尝试获取每个编译单元的编译参数,以便我可以为我的 vcxproj 创建可与 clang 的 libTooling 一起使用的“compilation_commands.json”。

libTooling 教程 建议使用

CompilationDatabase
为项目中的所有 cpp 文件提供编译参数。本教程显示 CMake 可以为基于 CMake 的项目生成compilation_commands.json。

由于 clang 可以通过

clang.exe --driver-mode=cl
clang-cl.exe
进入“MSVC 模式”,我的想法是,如果我可以获得 VS2012 项目中每个 cpp 文件的编译参数,我可以为 vcxproj 创建compilation_commands.json。

但是,我在 VS2012 SDK 中找不到用于遍历 vcxproj 并检索每个编译单元的编译参数的 API。有人能给我指出正确的 API 吗?

visual-studio-2012 msbuild clang visual-studio-sdk
5个回答
2
投票

我知道这确实很旧,但问题仍然相关,所以对于那些仍在寻找答案的人来说,我最近终于使用 this 小 VS 扩展做到了这一点。

只需安装它,就会出现一个新的“Sourcetrail”菜单,其中包含“创建编译数据库”条目(我发现需要启用 Intellisense 才能单击)。这将让您自定义要包含的内容并生成一个

compile_commands.json
,您可以将其与其他基于 clang 的工具等一起使用。


1
投票

您可以尝试解析中间目录下的CL.command.*文件。

https://gist.github.com/Trass3r/f3fbe6807d28106e917368c33abf45d4


1
投票

这是一项 DIY 工作。 VS IDE 项目具有每个 .cpp 文件的属性。通过选择 .cpp,然后右键单击 -> 属性 -> 配置属性 -> C/C++ -> 命令行,您将获得编译该特定文件所需的选项。 64 美元的问题是如何为项目/解决方案中的每个文件执行此操作。答案并不简单,但它是可行的。至少我在 VS 2010 上做到了,并且我很确定它可以在 VS 2012/3 上工作

秘密在于所谓的 VCEngine。它是一个评估项目中所有属性或文件的工具。所以真正的问题是如何评估每个文件的“命令行”属性。您需要遍历所有 .cpp 文件并为“命令行”属性调用 VCProject 的 Evaluate 方法。

我认为最简单的方法是为 VS IDE 编写一个插件,从而访问 VCEngine 实例。有很多关于如何做到这一点的例子。请注意,VCEngine 与版本相关。

无论如何,对于具有数千个.cpp文件的项目/解决方案,您需要自动创建编译数据库。

等我有时间我会把解决方案放在github上


0
投票

您可能有兴趣阅读本文 compile_commands.json 适用于 Windows/MSVC


0
投票

您可以通过劫持编译器来做到这一点。主要缺点是您将不再收到编译器二进制文件的名称。

  1. 将此 Python 脚本嵌入到

    cc.bat
    中(这还会将
    INCLUDE=...
    环境变量转换为
    /external:I...
    参数
    ):
    @python3 -u -s -E -I -c "import io, json, os, subprocess, sys; argv = sys.argv[1:]; cc = 'cl.exe'; includes = ['/external:I' + s for s in os.getenv('INCLUDE', '').split(os.pathsep) if s]; is_resp = len(argv) > 0 and argv[0].startswith('@'); cmdline = io.open(argv[0][1:], 'r', encoding='utf-16-le').read().lstrip('\uFEFF') if is_resp else None; filename = (cmdline[cmdline.rfind('\x22', 0, len(cmdline) - 2):].strip('\x22') if cmdline.rstrip().endswith('\x22') else cmdline[cmdline.rfind(' ') + 1:]) if is_resp else argv[-1]; json.dump({'directory': os.getcwd(), 'file': filename, ('command' if is_resp else 'arguments'): subprocess.list2cmdline([cc]) + ' ' + cmdline + (' ' + subprocess.list2cmdline(includes) if includes else '') if is_resp else [cc] + argv + includes}, sys.stdout)" %*

  2. 然后调用 MSBuild,并将

    MultiProcCL
    设置为
    true
    (这很重要,因为否则您将在同一编译命令中收到多个文件名):
    MSBuild -noLogo -v:m -t:ClCompile -p:BuildInParallel=false -m:1 -p:MultiProcCL=true -p:CLToolExe="%CD%\cc.bat"

现在标准输出上有一堆 JSON 行,每个文件一个,您可以使用逗号手动连接(并嵌入括号内)以创建 JSON 数组。

© www.soinside.com 2019 - 2024. All rights reserved.