Reputation: 6707
Say I use some C or C++ library, made out of headers and some source files, that are compiled into a static or shared library I can link with.
In the headers of the library (dozens... or hundreds of files), some macros/symbols are defined.
Now I want to use this library in a project, that also defines some macros and symbols. Of course, I want to avoid name collisions, as this has been reported sometimes, particularly with windows.h. But more generally I want to keep control of what is really exported out of that header.
I can produce a list of defined symbols with gcc preprocessor options:
gcc -E -dM include/great_lib.h | sort -V >symbols.txt
This outputs in file symbols.txt a sorted list of all the defined symbols included in a user file when it includes this header.
However, it only gives the symbol, not the file where it was defined.
I have the feeling that this could be a useful information. For example, to check if some system macro is being redefined in "great_lib.h" or its ascendants. Unfortunalty, after checking gcc preprocessor options, I don't see a way to do that using gcc.
For example, instead of only giving me:
#define M_PI 3.14159265358979323846
it would produce
#define M_PI 3.14159265358979323846; /usr/include/math.h
Maybe something with the -dN option ? But its output is confusing for me, it requires further text processing, and I don't understand how the information is layered. Or a simpler way ?
Related questions:
Upvotes: 15
Views: 5750
Reputation: 72639
Don't reinvent the wheel, clumsily. All that gcc -dM stuff gives you a square wheel :-)
Any ctags
(for vi) or etags
(for emacs) program will extract that information (which identifier is defined/declared in which file). As a bonus, you'll have it in a form that is directly understood by editors, allowing you to place the cursor on an identifier and then jump to its declaration/definition.
Use the tools in the toolbox, use the Unix philosophy of having one tool do one thing well.
Upvotes: 1
Reputation: 17114
The -dD option outputs the preprocessed source along with the macros. This includes lines that indicate the current source file, e.g.
# 1 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.5.2/../../../../include/_mingw.h" 1 3
You can write a little program that (i) keeps track of the current source file by parsing these lines; (ii) outputs all lines that start with #define
(and \t# define
etc.), followed by the current source filename; (iii) discards all other lines (the source code, declarations etc.).
Upvotes: 2
Reputation: 9336
A quick unix way to do it:
find "$PATH_TO_LIB" -name "*.h" | xargs grep "^[ \t]*#[ \t]*define"
You could then use sed and sort to clean up the formatting a bit.
Also, according to the gcc manual, gcc will warn you about this sort of thing.
http://gcc.gnu.org/onlinedocs/cpp/Undefining-and-Redefining-Macros.html
If a macro is redefined with a definition that is not effectively the same as the old one, the preprocessor issues a warning and changes the macro to use the new definition. If the new definition is effectively the same, the redefinition is silently ignored. This allows, for instance, two different headers to define a common macro. The preprocessor will only complain if the definitions do not match.
Upvotes: 1