Makefile with two .c files and no header - c

Trying to write a makefile with two .c files and no header. However, it seems examples online have shown the makefile with a header.
So i tried to write a header file and it would tell me a function is redefined somewhere else. my header consisted of declarations of functions in both my .c files.
#ifndef HEADER_H
#define HEADER_H
void calc(void parameters);
int main(int argc, char* argv[]);
struct compArray
{
int start;
int end;
int thr;
int m;
int r;
};
#endif
I'm positive that's not how you write a header but ideally I'd like to have my makefile without a header. Below is my Makefile:
all: thr_atomic.o thr_reduce.o
gcc -o make thr_atomic.o thr_reduce.o -lm -pthread
thr_atomic.o: thr_atomic.c
gcc -c thr_atomic.c
thr_reduce.o: thr_reduce.c
gcc -c thr_reduce.c
Is it possible to create a makefile without a header? My two .c files are independent of each other. If so how do I go about doing that? And if not, what would I put in my header.h to tell the computer that my variables are not being redefined and are independent from each other?

You can use the following Makefile:
all: thr_atomic thr_reduce
thr_atomic: thr_atomic.c
gcc thr_atomic.c -lm -pthread
thr_reduce: thr_reduce.c
gcc thr_reduce.c -lm -pthread <newline>
However, since it seems the two programs are totally independent, I would rather make two separate makefiles.

From what I can understand from your question, you don't need a header file in order to compile C code using a Makefile. Makefiles don't have anything to do with source code. All a Makefile does is run a command(s) if the file(s) you've specified have been updated.
# Makefile
outfile: infile1 infile2
command1
command2
# ^ commands MUST begin with a tab
If you run make outfile, this is what happens:
If outfile does not exist, then make runs command1, and then runs command2.
If outfile exists, but infile1 and infile2 have not been updated since then, make will do nothing.
If outfile exists and infile1 or infile2 have been updated since outfile was last modified, then make will run command1 and then run command2.
That's the basics of make and Makefiles. The files (outfile, infile1, infile2 etc.) and the commands (command1, command2) can be anything you like. There can also be any number of them present.
When it comes to compiling code, make is pretty useful because you can use it to recompile a binary file (also called an executable file) if the source files are changed, which is exactly what you want.
For example, this makefile creates a binary file (executable file) from two source files (and no header files):
# Makefile
# executable file is called "prog"
prog: a.o b.o
gcc -o prog a.o b.o
# ^^^^^^^
# tell gcc to name the output file "prog"
# compile the first source file "a.c" to produce the object file "a.o"
a.o: a.c
gcc -c a.c
# compile the second source file "b.c" to produce the object file "b.o"
b.o: b.c
gcc -c b.c
If you do have header files, then you would need to change the compilation lines to this:
# Makefile
# ...
# compile a.c, which has an associated header file a.h
a.o: a.c a.h
# ^^^ add the header file here
gcc -c a.c
If you are not clear about what header files are, then look them up somewhere or ask another question about them.

Related

How to use gcc correctly from the ubuntu terminal?

I'm try to compile a .c file from the terminal using gcc. The file includes a personal library where a function is defined. This library.h and the .c file are in the same directory.
I get the following message error
undefined reference to `function'"
Should I use another argument as:
gcc -o nameoutput filename
or should I place the library.h in another directory?
Assuming you have library.c, library.h and main.c in your current working directory:
$ gcc -Wall main.c library.c -o my_program
and then to run it:
$ ./my_program
"Undefined reference" means that the linker can't find the object file containing the compiled body of function; it doesn't have anything to do with the .h file.
I sounds like you have a situation where library.h and library.c are in one directory, and main.c is in a different directory. If that's the case, then your command line will need to look something like this:
gcc -o program -I /path/to/library main.c /path/to/library/library.c
-I /path/to/library means that gcc will look for .h files in that path as well as the standard include paths. That also allows you to write
#include "library.h"
instead of
#include "/path/to/library/library.h"
in any code that needs it.

In C how do I compile and then create an executable file with a header and two c files?

I have three C files in total. One is a header [.h] file, two are source [.c] files.
The .h file is called encryption.h and the corresponding source file is encryption.c. The encryption.c has logic, but no main() function. My second c file is called main.c. There I have the main() function that calls methods from encryption.c.
I am compiling these files within terminal on Mac OSx. I am confused on how to compile this, I have tried the following:
gcc -c main.c
gcc -c encryption.c
gcc -c encryption.h
gcc main.o encryption.o encryption.g.gch -o encrypt
This doesn't seem to work though, it says I have a precompiled-header already. I tried finding the answer online, I know it has to be simple, but I haven't had much luck. What is the issue here?
Don't compile the header file. Header files are meant to be included to the source files (using #include directive, in c). Just compile the source files and link them together. Something like
gcc -c main.c
gcc -c encryption.c
gcc main.o encryption.o -o encrypt
or, for shorthand,
gcc main.c encryption.c -o encrypt
Note: If you're bothered about the presence (or absence) of header files while compilation, check the pre-processed output of each source files using gcc -E option.

C include error multiple definition error

I'm encountering a classic error but still don't get why it occurs...
Below is the simplified explanation
Apparently I have two C files main.c and support.c
in support.c i have one function void bla(int input);
in main.c i have several functions using bla from support.c, and i included
#include<support.c>
at the top of main.c
However I cannot compile the project because of the error multiple definition of bla, first defined here (eclipse points to the definition of bla in support.c)
I know that optimally I would have to create header file support.h and gives prototype extern void bla(int input) there, but for this I have to include the .c file.
Thanks in advance.
The preprocessor will copy the contents of support.c, and paste it to main.c to replace the line #include<support.c>. So there are two definition of the function bla, one in support.c, the other in main.c.
The solution is, don't include an source file. Put the declarations of functions that you want to export in a header file support.h, and include the header file in main.c:
#include "support.h"
You don't include source files into other source files. Instead you make a header file (with the extension .h) that contains declarations of functions, i.e. function prototypes. Then you build both source files separately, and link them together to form the final executable.
So a header file support.h like
#ifndef SUPPORT_H
#define SUPPORT_H
void blah(void);
#endif
(The preprocessor #ifdef/#define/#endif things are for include guards, to protect from multiple inclusion in the same source file.)
Then the support.c source file
#include "support.h"
void blah(void)
{
/* Some code here... */
}
And finally the main.c source file
#include "support.h"
int main(void)
{
blah();
return 0;
}
If you have an IDE (like Visual Studio) if you add these files to your project the IDE will make sure everything is built and linked properly. If you're compiling on the command line, compile each source file into an object file (usually using an option like -c (used for GCC and clang)) and then link the two object files together to create the executable.
Command line example with GCC:
$ gcc -Wall -c main.c -o main.o
$ gcc -Wall -c support.c -o support.o
$ gcc main.o support.o -o my_program
The above three commands will first compile the source files into object files, and then link them together.
What compiler are you using?
When compiling, make sure you do this:
gcc main.c support.c -o yourProgram

How to link multiple implementation files in C

I have a number of .c files, i.e. the implementation files say
main.c
A.c
B.c
Where functions from any of the files can call any function from a different files. My question being, do I need a .h i.e. header file for each of A and B's implementation where each header file has the definition of ALL the functions in A or B.
Also, main.c will have both A.h and B.h #included in it?
If someone can finally make it clear, also, how do I later compile and run the multiple files in the terminal.
Thanks.
Header contents
The header A.h for A.c should only contain the information that is necessary for external code that uses the facilities defined in A.c. It should not declare static functions; it should not declare static variables; it should not declare internal types (types used only in A.c). It should ensure that a file can use just #include "A.h" and then make full use of the facilities published by A.c. It should be self-contained, idempotent (so you can include it twice without any compilation errors) and minimal. You can simply check that the header is self-contained by writing #include "A.h" as the first #include line in A.c; you can check that it is idempotent by including it twice (but that's better done as a separate test). If it doesn't compile, it is not self-contained. Similarly for B.h and B.c.
For more information on headers and standards, see 'Should I use #include in headers?', which references a NASA coding standard, and 'Linking against a static library', which includes a script chkhdr that I use for testing self-containment and idempotency.
Linking
Note that main.o depends on main.c, A.h and B.h, but main.c itself does not depend on the headers.
When it comes to compilation, you can use:
gcc -o program main.c A.c B.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 A.c
gcc -c B.c
gcc -o program main.o A.o B.o
You must provide an header file just if what is declared in a .c file is required in another .c file.
Generally speaking you can have a header file for every source file in which you export all the functions declared or extern symbols.
In practice you won't alway need to export every function or every variable, just the one that are required by another source file, and you will need to include it just in the required file (and in the source paired with the specific header file).
When trying to understand how it works just think about the fact that every source file is compiled on its own, so if it's going to use something that is not declared directly in its source file, then it must be declared through an header file. In this way the compiler can know that everything exists and it is correctly typed.
It would depend on the compiler, but assuming you are using gcc, you could use something like this:
gcc -Wall main.c A.c B.c -o myoutput
Look at http://www.network-theory.co.uk/docs/gccintro/gccintro_11.html (first google answer) for more details. You could compile it into multiple object files/ libraries:
gcc -c main.c
gcc -c A.c
gcc -c B.c
gcc -o mybin main.o A.o B.o
You want to use
gcc -g *.c -lm
It saves typing and will allow you to link all your c files in your project.

C header files and dynamic linking error

I have created a dynamically linked library. The only problem I have is that my main program does not recognize my header file. The header file is in a separate folder from my main program. I have tried #include "myheader.h" as well as #include "/folder/dir/myheader.h"
Here is what my .h consist of
extern int afunction(int,int);
extern int afunction(int,int);
So far this code works
gcc -fPIC -c filename1.c
gcc -fPIC -c filename2.c
gcc -shared -o libMylib.so filename1.o filename2.o
I then copy the lib to /usr/local/lib, and then
gcc main.c -L. -lMylib -o exeName -ldl
and I get
" myheader.h : no such file or directory.
Here is my directory structure:
directory1 ----------------folder1(main program.c)
directory1 ----------------folder2(myheader.h, along with functions for the pgm)
A push in the right direction would help, as I have written all my code and I am just at the last phase.
You need gcc ... -I<some directory to myheader.h>. That will enable the compiler to find the header file.
You can put your lib header files in the same folder with your current program.
or like #Ed Heal said.. adding -I<path> for include header folder.

Resources