yes, we have learned standard compilation phases since childhood. Still when $gcc hello.c (hmm.. considering linux platform) produces executable, some questions may confuse you. for e.g. standard questions asked to a newbie is 'what is there in stdio.h?'. Now a dumb one would say definition of functions like printf() which is wrong!! but a smart guy will tell that it contains 'declarations' not 'definitions'! Correct.. but then.. where are the definitions? If I go and call a function func() in my code which is 'declared' in hello.h that I have included, it still gives error.. it can not find the definiton. then what about printf?
The answer is - there are some predefined libraries that are linked and predefined path/s that are searched for header files and libraries by gcc. The function definitions are found at such places. By default gcc searches for header files at:
/usr/local/include/
/usr/include/
And for libraries at:
/usr/local/lib/
/usr/lib/
The standard c library is called 'libc.a'. On a unix system, it is usually located at '/usr/lib/libc.a'. the '.a' is archive file that can be created using a utility 'ar' (haven't heard? try cross-compilation once and you will get to know it). This can also be suppressed using '-nodefaultlibs' switch to gcc.
Well, that clarifies standard header files, standard functions and pre-included libraries. But things start to get more and more complicated when you move from 'all code and headers in single file' to 'all code and headers in multiple files in same directory' to ' code and headers scattered in multiple files across multiple directories'. First you get 'file not found' then 'no declaration' then 'no definition' and finally 'multiple definitions!!!!' errors!!
For successful compilation, GCC needs
1. to find all the files mentioned as arguments.
2. to find all the header files that you have included.
3. to find all the function declarations of functions that you have used ONLY ONCE*
4. to find all the function definitions of function that you have used ONLY ONCE*
5. to find all the libraries needed (yeah.. would be covered in above points.. still)
How do we achieve this?
1. to find header files: '-I' option is used to provide additional search path for headers. Hence if you have header files stored at '/x/y/z' then you can mention 'gcc -I/x/y/z ...' (The '...' here doesn't have any special meaning.. just a place holder) to make gcc look in '/x/y/z' for searching needed header files.
2. to find source files: well, as far as I know, by default only current directory is searched for '.c' files. Hence if you have source file src2.c in '/a/b/c/src2.c' then you have to use complete path e.g. 'gcc -I/x/y/z /a/b/c/src2.c ...' for compilation. (I donno if a gcc switch is available or not for searching c files)
3. to find libraries: First you have to link those libraries with '-l' option. for e.g. if your library name is 'libpqr.a' (I think its a convention to name a library file as 'libYOURNAME.a'.. donno for sure), then use -lpqr to link it. e.g. 'gcc -I/x/y/z /a/b/c/src2.c -lpqr...'. And for search path - if they are located in /l/m/n/libpqr.a' then use '-L' switch to specify this path - 'gcc -I/x/y/z /a/b/c/src2.c -L/l/m/n -lpqr ...'
4. For multiple declarations (very imp - gave a lot of pain to my bottom few years ago): use #ifndef, #define, #endif in your header file. e.g. if you have a file 'header1.h' and if you have included it in 'src1.c' and 'src2.c' then it will give redeclaration error if above 3 are not used.
Hence, in your header file, use:
#ifndef _HEADER1_
#define _HEADER1_
//your declarations
#endif
to avoid redeclaration error.
5. To find all function definitions: it must exist either in your source file or in included library. To find it only once .. well write it only once!!
Yup.. thats all I have to say right now!
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment