Pass macro to nmake - c++

From my earlier post, I figured out why the command
build /nmake "USER_C_FLAGS=/DMyVersion=3"
doesn't associate the define MyVersion with value 3. MSDN says that -
Compiling with /Dname= causes the symbol to not have an associated
value. So, while the symbol can still be used to conditionally compile
code, the symbol will otherwise evaluate to nothing. For example, in
the previous sample program, compiling with /DTEST= will cause a
compiler error. This behavior is similar to using #define with or
without a value.
I have an environment variable that gets set up at run-time and I need to pass that env. variable to the Visual Studio 2005 Makefile Project. Now the question is, how can I pass the env. variable to the run-time build environment ? Once passed, I should be able to something like -
#define VERSION 11
#ifdef BUILD_VERSION // How to get this macro to the current env. ?
#undef VERSION
#define VERSION BUILD_VERSION
#endif
#define FILE_VERSION VERSION
I don't see any flags from nmake documentation to pass env. variables. Any ideas are highly appreciated.

MSDN will answer this for nmake Environment-Variable Macros.
Pay attention here: "Use the /E option to cause macros inherited from environment variables to override any macros with the same name in the makefile."

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

search for unresolved references that should have been ifdef'ed out

I hope this is an interesting question. I'm trying to find the source of an unresolved external symbol. I have debug code that uses a global file pointer if debugging is turned on. All of this debugging code is supposed to be protected by #ifdef, like:
#ifdef DO_XLL_DEBUG
fprintf(debugPointer, "hello\n);
...
#endif
When I define DO_XLL_DEBUG, all is well. If I undef DO_XLL_DEBUG, everything compiles (I do a rebuild all just in case), but it fails at the link step, not finding debugPointer.
So, the question is, is there an easy way to find where I failed to #ifdef around the debug code? I can think of several not so easy ways.
I'm using Visual Studio 2005. This is a C++ project.
Thanks!
[EDIT]
Thanks for all the suggestions. Turns out the problem was in someone else's code that is not part the corresponding project I'm working on in Linux (where I do most of my work), so no wonder I didn't find it right away.
Just define some incompatible debugPointer and let the compiler point you at all the places where it's accidentially used or redefined. Maybe like this:
#ifndef DO_XLL_DEBUG
#define debugPointer static_assert(false,"damn it!");
#endif
(given that you don't have other variables, parameters, etc. which are called debugPointer)

Python in C++: Unresolved external

I try to embed Python in my C++ application, but the linker keeps saying this error:
[ILINK32 Error] Error: Unresolved external '_PyModule_Create2TraceRefs' referenced from E:\CPP PROJECTS\ANDERLICHT\WIN32\DEBUG\ANDERLICHT.OBJ
I'm using Embarcadero C++ Builder XE2, so I converted the python33.lib with coff2omf.exe.
This is my code in main.cpp:
#include "anderlicht.c"
#pragma comment(lib, "python33_omf.lib")
// In main():
PyImport_AppendInittab("anderlicht",PyInit_anderlicht);
Py_SetProgramName(programName.w_str());
Py_Initialize();
In anderlicht.c the Python.h is included. What do I have to do to fix this error?
I had the same problem, but I found a solution that doesn't need rebuild.
If you are developing a new application, you are in debug mode: the compiler defines _DEBUG. In the file "pyconfig.h" (near line 336 for python 3.6.3) you can find:
#ifdef _DEBUG
#define Py_DEBUG
#endif
=> Remove this code.
If you leave that code,you are in Py_Debug mode, so in object.h triggers this:
#if defined(Py_DEBUG) && !defined(Py_TRACE_REFS)
#define Py_TRACE_REFS
#endif
That in modsupport.h defines this alias:
#ifdef Py_TRACE_REFS
/* When we are tracing reference counts, rename module creation functions so
modules compiled with incompatible settings will generate a
link-time error. */
#define PyModule_Create2 PyModule_Create2TraceRefs
#define PyModule_FromDefAndSpec2 PyModule_FromDefAndSpec2TraceRefs
#endif
So your compiler needs a custom version of Python.
Now enjoy your standard embedded python.
The problem is most likely that you're using different compiler flags in building your code than were used in building the Python DLL. In particular, PyModule_Create2TraceRefs is only defined if you have -DPy_TRACE_REFS (which usually passed in via EXTRA_CFLAGS in the make command on Unix; I have no idea how you do it with Embarcadero C++ Builder on Windows). Usually, this isn't defined—in particular, if you're using a DLL from a pre-build Python binary, it won't have it defined.
So, if you want to have custom flags in building your code, you need to rebuild Python itself with the same flags. Otherwise, you need to get the flags that were used to build Python, and use the same ones when building your code.
On Unix, this is trivial: Just call python3.3-config --cflags and python3.3-config --ldflags to get the flags to pass to your compile and link steps. On Windows, it's less trivial. The Building C and C++ Extensions on Windows chapter in the docs explains how to do it when you're using the same toolchain used to build Python itself (usually MSVC), and if you're using mingw with its MSVC-compat features there's documentation elsewhere on how to do that… but if you're using a different toolchain, you will need to figure some of it out yourself.

Strange compiler errors with code::blocks

I switched from Visual Studio to Code::Blocks yesterday, and just had some strange compiler error messages.
I included windows.h and i can use all the API calls just fine, such as creating window classes and creating windows / buttons and stuff. But when I tried to send some keypresses with SendInput(), I got error messages on these two declarations:
INPUT ip;
KEYBDINPUT kbi;
Compiler errors:
C:\code_blocks\test-app\main.cpp|21|error: 'INPUT' was not declared in this scope|
C:\code_blocks\test-app\main.cpp|22|error: 'KEYBDINPUT' was not declared in this scope|
I can even right click the KEYBDINPUT and INPUT structors and click on "Find declaration", it finds it inside the "winuser.h" (which is inside ), but it's still giving me these error messages that they are not declared.
This code works fine in VS with just windows.h included. I'm using the GNU GCC compiler.
I think you need the pre-processor directives (Visual Studio may already add them):
What do you have _WIN32_WINNT defined as?
Perhaps you could add:
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0400
#endif
or you can add it to your pre-processor directives as part of your compile sequence. Any good compiler will have it.
If it still doesn't work, remove the include guards and define it directly. Maybe it is getting defined elsewhere.
Some compilers will have this in the pre-processor directive settings: WIN32,_DEBUG,_CONSOLE,_MBCS,_WIN32_WINNT=0x0400
To elaborate on Changeling's answer, if you look at the documentation for say KEYBDINPUT, you will see that near the bottom it has a table of minimal supported OS versions. VC++ sets _WIN32_WINNT to a later version than MinGW/GCC (which I am guessing is the compiler you are using with Code::Blocks), which is probably why you have encountered this problem.
The purpose of this macro is to prevent you inadvertently using API's that are not compatible with your minimum intended target OS.
There are a number of version related macros used by Windows API headers. The details can be found here

Visual C++ 2010 solution-wide macros with parameters

I'm trying to compile some source code with Visual C++ 2010 Express. The code was written for GCC, and contains attributes like this:
struct something {
...
} __attribute__((packed));
Since this is not standard C++ syntax, Visual C++ doesn't recognize it. With this macro prior to the struct declaration, it works fine:
#define __attribute__(p)
But I don't want to alter the files. I created a new property sheet (GccCompat), and went to Preprocessor Definitions, and added the macro, like this:
__attribute__(p)
or like this:
__attribute__(p)=
But it doesn't work. It's simply not called. If I define just __attribute__ (without parameters) in the same location, the macro is correctly defined. Note that the command line that is generated looks fine (the macros with parameters are passed exactly the same as the ones without), but the compiler seems to ignore it. So, how can I globally define my macro with a parameter?
It might be impossible, at least that way. Notice that Microsoft's documentation of the /D option doesn't specify a syntax for macros that take arguments.
Defining macros in the IDE is generally focused on the nature of creating a /D:CPP_TOKEN flag for the compiler, i.e. #define CPP_TOKEN.
In the advanced compiler settings you may be able to define such a macro as /D:"attributes(p)=/nothing/" or something like that. Just open the VS command prompt and see what it says. GCC 4.2 will allow something like that (using it's -D switch), but I don't have MSVC10 handy.