9

Is there a way to convert something like this:

#define ERROR_LOG_LEVEL 5

Into something that msbuild via command line will pass to its projects?

msbuild.exe {???}ERROR_LOG_LEVEL=5 target

I've read the responses to similar questions, and it looks like the answer is no, just want to double-check in case some genius has found a workaround.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Yimin Rong
  • 1,890
  • 4
  • 31
  • 48
  • 1
    I should add: is there a way to do the above **without** modifying the project or solution file? – Yimin Rong Jan 15 '13 at 17:25
  • 2
    The answer is **Yes** after all, see http://stackoverflow.com/a/17446623/128384 – stijn Jul 03 '13 at 11:26
  • 2
    possible duplicate of [How to set PreProcessorDefinitions as a task propery for the msbuild task](http://stackoverflow.com/questions/15141429/how-to-set-preprocessordefinitions-as-a-task-propery-for-the-msbuild-task) – stijn Jul 03 '13 at 11:28

2 Answers2

7

Macros may be defined by passing the /D option to the compiler. You can specify the /D option from MSBuild using the AdditionalOptions of ClCompile:

<ItemDefinitionGroup>
    <ClCompile>
        <AdditionalOptions>/DERROR_LOG_LEVEL=5 %(AdditionalOptions)</AdditionalOptions>
    </ClCompile>
</ItemDefinitionGroup>

If you want to be able to pass the value for the macro via a call to msbuild.exe, you can easily do that too:

<ItemDefinitionGroup Condition="'$(ErrorLogLevel)' != ''">
    <ClCompile>
        <AdditionalOptions>/DERROR_LOG_LEVEL=$(ErrorLogLevel) %(AdditionalOptions)</AdditionalOptions>
    </ClCompile>
</ItemDefinitionGroup>

with msbuild.exe invoked as:

msbuild /p:ErrorLogLevel=5 MyProject.vcxproj
James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • Yes, you need to modify the project file to propagate the value of the MSBuild property `$(ErrorLogLevel)` to the C++ macro `ERROR_LOG_LEVEL` passed to the compiler via the `/D` option. But, you do not need to use the IDE: you can edit project files and targets/props files in any text editor of your choosing. – James McNellis Jan 15 '13 at 17:23
  • Thank you. Does the method: `msbuild /p:ErrorLogLevel=5 MyProject.vcxproj` require opening the project in MSVC, or any kind of modification to the MyProject.vcxproj file? – Yimin Rong Jan 15 '13 at 17:26
  • Okay. I don't have the option to edit the proj file. Read only. – Yimin Rong Jan 15 '13 at 17:28
  • You can create your own project file that includes the read only project file and specifies the additional options, assuming the read only project file does not do anything horrible like reset ClCompile.AdditionalOptions. – James McNellis Jan 15 '13 at 17:29
  • I'll mark your answer as accepted, but it appears that the answer for my specific case is basically **no**. Thank you for your help. – Yimin Rong Jan 15 '13 at 17:37
  • Sorry just to confirm: isn't there a way to pass a pre-processor definition from the command line without changing the project file? Something to say ```msbuild /p:ERROR_LOG_LEVEL=5 MyProject.vcxproj``` – Giuseppe Salvatore Feb 26 '19 at 18:36
0

I've posted an answer in here, but I copy it for another answer. You need to define a user-defined macro in a PropertySheet. Then create a Preprocessor which refers to the user-defined macro. You can now use the new preprocessor value in your code. Finally, for the build, you can change the value of user-defined macro with /p flag. In here I defined a user-defined value like mymacro and a preprocessor value like VAL. Now you can simply compile the project with /p:mymacro="\"some thing new\"".

#include <iostream>


int main() {
    std::cout << VAL << std::endl;

    getchar();
}

yourproject.vcxproj:

<ClCompile>
  ...
  <PreprocessorDefinitions>VAL=$(mymacro);%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>

msbuild yourproject.vcxproj /p:mymacro="\"some thing new\""

Masoud Rahimi
  • 5,785
  • 15
  • 39
  • 67