1

I am writing a Visual Studio extension in C# and I need to capture programmatically all the options set by the compiler when the user runs a build.

I have realized that I can get some of them from the Project Properties (like all the -I and -D). But some are "invisible" and I realized that they are the macros set by the compiler itself. I have found a page listing all of them at: https://learn.microsoft.com/fr-fr/cpp/preprocessor/predefined-macros?view=vs-2019.

I could find a lot of those I am looking for: __cplusplus, _MSVC_LANG, _MSC_VER, _CPPRTTI, _MSC_FULL_VER, _MSC_EXTENSIONS, etc.

I am looking for the (C#) API allowing to get all those macros values programmatically so my VS extension can get them and inject them in my process.

Thanks for your help!

Stephane
  • 333
  • 1
  • 13
  • Most of the macros you want to expand are defined in `Microsoft.Cpp.Common.props` file, path: `C:\Program Files (x86)\Microsoft Visual Studio\xxx\xxx\Common7\IDE\VC\VCTargets` – LoLance Nov 27 '19 at 03:47

1 Answers1

1

The normal way I know to get the expanded value of macros is to use MSBuild knowledge.

Choose any C++ project, add this script into the xx.vcxproj and we can get the details in output log:

  <Target Name="GetExpandedValue" AfterTargets="build">
    <Message Text="VS_IncludePath = $(VC_IncludePath)" Importance="high" />
    <Message Text="WindowsSDK_IncludePath = $(WindowsSDK_IncludePath)" Importance="high" />
  </Target>

But it's hard to get the expanded value by any api from VS SDK. Those macros are defined in a msbuild props file: C:\Program Files (x86)\Microsoft Visual Studio\xxx\xxx\Common7\IDE\VC\VCTargets\Microsoft.Cpp.Common.props.Those macros are defined there and I don't find any api in VS SDK or .net framework that can be used expand them.

I can only imagine a possible way like this, call the msbuild.exe programmatically to build a xx.csproj file with script above, and get the output logger. Then parse it to get the useful info we need from the log. It would be a big job...

So if you don't have special need for the expanded value, I suggest you get the value in your machine, and insert the value into your extension code. (As I know, if we use same VS version with similar workloads, the value of those unique macros are the same. )

LoLance
  • 25,666
  • 1
  • 39
  • 73
  • Thanks for your answer! My take away in my case is that if I want to get those value "immediately" in my process, I can only hope for a best effort workflow guessing the main ones from your hints, while if I want to get those values exactly and exhaustively, I cannot get them "immediately" and I have to run MSBuild so that it will resolve all of them. – Stephane Nov 27 '19 at 10:08
  • The bad news is it seems no api available to return the expanded value directly. And the good news is since same VS version with similar workloads, the value of them are the same by default. So We may get the value in our machine with VS2015, 2017, 2019 with C++ workload. Then we can know the value of current vs by judging its vs version... – LoLance Nov 27 '19 at 10:11
  • I don't understand what you mean. Can you clarify about how I could work around? – Stephane Nov 27 '19 at 10:19
  • I mean apart from the getting useful info from log like [this](https://stackoverflow.com/questions/7264682/running-msbuild-programmatically/42816251#42816251), another direction is to do some tests to get the value of the `$(VC_IncludePath)` in VS2015, VS2017, VS2019... Just like what I described above, those marcos are defined in `Microsoft.Cpp.Common.props` file(This file differs from VS2015~2019). So for same vs version with C++ workload, the value is the same. e.g: For VS2015, the value of `$(VC_IncludePath)` is A, for VS2017=>B, for VS2019=>C. – LoLance Nov 27 '19 at 10:49
  • So we can know current value by determining which vs version your extension is installed in. The macros are defined in `Microsoft.Cpp.Common.props` file. So they have fixed value! So I think maybe we don't really need to get their values programmatically... – LoLance Nov 27 '19 at 10:55
  • I don't get what you mean by: "for same vs version **with C++ workload**"... Apart from that, I had a look on the `Microsoft.Cpp.Common.props` file, and it is awfully complex: I have not a single chance to re-implement correctly the logic to expand all these multi-level nested conditional rules. I went down through at least 6 or 7 levels trying to get the final expanded value for `$(VC_IncludePath)` and I still was not finished. Do you mean I should have a best bet about where the includes should be (if the user has used the default Visual Studio location)? – Stephane Nov 28 '19 at 10:27
  • On my machine it is `C:/Program Files (x86)/Microsoft Visual Studio/2017/Professional/VC/Tools/MSVC/14.15.26726/include`. Should I bet that it should be /VC/Tools/MSVC//include? How could I get the exact correct ? And how to guess correctly for `$(WindowsSDK_IncludePath)`? On my machine, it is: `C:/Program Files (x86)/Windows Kits/10/include/10.0.17134.0/`. I suppose it does not go with Visual Studio: how to guess correctly the base directory and the version number? – Stephane Nov 28 '19 at 10:29
  • When I create a new test C++ project and go directly (without building) to the Project Properties > VC++ Directories > Include Directories and select "Edit..." and open the "Macros" pane, all the macros are expanded. It really like Visual Studio has an internal API to get macro expanded values!!! Or is MSBuild launched in the background when creating the new project to produce all macros expanded values? – Stephane Nov 28 '19 at 11:02
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/203234/discussion-between-lance-li-msft-and-stephane). – LoLance Nov 28 '19 at 11:04