How to conditionally compile VC6 resources - mfc

depending on a compile switch (values are COMPILE_A or COMPILE_B), which is set in the form of an envorinment variable, I want to compile my application with different settings, like application name and splash screen.
I got this far:
In "Project / Settings / C/C++ / Preprocessor Definitions" I added $(COMPILESWITCH) (results in command line option /D "$(COMPILESWITCH)").
In stdafx.h I can use the following code, which means I correctly defined the preprocessor definition via the command line parameter:
#if defined COMPILE_A
# define IDB_SPLASH IDB_SPLASH_A
# elif defined COMPILE_B
# define IDB_SPLASH IDB_SPLASH_B
# else
# error Unknown or undefined target compile switch; cannot compile!
# endif
But I've noticed the "Condition" property under "ResourceView / [right-click] / Properties"...
The help text says this:
Condition
Determines the inclusion of
the resource. For example, if the
condition is _DEBUG, this resource
would be included only in debug
builds.
This looks like the elegant way of doing it, right?
Specifiying _DEBUG as condition works. So as _DEBUG is specified via /D _DEBUG my $(COMPILESWITCH) should also work, right?
For some reason it doesn't; why?
Or is there even another, better way to achieve what I want?

I guess I just solved my problem...
The resource compiler uses its own preprocessor.
Therefore the same preprocessor definition has to be added under "Project / Settings / Resources / Preprocessor Definitions".
Edit: String Resources
The above doesn't work for string resources as they don't have a "condition" property...
I chose to use the res\<projectname>.rc2 custom resource file which won't be touched by the resource editor.
The content looks like this
#if defined(COMPILE_A)
STRINGTABLE DISCARDABLE
BEGIN
IDR_MAINFRAME "AppTitle A"
END
#else
# if defined(COMPILE_B)
STRINGTABLE DISCARDABLE
BEGIN
IDR_MAINFRAME "AppTitle B"
END
# else
# error Compile switch not defined or unknown; cannot compile!
# endif
#endif

Related

How can I make compiler version specific ifdef?

I've got the problem that my program will compile with g++10.2 and c++11 activated through cmake. but it will not compile with arduino dues arm-none-eabi-g++.exe compiler which also has c++11. The failure occurs because of one line that needs to be added for the arm compiler, but when I add that line to g++10.2 it won't compile.
So I need an #ifdef or some alternative to activate and deactivate the line specific for the compiler.
Like Deumaudit said in the comments:
Try to use __arm__, __aarch64__ or __ARM_ARCH macro
You'll probably be ok if you use #ifdef __arm__ or even #if defined(__arm__) || defined(__aarch64__)
If you're planning to add more supported platforms to your program, it might be a good idea to define some macros when building for a specific platform. I have my own _MY_APP_ARM macro defined in my CMakeLists.txt:
if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm")
add_definitions(-D_MY_APP_ARM)
endif()
Which I can then use as #ifdef _MY_APP_ARM

Using #define with build mode

Is it possible to define something when building in debug mode?
For example:
...
#ifdef ENABLE_DEBUG
/* This line will be executed if the program is built in debug mode */
#endif
...
This is indeed possible, because it's you who defines what "debug mode" means. There is no "standard" way to do this, because there is no such thing as "standard" debug mode. You, as the author of the buildsystem, are in control of all build settings. If you decide that you will define the macro DEBUG if and only if building in debug mode, you can of course use #ifdef DEBUG in your code to distinguish between debug and non-debug builds.
The closest "standard" thing you can get is that the macro assert is specified to do its check when macro NDEBUG is not defined, and do nothing when NDEBUG is defined. For this reason, IDEs normally set up build configurations so that debug builds do not define NDEBUG and optimised builds do.

Error "token is not a valid binary operator in a preprocessor subexpression"

if I build and run a project, basically a stub generated by the Qt framework on Mac OS 10.6, I get this error output:
/Users/home/Qt5.0.1/5.0.1/clang_64/include/QtCore/qisenum.h:53: Error:token is not a valid binary operator in a preprocessor subexpression
# if __has_extension(is_enum)
~~~~~~~~~~~~~~~^
I canĀ“t find a solution to this, although I read that other Mac users seem to have the same problem. Anyone knows how to solve this?
I have found the solution. Just copy the latest qisenum.h file from here and replace it in clang_64/include/QtCore folder in your Qt creator installation, it will work fine.
This issue is resolved in this forum post.
It is basically an issue with your version of clang
# if __has_extension(is_enum)
~~~~~~~~~~~~~~~^
That's a Clang language extension called feature checking macros. They've been around a long time for Clang. GCC provided them starting at GCC 5.0, IIRC.
__has_extension can be tested as a preprocessor macro. So you test for the presence of the macro first, and then you test for the feature:
#if defined(__has_extension)
# if __has_extension(is_enum)
...
# endif
#endif
__has_extension(is_enum) must be on a separate line.
It works for include files, too. From the Crypto++ project an rdrand.cpp file:
# include <immintrin.h> // rdrand, MSC, ICC, and GCC
# if defined(__has_include)
# if __has_include(<x86intrin.h>)
# include <x86intrin.h> // rdseed for some compilers, like GCC
# endif
# endif
In my case the reason of the same error was that Preprocessor macro name in Target Build Settings contained hyphen sign '-', something like that TEST-DEBUG=1.
Xcode build configuration names with hyphens ('-') cause pods build failures
My case is:
#define USE_LIBICONV 1 # xxxxxx
Error
Token is not a valid binary operator in a preprocessor subexpression
Solution:
remove typo comments after #define
=> change # to //
#define USE_LIBICONV 1 // xxxxxx
then can use macro normally:
#if USE_LIBICONV
...
#endif

How to set predefined macros in Code::Blocks

Is there a way to set some predefined Macros for my local installation of Code::Blocks.
To elaborate on that, basically I would like to have certain blocks compiled only at pc and not anyplace I send the code to. One way to achieve this is as follows:
#define MYPC
#ifdef MYPC
//do something
#else
// do something else
#endif
I was to achieve the same thing, but I don't want to include the line #define MYPC and woud like to add this somewhere in the IDE. I know how to do this in Visual Studio, and I think it also exists in Code::Blocks as well.
Thanks.
Project - Properties - Project's build options - Compiler Settings - #defines.
Edit. Example of #defines edit box:
CONSTANT1
CONSTANT2="0"
Gives the following command line:
g++ -DCONSTANT1 -DCONSTANT2="0" ...

D_WIN32_WINNT compiler warning with Boost

Not sure what to make of this error. Added -D_WIN32_WINNT=0x0501 to Visual Studio's "Command Line" options under Project Properties but it says it doesn't recognize it and the warning still appears.
I am also not sure how to add the Preprocessor Definition.
1>Please define _WIN32_WINNT or
_WIN32_WINDOWS appropriately. For example:
1>- add -D_WIN32_WINNT=0x0501
to the compiler command line; or
1>-
add _WIN32_WINNT=0x0501 to your
project's Preprocessor Definitions.
Add following line in your top source code.
#include <SDKDDKVer.h>
I think you're really close to getting this to work. John Dibling gave three ways you could do this and it looks like you tried the third solution, which was to "go in to your project's settings ... and under the Configuration Properties->C/C++->PreProcessor heading, add ;_WIN32_WINNT = 0x0501". You replied that you were still getting that error and provided the contents of your preprocessor settings, WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT = 0x0501. I think you can solve this if you change _WIN32_WINNT = 0x0501 to _WIN32_WINNT=0x0501. When I tried the version with spaces, it did not eliminate the error, but removing the spaces did.
A few options.
1) If you have a main header file, like stdafx.h, you could add this:
#define _WIN32_WINNT 0x0501
Or you could add that anywhere you need it.
2) You can add -D _WIN32_WINNT=0x0501 (note the space)
3) Go to Project Properties > Configuration Properties > C/C++ > Proporcessor. Add ;_WIN32_WINNT=0x0501 to Preprocessor Definitions.
Personally, I choose #3 because there's no doubt about it being defined at the right time in the right translation units, and I'd rather have all the #defines in one place rather than some being in Preprocessor Defines and others in the advanced tab.
Put a space after the D
You should define the WIndow sversion you ant to target as many have suggested:
// Target Windows XP
#define _WIN32_WINNT 0x0501
The reasons you do not want to use the SDK version that happens to be installed are:
To have reproducible builds. You don't want to just pick up whatever happens to be installed as that can very for each person trying to build.
To be in control of your target platform. You don't want to target Windows 11 just because you happen to compile on Windows 11. As the programmer, you want to be in control of what is done.
To support the widest range of Windows versions. Users will be grateful that they can run your program on their older Windows version.
For Code Blocks here is how you do it.
Right click **Project Name** on your left >> Click 'Build Options' >> Select Debug or Release on your left >> Select 'Compiler Settings' Tab on the right >> Select #defines tab >> Then add the following line as it is:
_WIN32_WINNT=0x0501
>> Click Ok >> Close >> Right click **Project Name** again >> Re-build.
OP didn't ask about CMake, but google brought me here. If you're using CMake, try adding this to your (top-level) CMakeLists.txt:
if (WIN32)
add_definitions(-D_WIN32_WINNT=<myWindowsTarget>
endif()
I was interested in Windows 10, so myWindowsTarget was 0x0A00. Here's a full list of Windows Targets