Files accessed by GCC while compiling a given code - c

I came across the topic of the precompiled headers in C, so I started reading about it, in brief, the article(s) I read said that gcc will use precompiled header (h.gch) if there is one, otherwise normal header file(.h) will be used.
I just wanted to try it out and see if that actually happens with my code. So, I wanna know if there is any command in Linux(Ubuntu) to see what all files are being used by the GCC compiler while it is compiling your code. What I am thinking is, if the .h.gch file is used instead of .h files then it works how it should be and I get the concept of precompiled header files.
For example,
if I do something like
gcc myCode.c
then gcc will definitely go to that file (myCode.c) and if myCode.c file includes a header file then that header file will also be touched/opened by gcc.
https://gcc.gnu.org/onlinedocs/gcc-5.1.0/gcc/Precompiled-Headers.html
This is from where I read about precompiled headers.

If you simply want to see what files are opened by gcc or any other process on Linux then you can use Strace.
strace -f -e open gcc myCode.c

Related

How do I use an external library with gcc?

I am attempting to compile this code:
#include <GLFW/glfw3.h>
int main() {
glfwInit();
glfwTerminate();
return 0;
}
Using this command in MSYS2 on Windows 10:
gcc -Wall runVulkan.c -o runVulkan
as well as this:
gcc -Wall -Llibs/glfw runVulkan.c -o runVulkan
libs/glfw is where I downloaded the library to.
For some reason I keep getting this:
runVulkan.c:1:10: fatal error: GLFW/glfw3.h: No such file or directory
1 | #include <GLFW/glfw3.h>
| ^~~~~~~~~~~~~~
compilation terminated.
It seems like I'm getting something very basic wrong.
I'm just getting started with C, I'm trying to import Vulkan libraries.
Run pacman -S mingw-w64-x86_64-glfw to install GLFW.
Then build using gcc -Wall runVulkan.c -o runVulkan runVulkan.c `pkg-config --cflags --libs glfw3`.
The pkg-config command prints the flags necessary to use GLFW, and the ` backticks pass its output to GCC as flags. You can run it separately and manually pass any printed flags to GCC.
Note that any -l... flags (those are included in pkg-config output) must be specified after .c or .o files, otherwise they'll have no effect.
For me pkg-config prints -I/mingw64/include -L/mingw64/lib -lglfw3.
-I fixes No such file or directory. It specifies a directory where the compiler will look for #included headers. Though it's unnecessrary when installing GLFW via pacman, since /mingw64/include is always searched by default.
-l fixes undefined reference errors, which you'd get after fixing the previous error. -lglfw3 needs a file called libglfw3.a or libglfw3.dll.a (or some other variants).
-L specifies a directory where -l should search for the .a files, though it's unnecessrary when installing GLFW via pacman, since /mingw64/lib is always searched by default.
#include are just headers, for declarations. gcc, as any compilers, needs to know where those .h should be searched.
You can specify that with -I option (or C_INCLUDE_PATH environment variable).
You'll also need -L option, this times to provide the library itself (.h does not contain the library. Just declarations that the compiler needs to know how to compile codes that use the library function's and types).
-L option tells the compiler where to search for libraries.
But here, you haven't specify any libraries (just headers. And I know that it seems logical that they go together. But strictly speaking, there is no way to guess from #include <GLFW/glfw3.h> which library that file contain headers for (that is not just theory. In practice, for example, the well known libc declarations are in many different headers)
So, you will also have to specify a -l option. In your case -lglfw.
This seems over complicated, because in your case you compile and like in a single command (goes from .c to executable directly). But that are two different operations done in one command.
Creation of an executable from .c code source is done in two stage.
Compilation itself. Creating .o from .c (many .c for big codes), so many compilation commands. Using command such as
gcc -I /path/where/to/find/headers -c mycode.c -o mycode.o
Those are not related to the library. So no -l (and therefore no -L) for that. What is compiled is your code, so just your code is needed at this stage. Plus the header files, because your code refers to unknown function and types, and the compiler needs to know, not their code, but at least declarations that they really exist, and what are the types expected and returned by the functions is the headers files.
Then, once all the .o are compiled, you need to put together all compiled code, yours (the .o) and the libraries (which are somehow a sort of .zip of .o) to create an executable. That is called linking. And is done with commands like
gcc -o myexec mycode1.o mycode2.o -L /path/where/to/search/for/libraries -lrary
(-lbla is a compact way to include /path/where/to/search/for/libraries/libbla.so or /path/where/to/search/for/libraries/libbla.a)
At this stage, you no longer need -I or anything related to headers. The code is already compiled, headers has no role left. But you need everything needed to find the compile code of the libraries.
So, tl;dr
At compilation stage (the stage that raises the error you have for now), you need -I option so that the compiler knows where to find GLFW/glfw3.h
But that alone wont avoid you the next error that will occur at linking stage. At this stage, you need -lglfw to specify that you want to use that library, and a -L option so that the compiler knows where to find a libglfw.so

How to use functions in a package that is written in C in a different location

I am trying to use a linear algebra package called hnfprof. I have done the installation with the given instructions and now its ready to use. Now I want to use some functions in hnfproj/src/lift/lift.c file. I want to create my own matrix examples and check outputs for each functions separately. I am not clear how to do this. (I know only basics of C language, creating .c files in a folder and running it in my Ubuntu terminal.)
I know that I should write a C file including this "#include <lift.c>" file name and creating a matrix in my file "main.c". I don't know how to include a file name in a different location. When I compile I can not use "gcc -o program main.c lift.c". My "main.c" file is in a different folder. I don't want to create any make file inside the package folder. So how I can just use the "lift.c" file inside my "main.c" file which is in a separate folder "Main" and create all executable make files inside "Main" folder?
If its difficult to give a answer, appreciate if you can suggest me some source to learn this. Thank you
No need to include lift.c directly in main.c, and you can call function in lift.c from main.
When it comes to compilation, you can use:
gcc -o program main.c file_location/lift.c
If you need other options, add them (most flags at the start; libraries at the end, after the source code). You can also compile each file to object code separately and then link the object files together:
gcc -c main.c
gcc -c file_location/lift.c
gcc -o program main.o lift.o
refer
Compiling multiple C files with gcc

How to use shared object file in c compilation

I'm trying to use this C library using gcc Apple LLVM version 8.0.0 (clang-800.0.42.1) on macOS Sierra. I've done the following steps:
make libquirc.so
Copied libquirc.so into my project directory
gcc -o quirc_test quirc_test.c -L. -l libquirc.so.1.0
It produces the error:
quirc_test.c:1:10: fatal error: 'quirc.h' file not found
#include <quirc.h>
^
1 error generated.
quirc_test.c
#include <quirc.h>
This is the first time I've tried to do anything in C and other related questions about compiling with the link flag didn't seem to help as seen above.
C is somewhat primitive. Shared object libraries do not contain the declaration of the API they implement - at least not in enough detail or a form that the compiler can understand.
You'll need the header file quirc.h somewhere you can find it. You could just copy it into the current directory just like the library, but you'll need a minor adjustment to the include statement.
#include "quirc.h"
If the included file is surrounded by double quotes instead of angle brackets, it will first look in the source code directory instead of the system header directories.
An alternative is to install the library somewhere e.g. /usr/local. Your library would go in /usr/local/lib nd your header in /usr/local/include. If you do that, use the -I directive on the compiler command line to tell the compiler where to look for the header e.g.
cc -I/usr/local/include -L/usr/local/lib -lquirc quirc_test.c

How to divide C code in different files

I'm doing a code in C right now and the problem is that it's quite large. I've been doing some research about how to separate this code and the solution more attracting is to try and put some generic functions in a header file instead of putting them at the beginning of my .c code.
The problem comes when I read about this header files and I see that they are used to define MACROS. I started reading about it and what I see is strange definitions for me of variables (I mean strange because I normally don't define that kind of variables in a .c file).
Any thoughts on how to do this before I get my hands dirty?
As long as I understand your problem, you are trying to make an header file for your project, am I right? If this is the case, perhaps you are referring to #ifndef, #endif etc. etc. These are commands that will be executed by the preprocessor. You should give it a read. When you have finished your header save it in .h extension. Furthermore, when including your header, this has to be in the same folder of the .c file and you have to include it like that :
#include "myHeader.h"
In the header you just have to write down the prototype for your function. Then create a .c file myHeader.c and do the actual function. Remember to include you header in both of your .c files.
To compile it use the following :
gcc -c myFile.c -o myFile.o
gcc -c myHeader.c -o myHeader.o
Then you have to link the objects and you are done :
gcc myFile.o myHeader.o -o filename

Check what files is 'make' including

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

Resources