views:

131

answers:

4

Is it possible to add a #define _MYDEFINE_ in my header file based on some options in the project settings. For Ex: Suppose in my exposed header file (which is delivered along with the library) I have some macros like shown below:

#ifdef _MYDEFINE_
#define ABC 2
#else
#define ABC 4
#endif

Now, while building my library, I can add _MYDEFINE_ in my settings, but I don't want the user of the library to add _MYDEFINE_ in his project settings or code. Instead I want "#define _MYDEFINE_" to automatically get added in the beginning of the header.

Note: #define _MYDEFINE_ should get added only when it is defined in my preprocessor settings. For other settings it should not get added.

If not possible through project settings, are there any innovative ways of getting it done? Any ideas are welcome.

+3  A: 

Most C compilers accept the option -D to define a symbol:

gcc -D_MYDEFINE_ file.c

In that form, it is implicitly set to one. Otherwise one can explicitly set a value:

gcc -D_MYDEFINE_=4 file.c

Multiple -D are allowed, even on operating systems which make that difficult (such as VMS).

gcc -DSYMBOL1 -DSYMBOL2 -DSYMBOL3 file.c

These behave as though corresponding #define statements appeared before the first line of each command line file.

#define SYMBOL1 1  (these are virtually present due to command line -D options)
#define SYMBOL2 1
#define SYMBOL3 1

(actual source code begins)
/*
 * file.c:  
 */
#include <ctype.h>
#include <stdlib.h>
 ...
wallyk
A: 

You seem to be looking for the "/D" compiler flag (one of a few that's identical in nearly every C compiler on the planet). Usage would be something like: cc /D_MYDEFINE_ myfile.c

As an unrelated aside, note that a name like _MYDEFINE_ that starts with an underscore followed by another underscore or a capital letter is reserved for the implementation -- i.e. you're not supposed to use such a thing.

Jerry Coffin
I just added _MYDEFINE_ as an example. I really don't name my constants that way. But, does /D add the define to your exposed header file? I am talking from the perspective of a library with exposed header files which will be used by some application.
Jay
@Jay:No, the "/D" would typically be in the makefile, not any of the source files. So basically, you'd add it to your makefile for when you build the library.
Jerry Coffin
+1  A: 

You might need to consider what effect _MYDEFINE_ has on your library.

If it you want its effects only for development (like NDEBUG), using the -D or /D compiler option should be fine.

If it has an effect which is going to affect what happens when your users use the library, you may need to do something more elaborate. In the latter case, you will be creating two versions of your library, and you may want to name them such: as in libX-ABC2.a and libX-ABC4.a. And you will need two versions of your include files too, and you may need to generate configuration headers with _MYDEFINE_ defined appropriately in each. If your library is installed, you may need versioned include directories for the header files.

If, for example, _MY_DEFINE_ affects the layout of declared structures or the size of a declared array in other headers, having users include header for #define ABC 4 with the library which assumes #define ABC 2, you will be introducing some nasty bugs for your users to track down.

I've seen this before. Taking care of this is difficult and tedious, but not doing it can create serious problems with different versions of you library.

Tim Schaeffer
+1  A: 

Have a build configuration header file and include this header file before you include any other header file. This build configuration header file can be created by using some scripting mechanism during build time.

Andy