how do I add preprocessor #define in devenv command line? - preprocessor

Is there a way to add extra preprocessor #define in devenv command line?

I am not entirely sure what you mean by vcbuild command line but if you mean the Visual C++ command line compiler then you can add defines by add /Dxxxx, e.g.
cl.exe /DSHAREWARE ....
Additional answer based on comments:
You should be able to set the CL environment variable with the extra preprocessor define:
SET CL=/DSHAREWARE
devenv ....
Mere information can be found at MSDN

in your project settings, add the following preprocessor definition:
$(MyPreprocessorDefinitions);
then in your *.bat file, use
REM #define MY_DEF
set MyPreprocessorDefinitions=MY_DEF
devenv.exe ...
REM #undefine MY_DEF
set MyPreprocessorDefinitions=

The #defines are defined in your Visual Studio project file (.dsp or .vcproj file). This is a simple text file. So you could edit the project file from a script, then call devenv.exe.

In my case, I needed to use devenv for other reasons, (and was running in cygwin, so i had sed).
I set a Compilation symbol in the project's properties SED_REPLACE_THIS
and then used sed to set it to something meaningful (ie: DONT_CRASH_AS_MUCH)
sed -i 's/SED_REPLACE_THIS/DONT_CRASH_AS_MUCH/g' project.csproj

I couldn't find a way without modifying solution or project files so I came up with the following:
Create empty file as part of build e.g. feature_flag.h
Replace #if FEATURE_FLAG with #if !__has_include("feature_flag.h")
Remove feature_flag.h at the end of the build
It's not using #define but it does use the preprocessor which was what I needed.

Related

Is it possible to set the properties on the command line for sourceanalyzer?

I'd like to change the scan properties on only one project for our build server. I've found tons of references for what to change in the various fortify ".properties" files, but I don't want to make any changes that will be universal.
Is it possible to either define these on the command line or, even better, specify a specific .properties file to use only for the current scan?
Note, this has to be via the command line.
Yes, for any property that you want to change put it in the appropriate command line (translate vs scan) in the following format:
-D<property key>=<property value>
for example
sourceanalyzer -b mybuild -Dcom.fortify.sca.fileextensions.sql=PLSQL *.sql

Does the preprocessor pass environment variables?

Does the preprocessor have a mechanism to access environment variables directly as defines, without the need to define them on the command line?
For instance,
SOME_VAR=foo gcc code.c
and
#if ENV_SOME_VAR == "foo"
#define SOME_VAR_IS_FOO
#endif
No, the standard C preprocessor has no such mechanism, and I'm not aware of any compiler extensions that provide such a feature either.
However, you can do this using a build system, such as Cmake or GNU Autoconf, the latter being a part of the GNU Autotools build system. A simple shell script would do this as well, though all of these options mean you'd need to test the environment variable to determine whether to define ENV_SOME_VAR, in which case, you might just define it using something like the following:
-DENV_SOME_VAR="${SOME_VAR:-unfoo}"
That would define ENV_SOME_VAR in your C file as the value of $SOME_VAR if it's set or to the string "unfoo" if $SOME_VAR is empty (null) or unset.

C++ precompiler conditionally include code

I have a few projects that share a lot of common code, but sometimes I need to not include certain parts of the common code depending on the project.
I've tried creating a separate file called project_names.hh, containing this:
// list of project names
#define FIRSTPROJECT 0
#define SECONDPROJECT 1
// PROJECT_NAME must be set to one of the above names in the project's main.cc file
#define PROJECT_NAME
Then in one of the projects' main files I do this:
#define PROJECT_NAME FIRSTPROJECT
The problem is that even though I include project_names.hh in another file, I can't seem to get this statement to compile:
#if PROJECT_NAME == FIRSTPROJECT
I get this error:
error: operator '==' has no left operand
Does anyone have a good way to do this?
Thanks!
Marlon
That's because you've defined PROJECT_NAME to be the empty string with your line
#define PROJECT_NAME
you want to change it to
#define PROJECT_NAME FIRSTPROJECT
This needs to be in a header file that all the files of that project #include.
Alternatively, you could get rid of the #define PROJECT_NAME and instead use
-DPROJECT_NAME=FIRSTPROJECT on the compiler command line for all the files in that project. Note that if the same file is used in multiple projects, you'll need to compile it mulitple times with different options, and have it put the output in different places...
If I were in your situation I would simply define either FIRSTPROJECT or SECONDPROJECT instead of setting PROJECT_NAME to either of those values. I would then use #ifdef to check whether that value is set.
rather than #define PROJECT_NAME FIRSTPROJECT,
use #define FIRSTPROJECT,
then check its existence with #ifdef FIRSTPROJECT
You should include project_names.hh in the file in which you're running the #if PROJECT_NAME == FIRSTPROJECT. The preprocessor might not have loaded and executed the statements setting PROJCET_NAME in the first place.
This is most probably because the PROJECT_NAME isn't set. You should check, which file is being compiled and check if the #define is set there.
It might help to set the define as a compiler option for the whole building process. For most compilers that I know (gcc, MSVC, clang, xlC), the compiler option would be
-DPROJECT_NAME=FIRSTPROJECT

Can I add conditional defines in the msbuild command line?

I have the following sample code:
program boohoo;
{$APPTYPE CONSOLE}
{$IFDEF boo}
{$MESSAGE warn 'boo'}
{$ENDIF}
{$IFDEF hoo}
{$MESSAGE warn 'hoo'}
{$ENDIF}
begin
end.
In the project options the conditional boo is defined. I would like to be able to add the conditional hoo as part of my msbuild command line.
I have tried it like this:
msbuild boohoo.dproj /p:Config=Release;DCC_Define="$(DCC_Define);hoo"
The output shows hoo but not boo. When I use verbose output to see the dcc32 command I see
-D$;hoo
Clearly I can do it like this:
msbuild boohoo.dproj /p:Config=Release;DCC_Define="boo;hoo"
but naturally I want to use whatever conditionals are declared in the project options plus what I specify on the command line.
Is there any way for me to specify this property with reference to the value from the underlying configuration?
Disclaimer: don't use MsBuild myself yet, all taken from the docs and some IDE experimentation
According to MsBuild command line reference ( http://msdn.microsoft.com/en-us/library/ms164311.aspx ):
/property:name=value
Sets or overrides these project-level properties, where name is the
property name and value is the property value. Use a semicolon or a
comma to separate multiple properties, or specify each property
separately. /p is also acceptable. For example:
/property:WarningLevel=2;OutputDir=bin\Debug
setting or overriding is all you can do for a property value. Adding to a property value from the project file is either not possible or a case of a hidden feature.
But I guess what you could do is define a custom property in your dproj file with an " " as its default value:
<PropertyGroup>
<ExtraDefines> </ExtraDefines>
</PropertyGroup>
reference that in your defines statement
<DCC_Define>DUNIT;$(ExtraDefines);$(DCC_Define)</DCC_Define>
which in the IDE should be DUNIT;$(ExtraDefines)
and then specify it on the command line:
msbuild boohoo.dproj /p:Config=Release;ExtraDefines="hoo"
I did test adding the $(ExtraDefines) to the Include options for the project using the IDE. And at least that didn't barf at me, even without having the option defined in the dproj. The commandline the IDE produced from this was:
...rad studio\7.0\bin\dcc32.exe --no-config -B -Q -DDEBUG;DUNIT; -E....
Which seems to indicate that the $(ExtraDefines) got eliminated as it had no value. And that it should be picked up using MSBuild and specififying a value on the command line.
Almost 5 years later, but all answers are not quite elegant ))
Recently, I've faced the same problem
And here is the solution:
Usually, DCC_Define is defined in a .dproj file like this:
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_Define>boo;$(DCC_Define)</DCC_Define>
We all have tried to define DCC_Define via /property:DCC_Define=blah-blah
But accordingly to How to: Build the Same Source Files with Different Options:
The property value that is specified on the command line takes precedence over any value that is set for the same property in the project file, and that value in the project file takes precedence over the value in an environment variable.
So, failure (that is the question here!)
BUT! How to: Use Environment Variables in a Build
To use an environment variable in an MSBuild project
Reference the environment variable the same way you would a variable declared in your project file. For example, the following
code references the BIN_PATH environment variable:
<FinalOutput>$(BIN_PATH)\MyAssembly.dll</FinalOutput>
So, we must define environment variable with the name DCC_Define and values of our ADDITIONAL conditionals
> set DCC_Define=hoo;doo;moo;foo
and then simply run
> msbuild boohoo.dproj /p:Config=Release
DCC32 will get then -Dboo;hoo;doo;moo;foo
Straightforward solution is to create a new build configuration (say, boohooRelease), add both boo and hoo conditional defines to it and compile as msbuild boohoo.dproj /p:Config=boohooRelease. Not exactly what you are trying to do, but it works.
I just tried the following and it worked, so don't know whether Microsoft has changed it:
msbuild "myApp.dproj" /t:build /property:DCC_Define="boo"
remember to add the double quote "", otherwise it won't work
Another way is to create a wrapper project file like this:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Full" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Full">
<CreateProperty Value="$(DCC_Define);$(ExtraDefines)">
<Output TaskParameter="Value" PropertyName="DCC_Define"/>
</CreateProperty>
</Target>
<Import Project="example.dproj" />
</Project>
and invoke like this:
msbuild.exe "/t:Clean;Full;Build" "/p:config=Debug" /p:ExtraDefines=SOME_DEFINE wrapper.proj
It is certainly less elegant but you don't have to modify the .dproj file.

Preserving environment variables in CMake

I am working on something that requires some header files from a different source tree. For various reasons, I would like to keep these headers outside of my project and reference them during the make process.
I have a CMake build script that generates my makefiles, but I would like to be able to generate makefiles with references to environment variables in them, such that the generated makefile can be run like so:
HEADERS=/somewhere/on/the/filesystem make
Is this possible using CMake? Failing that, is there a way to get what I'm after using CMake only?
This seems to have worked for me:
set(${PROJECT_NAME}_PORT "$(TARGET_SERIAL_PORT)")
It's a real-world example but I hope it gives you an idea. You can assign a string to a variable which will be copied verbatim to the Makefile.
You should look at add_custom_command using the TARGET and PRE_LINK options.
You can use $ENV{VARIABLE} to get the value of an environment variable, but it will only be evaluated during the cmake run and not during the make.
For passing environment variable to make, you can:
CMAKE_POLICY(PUSH)
CMAKE_POLICY(SET CMP0005 NEW)
ADD_DEFINITIONS(-DHEADER=$ENV{HEADER})
CMAKE_POLICY(POP)
Replace HEADER to whatever your variable name.
Setting cmake policy CMP0005 is for cmake to generate correct escape for you.

Resources