Question

In a C++ file, I have a code like this:

#if ACTIVATE
#   pragma message( "Activated" )
#else
#   pragma message( "Not Activated")
#endif

I want to set this ACTIVE define to 1 with the msbuild command line.

It tried this but it doesn't work:

msbuild /p:DefineConstants="ACTIVATE=1"

Any idea?

Was it helpful?

Solution 11

The answer is : YOU CANNOT

OTHER TIPS

I'm a little late to the party (only 4 years or so), but I just had to workaround this problem on a project, and stumbled across this question while searching for a fix. Our solution was to use an environment variable with /D defines in it, combined with the Additional Options box in visual studio.

  1. In Visual Studio, add an environment variable macro, $(ExternalCompilerOptions), to the Additional Options under project options->C/C++->Command Line (remember both Debug and Release configs)
  2. Set the environment variable prior to calling msbuild. Use the /D compiler option to define your macros
    c:\> set ExternalCompilerOptions=/DFOO /DBAR 
    c:\> msbuild

Item #1 ends up looking like this in the vcxproj file:

    <ClCompile>
      <AdditionalOptions>$(ExternalCompilerOptions) ... </AdditionalOptions>
    </ClCompile>

This works for me with VS 2010. We drive msbuild from various build scripts, so the environment variable ugliness is hidden a bit. Note that I have not tested if this works when you need to set the define to specific value ( /DACTIVATE=1 ). I think it would work, but I'm concerned about having multiple '='s in there.

H^2

C++ projects (and solutions) are not (yet ?) integrated in the MSBuild environment. As part of the build process, the VCBuild task is called, which is just a wrapper around vcbuild.exe.

You could :

  • create a specific configuration for your solution where ACTIVATE=1 would be defined, and compile it with devenv.exe (with the /ProjectConfig switch).
  • create your own target file to wrap your own call to the VCBuild task (see the Override parameter)...
  • use vcbuild.exe instead of msbuild.exe. (vcbuild.exe does not seem to have the equivalent of an Override parameter).

Note that your solution would not work for C# projects either unless you tweaked your project files a bit. For reference, here is how I would do this :

  • Add the following code before the call to <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> :
<PropertyGroup Condition=" '$(MyConstants)' != '' ">
  <DefineConstants>$(DefineConstants);$(MyConstants)</DefineConstants>
</PropertyGroup>
  • Call MSBuild like this :
msbuild /p:MyConstants="ACTIVATE=1"

I think you want:

/p:DefineConstants=ACTIVATE

If you need to define some constant (not just true/false), you can do it the following way:

On command line:

MSBuild /p:MyDefine=MyValue

In vcxproj file (in section <ClCompile> and/or <ResourceCompile>, depending on where you need it):

<PreprocessorDefinitions>MY_DEFINE=$(MyDefine);$(PreprocessorDefinitions)</PreprocessorDefinitions>

Maybe it is a bad idea to answer such old question, but recently I googled a similar problem and found this topic. I wrote a cmd script for some build system and I was succeed to find a solution. I leave it here for future generations (:

According to @acemtp's problem, my solution would look like this:

@echo off

:: it is considered that Visual Studio tools are in the PATH
if "%1"=="USE_ACTIVATE_MACRO" (
    :: if parameter USE_ACTIVATE_MACRO is passed to script
    :: the macro ACTIVATE will be defined for the project
    set CL=/DACTIVATE#1
)
call msbuild /t:Rebuild /p:Configuration=Release

UPD: I tried to use set CL=/DACTIVATE=1 and it also worked, but the official documentation recommends to use number sign

Use the CL environment variable to define preprocessor macros

Before calling MSBUILD, simply set the environment variable 'CL' with '/D' options like so:

set CL=/DACTIVATE to define ACTIVATE

You can use the '#' symbol to replace '=' sign

set CL=/DACTIVATE#1 will define ACTIVATE=1

Then make the call to MSBUILD

More documentation on the CL Environment Variables can be found at: https://msdn.microsoft.com/en-us/library/kezkeayy(v=vs.140).aspx

I needed to do this too - needed to be able to build two different versions of my app and wanted to be able to script the build using VCBUILD. VCBUILD does have the /override command line switch, but I am not sure it can be used to modify #define symbols that can then be tested using #if conditional compilation.

The solution I cam up with was to write a simple utility to create a header file that #defined the symbol based on the state of an environment variable and run the utility from a pre-build step. Prior to each execution of the VCBUILD step the script sets the environment variable and "touches" a file in the app to ensure that the prebuild step is executed.

Yes, it is an ugly hack, but it was the best I could come up with!

For VS2010 and up, see my answer here for a solution that requires no modification of the original project file.

As @bigh_29 has mentioned, using environment variables to define or undefine a preprocessor.

What he suggested the way to undefine a preprocessor is actually /UACTIVATE.

This way, any preprocessor matching ACTIVATE will be negated and compiler wouldn't go through your #if ACTIVATE #endif enclosure.

It should probably be:

#ifdef ACTIVATE
#   pragma message( "Activated" )
#else
#   pragma message( "Not Activated")
#endif
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top