-2

I want to write a good callgraph program in python and for that reason I use pycparser. Pycparser needs to preprocess c files in order to create an abstract syntax tree correctly. My first approach was to use only the -E option of gcc on the files and then pass it to pycparser. But with different projects I get "No such file or directory" errors because gcc doesn't find the specific headers. If I try to preprocess the linux kernel with gcc -E `find | grep "\.c"\` it misses some header files like those with a Linux/ prefix as there is no such folder. It seems to me that I need some additional flags for gcc to pass the location of the header files and preprocess correctly. Is there a general way to preprocess arbitrary C projects?

Additionally I guess if I get it to preprocess correctly there are multiple copies of the same function in different files. Is there a way to determine the original file of a function?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Mr. Moon
  • 9
  • 1
  • There is no single correct way to find headers for all source code. Different programs need different sets of directories specified via `-I /path/to/headers` options on the preprocessor command line. – Jonathan Leffler Nov 19 '16 at 16:59

1 Answers1

1

You need to read about how GCC finds header files, at least including compiler command line switches and environment variables for search paths.

I suspect the build scripts for various project set configuration variables that affect how GCC finds the header files for any specific compilation. Many such scripts even do macro substitution on command lines, meaning you have to know what the script is doing.

If you isolate the C source file from the make script that sets up its build context, GCC won't find the right headers. And that's your problem.

You probably need to run the build scripts, and intercept the calls to GCC to capture the necessary context.

Ira Baxter
  • 93,541
  • 22
  • 172
  • 341
  • thanks. Sounds complicated. Maybe I try to write this program only for the linux kernel. Can someone help me with a gcc command to preprocess it. gcc -E -nostdinc -I ./include -I ./arch/x86/include/ `find | grep "\.c"` doesn't seem to work :( – Mr. Moon Nov 19 '16 at 16:45
  • @Mr.Moon What makes you think the Linux kernal is substantially easier with respect to this problem? – Ira Baxter Nov 19 '16 at 17:21
  • My Intention to write this callgraph program was the linux kernel. I only wanted to have it generic so other people can use it for other c programs. If I can preprocess the kernel and write this program only destined for the kernel it would suffice to me. – Mr. Moon Nov 19 '16 at 18:07
  • @Mr Moon: You didn't answer the question I asked. The kernal is LOTS of compilation units. Why do you believe these are somehow easier to (pre)process than other C programs? – Ira Baxter Nov 19 '16 at 19:08
  • I don't believe that it's easier to preprocess than other C programs but I think it's easier than generically preprocessing arbitrary C programs. – Mr. Moon Nov 19 '16 at 19:58
  • @Mr.Moon: If you were talking about 10 files, I might believe you. Sometimes it is easier to solve the general case than it is to try to make a special hack. Good luck with this. – Ira Baxter Nov 19 '16 at 20:22