I have a C file with some #include instructions of header files. I know that when I compile the C file with gcc, the compiler looks for the .h files in the paths contained in the environment variable $CPATH. How can I get the absolute path of a specific .h file? (I prefer to get the path without compilation)
If you compile with -E you will get the preprocessor output and within that all of the included files will have their full paths. eg in the following, the file 'file' will contain the preprocessed output:
gcc -E -o file file.c
This is a bit of a hack:
cpp -MD file.c | sed -n '/\.h"/s/.*"\(.*\)".*/\1/p' | sort -u
and clearly depends on the output format of cpp. (The above works for gnu cpp 3.4.6)
This gives the full paths of all included files. Fun it through another filter to reduce the output to the specific header you care about.
Related
I have made a python "compiler" that helps me compile my C code with gcc, for example it fetches all my header files and source files. So my cmd commmand is gcc {headers} {source} -o {build_dir}/build.exe -lgdi32 -w where {headers} is a string like -Ipath/to/headers/foo.h -Ipath/to/other/headers.foo2.h and where {source} is the same but with .c files. It seems that the compiler finds the header files, but when compiling my code it fails.
(btw I am trying to make a portable programming environment on my flash drive so python and mingw are both portable)
This is the error: fatal error: test.h: No such file or directory #include "test.h"
My project tree
I have put the third party library files into the mingw directory instead of making a custom one and then linking it in the gcc command.
The -I option takes the path to the directory containing the header files or more specifically with an argument -Ipath and a directive #include<a/b.h>, the compiler will try to look for the header file at path/a/b.h.
So you should not give it paths to header files, only to the directory or directories relative to which you use include directives.
I want the preprocessed output of a .c file, but I also want to include a header file without the macro "include..." in the .c file. Usually, you add the -I option for including a directory where headers are.
But if I want to combine -I and -E, gcc does't seem to include my header files in the specified directory.
My command:
gcc -E -I/externDefines myFirmware.c > myFirmware.preprocessed
Does anyone know what the problem could be?
-I does not mean “Include the header files from the given directory in the compilation.” It means “When searching for a file requested with #include, look for the file in the given directory.”
GCC has a command-line switch, -include file that will include a file in the compilation. However, it includes a single file, so you must list each file you want included; it will not automatically include all header files in a single directory. The command-line shell you are using may have features that help generate a list of -include switches with the file names.
A portable way to include a header file X.h while compiling Y.c without changing Y.c would be to create an auxiliary file containing:
#include "X.h"
#include "Y.c"
and then compile that instead of Y.c.
I'm compiling a kernel module and I'm including <asm/unistd.h>, but I'm not sure if the compiler is using the unistd.h from /usr/includes/ (wrong) or the one from /usr/src/kernel-3.x.x/arch/x86/includes/ (right).
My question is: How can I check which one of those two is the compiler using?
And also, is there a way to force the file from the kernel headers instead of the one from /usr/include?
cpp code.c | grep unistd.h
or
gcc -E code.c | grep unistd.h
To answer the second part of your question:
And also, is there a way to force the file from the kernel headers instead of the one from /usr/include?
You can pass the -nostdinc option to gcc:
"Do not search the standard system directories for header files. Only the directories you have specified with -I options (and the directory of the current file, if appropriate) are searched."
GCC: Options Controlling the Preprocessor
Is it possible to look at a c/c++ file before preprocessing? Or rather after just a half-hearted pre-processing? Basically there is a
#define <commonly_used_word> 0
in a third party library header and I want to figure out where it is. So basically, I just want the compiler to include all the headers but not the the preprocessor as such.
Your original source file is file before preprocessing.
It sounds like you want your #include directives processed, yet you want to keep macros non-substituted. Both actions are carried out by the preprocessor.
In general case it is impossible, since in C and C++ it is legal to use macros as include file names, as in
#define INCLUDE_FILE "stdio.h"
#include INCLUDE_FILE
Achieving what you want would require a preprocessor specifically designed to satisfy your request. I, for one, don't know of any such preprocessor implementation.
If you want to find where a specific macro is defined, you might try the following trick: define your own macro with the same name before including any headers, and start compilation. The compiler (the preprocessor) should complain about macro redefinition when it encounters the library definition of the same macro and point out its location to you.
There are GCC-specific -M and -MM options:
To list absolute paths of include files, use -M
Instead of outputting the result of preprocessing, output a rule
suitable for make describing the dependencies of the main source file.
The preprocessor outputs one make rule containing the object file name
for that source file, a colon, and the names of all the included
files, including those coming from -include or -imacros command line
options. gcc -M test.c
If you dont want the system includes like
#include <stdio.h>,
then use -MM Like -M but do not mention header files that are found in
system header directories, nor header files that are included,
directly or indirectly, from such a header. gcc -MM test.c
That could significantly narrow down the search area.
http://www.math-linux.com/spip.php?article263
You can tell cpp to generate the list of included files using -M option:
$ cpp -M a.c
a.o: a.c /usr/include/stdio.h /usr/include/features.h \
/usr/include/sys/cdefs.h /usr/include/bits/wordsize.h \
/usr/include/gnu/stubs.h /usr/include/gnu/stubs-64.h \
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.1/include/stddef.h \
/usr/include/bits/types.h /usr/include/bits/typesizes.h \
/usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.1/include/stdarg.h \
/usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h
It gives you a Makefile rule format but you could ignore that and use with any other command.
For example, you can grep for the symbol (here I'm ignoring stderr because of \ and a.o: not being a real file names -- laziness):
$ grep '#\s*define\s*BUFSIZ' $(cpp -M a.c) 2>/dev/null
/usr/include/stdio.h:# define BUFSIZ _IO_BUFSIZ
You can also use a program like ctags to find the symbol for you:
$ ctags $(cpp -M a.c)
...
$ grep BUFSIZ tags
BUFSIZ /usr/include/stdio.h 128;" d
If you know which header files contain the definition you're looking for, e.g by using find and grep as suggested, you may be able to pinpoint which one is affecting the current source file by getting gcc to print the header inclusion tree. As described in gcc's documentation, you can achieve this by using the -H option, possibly combined with -MG to eliminate normal processing.
I would like to know how to generate assembler code from a C program using Unix.
I tried the gcc: gcc -c file.c
I also used firstly cpp and then try as but I'm getting errors.
I'm trying to build an assembler program from 3 different programs
prog1.c prog2.c prog.h
Is it correct to do gcc -S prog1.c prog2.c prog.h?
Seems that is not correct. I don't know if I have to generate the assembler from each of them and then link them
Thanks
According the manual:
`-S'
Stop after the stage of compilation proper; do not assemble. The
output is in the form of an assembler code file for each
non-assembler input file specified.
By default, the assembler file name for a source file is made by
replacing the suffix `.c', `.i', etc., with `.s'.
Input files that don't require compilation are ignored.
so try gcc -S file.c.
From man gcc:
-S Stop after the stage of compilation proper; do not
assemble. The output is an assembler code file for
each non-assembler input file specified.
By default, GCC makes the assembler file name for a
source file by replacing the suffix `.c', `.i',
etc., with `.s'. Use -o to select another name.
GCC ignores any input files that don't require com-
pilation.
If you're using gcc (as it seems) it's gcc -S.
Don't forget to specify the include paths with -I if needed.
gcc -I ../my_includes -S my_file.c
and you'll get my_file.s with the Assembler instructions.
objdump -d also works very nicely, and will give you the assembly listing for the whole binary (exe or shared lib).
This can be a lot clearer than using the compiler generated asm since calls to functions within the same source file can show up not yet resolved to their final locations.
Build your code with -g and you can also add --line and/or --source to the objdump flags.