3
votes

I need to be override certain macro definition by my header file. And I am not allowed to change source code. And I have to use gcc, but if anyone is aware of something similar on any other compiler then also it will help.

Here is what I exactly need:

Lets say I have code base with lot of .c files. These .c files include .h files. After all the .h files have been included for each file I want the compiler to behave as if I have another extra.h file which I want to specify when invoking the compiler. What I do in that .h file is #undef some macro and re-define the macro the way I want them to be.

Note: I am aware of --preinclude option in gcc, but using --preinclude over-rides my extra.h by the .h of the original source code. What I need is some kind of post include option.

5
I donot know why one line became big font and bold. I apologize if you find that annoying. - Saurabh
Why can't you change the source code? Is this related to a homework assignment? - Adam Rosenfield
No, this is not my homework. I need to wrap certain macro calls and gather and do some pre and post processing. The reason I cannot change the source code is that customers would want to have their code touched. - Saurabh

5 Answers

3
votes

Unless you uniformly have one specific header that is always included last in the source files, this is going to be tricky.

I think the way I'd approach it, if I had to, would be:

  • Create a new directory, call it headers.
  • Put in there suitable dummy headers with the same name as the regular headers, which would contain #include "extra.h" at the end (or possibly #include <extra.h>, but I would try to avoid that).
  • The dummy headers would also include the original files by some mechanism, possibly even using #include "/usr/include/header.h" but preferably some other technique - such as #include "include/header.".
  • The extra.h header would always redefine all its macros - it would not have the normal #ifndef EXTRA_H_INCLUDED / #define EXTRA_H_INCLUDED / #endif multiple inclusion guards, so that each time it is included, it would redefine the relevant macros.
  • Consequently, extra.h cannot define any types. (Or, more precisely, if it does, those must be protected against multiple definition by multiple include guards; the key point is that the macros must be defined each time the file is included - a bit like <assert.h>.)
  • Each redefined macro would be explicitly protected by #undef REDEFINED_MACRO and then #define REDEFINED_MACRO ....
  • There is no point in testing whether the macro is defined before undefining it.
  • The build process would be modified to look in the headers directory before looking anywhere else. The compiler option would be -I./headers or something similar, depending on exactly where you locate the headers directory.
  • Depending on how you have decided to locate the normal versions of the headers, you might need another -I option (such as -I/usr if you've used #include "include/header.h" notation) to locate the standard headers again.

The upshot is that your private headers get used directly by the compiler, but they include the standard headers and then your extra.h header - thus achieving what you wanted without modifying the C source or the normal headers.

But there is something misguided about the whole attempt...you would be better off not trying this.

0
votes

Makefile could be used to redefine the macros through the -U and -D compiler(gcc) options. But why redefine them after the originals are evaluated? I cannot think of a need for such a thing. Can you tell what are you hoping to achieve through this?

0
votes

The requirement is to insert extra.h after all the other .h files in a .c file. So adding it at the end of each .h file will insert it between two .h files included in sequence inside a .c file, which is not the intention.

You can use sed/awk inside makefile(s) to: - first create duplicate .c files inserting '#include "extra.h"' after other #include lines inside each of the .c files (it will be tedious/ticky to resole #ifdef blocks inside the .c files) - then achieve your target compiling those duplicate .c files - finally delete the duplicate .c files

0
votes

You can use -include file option of GCC, because of this feature:

If multiple -include options are given, the files are included in the order they appear on the command line.

So as I understand you must include ALL *.h files from the command line,- just keep your "extra.h" the last header in -include option list and you should get what you want.

0
votes

There are two ways I can think of doing this according to your requirements, and both should be relatively simple, I hope.

The first way does not touch the source code at all, however it requires that each header file you are #undef'ing things from has a header guard. You can copy and concatenate every header file that you need to "change" things in into one monolithic file, your "extra.h" file. Then at the end of that file, go ahead and redefine all the macros you need. Then include this file when you compile. The header guards will prevent the original headers from being included. Obviously, there are a number of potential problems with this approach, and it certainly wouldn't work in general.

The second way is a lot cleaner and more reliable, but it requires you to edit the code directly, albeit non-intrusively. For each header you need to redefine things in, make a copy of that header with an ".orig" suffix or something, then edit the actual header file directly. After you are all done doing whatever you are doing, then just copy all the ".orig" files back into the actual headers before your customers obtain the code. I assume your requirements aren't so draconian that you can't change the code even temporarily.

If none of that works, then I doubt you are going to find an effective answer from anybody short of hacking GCC directly and adding a "-postinclude" option yourself.