7

I'm currently trying to switch between a few different default Icons in a Visual C++ .rc file using #ifdef tags.

The builds switching the #define value are being created through command line using MSBuild.

The difficulty I have been running into is that using Visual Studio 2010, in order to pass a preprocessor definition to the resource compiler you must define it in the project settings (Config Properties -> Resources -> General).

This makes it difficult to use an #ifdef tag because using this method it will always be defined in the resource compiler.

I would love to define it to a value, so that I might use a preprocessor #if SOMEVALUE == 4 might work, but Cannot seem to find a way to pass a Preprocessor definition + value to MSBuild via the command line.

Does anyone know a way to pass a preprocessor definition directly through to the resource compiler or a way to define a value for a preprocessor definition via commandline for msbuild?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Maixy
  • 1,151
  • 2
  • 12
  • 27

4 Answers4

7

Yes, this can be done.

Try using environment variables to pass values into your build process.

In your project properties add ;$(CMDLINE_DEFINES) to the end of your resource preprocessor definitions. (Be sure to pick the right configuration.)

Then when you use MSBuild from the command line type (or add to a batch file)...

C:\Projects\SomeProject> set CMDLINE_DEFINES=SOMETEST=42
C:\Projects\SomeProject> MSBuild SomeProject.vcproj

A batch file may look like:

@echo off
SET CMDLINE_DEFINES=%1
MSBUILD SomeProject.vcproj

Using this batch file, whatever you pass on the commandline will be passed on to the build process as your preprocessor macro(s).

2

See the answer to this, with the additional step of setting up ResourceCompile options, i.e. edit your project file in a text editor to include elements like this:

<ItemDefinitionGroup>
    <ClCompile>
        <AdditionalOptions>/DERROR_LOG_LEVEL=5 %(AdditionalOptions)</AdditionalOptions>
    </ClCompile>
    <ResourceCompile>
        <AdditionalOptions>/DERROR_LOG_LEVEL=5 %(AdditionalOptions)</AdditionalOptions>
    </ResourceCompile>
</ItemDefinitionGroup>
Community
  • 1
  • 1
fakeleft
  • 2,830
  • 2
  • 30
  • 32
2

The difficulty I have been running into is that using Visual Studio 2010, in order to pass a preprocessor definition to the resource compiler you must define it in the project settings (Config Properties -> Resources -> General).

You got the hard part. Just enter the define as TESTAPPLE=15 and it will effectively #define TESTAPPLE 15 for the entire project.

Praetorian
  • 106,671
  • 19
  • 240
  • 328
Mooing Duck
  • 64,318
  • 19
  • 100
  • 158
  • 1
    Unfortunately #define values that are passed to project compiler don't get passed down to the Resource compiler. I.e., /D "TESTAPPLE=15" in when compiling the project sets TESTAPPLE to a value of 15. In the Resource Compiler, however, TESTAPPLE is just defined, but doesn't have a value of 15. – Maixy Aug 22 '11 at 18:08
  • huh, guess I haven't played with the resource compiler enough. http://www.cmake.org/pipermail/cmake/2011-January/042093.html implies that it works `/d "CMAKE_INTDIR=\"Release\""`, but not an authoritive source. – Mooing Duck Aug 22 '11 at 21:40
0

Although this is an old question, but for any reference now, the following steps work with me:

  1. Pass the variable = underlying value in msbuild command line using /p, e.g.
msbuild my_solution.sln /p:ENVSOMEVALUE="4"
  1. In the project file my_proj.vcxproj, define the variable as a preprocessor definition for the resource compiler, and assign it to the variable passed from msbuild, e.g. add the following section inside <Project></Project>:
  <ItemDefinitionGroup>
    <ResourceCompile>
      <PreprocessorDefinitions>
        SOMEVALUE=$(ENVSOMEVALUE);
        %(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ResourceCompile>
  </ItemDefinitionGroup>

  1. in the .rc file, use the code the way you like:
#if SOMEVALUE == 4 

You might need to set a default value for the definition if not passed from msbuild (e.g. building from Visual Studio IDE), in this case you might use the condition manually in the project file, e.g.

  <ItemDefinitionGroup  Condition="'$(ENVSOMEVALUE)'!=''">
    <ResourceCompile>
      <PreprocessorDefinitions>
        SOMEVALUE=$(ENVSOMEVALUE);
        %(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ResourceCompile>
  </ItemDefinitionGroup>  
  <ItemDefinitionGroup  Condition="'$(ENVSOMEVALUE)'==''">
    <ResourceCompile>
      <PreprocessorDefinitions>
        SOMEVALUE=1; <!-- Default Value -->
        %(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ResourceCompile>
  </ItemDefinitionGroup>  
Bassem Ramzy
  • 326
  • 3
  • 10