When writing a Makefile how is all: used in it - c

I am currently learning c through a few differant sources one being Learn C The Hard Way PDF and Cprogramming.com for extra credit it says to use all: in the Makefile. I'm currently using Kali Linux, vim for my editor and so far my Makefile looks like so.
CFLAGS=-Wall -g
clean: "this is on the next line with a Tab in--->"
rm -f ex1
I'm just trying to understand the syntax and were to put the all: and how to add to it. it says to add my next project ex3 to the all: and the clean in my Makefile if someone could explain this a little better I would be very appreciative as I don't want to jump ahead without understanding all the extra credit.
If you need a reference point as to were I am on the 3rd lesson of LearnCTheHardWay. I'm just starting out with C using Linux. Thank you for your time and any answers you may have.

all has no special meaning to make. Same goes for clean.
make will use the first target it sees unless you specify otherwise via the command line invocation.
Reading the documentation is absolutely recommended, especially considering the GNU make docs are pretty well written and work as part-tutorial-part-reference.

I would recommend that you just build your programs from the command line. This should be no problem until the build command becomes more than a couple of lines.
At that point you will be (1)frustrated enough and (2)knowledgeable enough about the compilation process (preprocessing, compiling, assembling, linking, stripping) to learn about makefiles.
You can browse online tutorials, browse the gnu make documentation and experiment in your makefiles.
From there on, you might want to learn about build systems, like autotools and Cmake, probably a couple of years in the future.

In make file the format is like this,
<tag>: <dependency1> <dependency2>....
$CC <dependency1> <dependency2>....
<dependency1>: <dependencya> <dependencyb>....
$CC -c <dependencya> <dependencyb>....
So basically for all: you have add dependecy as *.o files, for the *.o file the dependenc

Related

How exactly "make all" works?

So I am studying makefiles usage. Let's say I 've many functions fun_i.c where i is in [1,100]. I have wrote them all in seperate .c files in order to make faster compilation when I only change some of them. I need to create a Makefile. I was thinking something like that:
all : program
program: fun1.o fun2.o ........ fun100.o main.o
gcc -o program fun1.o fun2.o ..... fun100.o
fun1.o: fun1.c
gcc -c fun1.c
.
.
.
fun100.o: fun100.c
gcc -c fun100.c
main.o : main.c
gcc -c main.c
I 've read many articles online talking about how the target "all" makes sure that everytime I change something in a function and I call make it will update only what changes (so I'm going to avoid uneccessary recompilation).
However, I am not sure if I am using it right here. I checked my makefile ( with 2 functions though) and it worked fine. But I am not sure if that's the way to take advantage of all here.
I tried to remove it and just leave program and below.. there and it worked as fine.
What am I missing?
Could you may provide examples that all is critical?
I 've read many articles online talking about how the target "all" makes sure that everytime I change something in a function and I call make it will update only what changes
all does not mean anything. It's just a convention. You have to define the targets correctly to do what you want. If you want make all to recompile everything, you need to define it so that it does that.
so I'm going to avoid uneccessary recompilation
In practice, I'd say that this is a completely unnecessary concern, and it's a waste of time creating makefiles that does this. If you have a large project you should not create makefiles manually. You use a build system like cmake.
If the project is small and only contain a few files, then the compilation time is in general not an issue. For a small project, my goal with a makefile would be to not have to type the compiler flags all the time.
Here is a makefile that would work fine for most very small projects like school assignments:
CFLAGS=-Wall -Wextra -pedantic -std=c17 -fsanitize=address
LIBS=-lm -lpthread
program:
gcc $(CFLAGS) $(LIBS) *.c
clean:
rm -rf *.o *~
Your makefile is fine, both with and without all: program.
The word all has no special significance in makefiles, using is just a convention. In your makefile all has no recipe (i.e. no commands associated with it), so make all and make program are equivalent.
Note that if you don't specify a target when invoking Make (e.g. make as opposed to make program), the first target in the makefile is built.

Compiling files with own header in C

I am currently at the beginning stage of learning how to program in C, and I came across some questions regrading header files. For example
I have a header file named header.h,
which has int comp (int, int) declared in header.h and
defined in header.c
In such case, If i were to compile a test.c using the comp function, I would have to go like
gcc test.c header.c
First question: having to add header.c everytime I gcc seems too inconvenient and redundant. Is it a necessity? If not, is there a way I can get around it? If so, why? Or is it, in fact, not redundant compared to its usage, and am I just complaining?
Second question: if I were to use multiple .c files with functions declared in header.h my gcc would have to go
gcc test.c header.c header2.c header3.c .....
and that again seems too redundant. (and from hereon, same questions as First question..)
Thanks in advance. First time asking questions in SO. Please tell me if there is anyway I can improve the clarity of the question.
I think you are looking for the make, that automates the execution of the files you are compiling.
With the use of make, you don't need to write every time the commands like 'gcc test.c header1.c header2.c ...' in the terminal (if you type the commands directly to the terminal, yes, you will need to do this all the time, which is very redundant and costs lots of time). Using make, you only do this one time, and then all you have to do is run the make command.
You can see more about makefile at https://en.wikibooks.org/wiki/Make.
I hope it can help you.
You could make a shell macro or script to execute the command, if it is too much effort to use shell history feature to re-execute the command.
When your project starts to get complicated it's normal to use a build system in which you configure the build commands in the build system, and then you invoke the build system when you want to build. For example, write a Makefile that lists all the .c files using the right syntax for makefiles, and then type make each time you want to build.
You could consider using an Integrated Development Environment which is a (usually) GUI that includes a build system and other useful features, in which case you just need to hit a key to build and run.
It is often desirable to spread out your code across multiple files; this helps to ease code management. Header files provide a unified way to expose functions defined in libraries or source code files to other source code files without including the actual code for those functions. This way, the same header file can be included in multiple source code files without compiling the same code for each of those files. However, this means that the source code for functions in the header file must be given to the compiler also. As such, you have to give your header.c to the compiler each time you compile.
This does mean that you will compile header.c each time you build your project, which is a bit redundant. One way around this is to compile the header.c into an object file, and then give that the compiler when you build:
gcc -c header.c -o header.o
gcc header.o test.c
Furthermore, software developers often like to distribute their program functions to other developer but without providing the actaul code. To do this, they often use software libraries, which contain the compiled source code, along with header files to access this code. This is probably a little more than what your looking for, so I'll leave you read up on it.
All this is used not to reduce redundancy in your compiler commands, but in your compiled programs. To make programmers' lives easier building their programs, makefiles and IDEs are often used. These may be things you might have to read up on, but the other answers posted here should provide a good starting point.
Writing a simple Makefile is very useful for compiling C programs. Here's an example
CC = gcc
CFLAGS = -g -Wall
OBJECTS = main.o cfile1.o cfile2.o cfile3.o
run: $(OBJECTS)
$(CC) $(CFLAGS) -o run $(OBJECTS)
Don't worry about header files when writing a Makefile; only worry about your ".c" files. This example Makefile assumes that you want to compile main.c, cfile1.c, cfile2.c, and cfile3.c. When adding the C files to your Makefile, make sure to use ".o" instead of ".c".
The Makefile should be in the same directory as your C files and must be named "Makefile" with a capital M. Simply type "make" to compile. Then run the program with "./run".

How to write a Makefile to compile a simple C program

Compile the following program
#include <stdio.h>
int main(void)
{
printf ("Hello from your first program!\n");
return 0;
}
a)-by using file of type Makefile
b)-the executable will be named Hello
"Please help to do an exercise. I know how to do it in CodeBlocks, but I don't know what Makefile is and how to write it in Linux. I compiled it using command "gcc filename.c" and subsequently "./a.out" but I still don't understand what the Makefile is. Is it a sort of shell script, an instruction? How would a Makefile for this task exactly look? Thanks in advance :) "
This is your simple make file for hello program.
CC = gcc
CFLAGS = -g
RM = rm -f
default: all
all: Hello
Hello: Hello.c
$(CC) $(CFLAGS) -o Hello Hello.c
clean veryclean:
$(RM) Hello
Suppose you have two makefiles in one directory named makefile.m1 and makefile.m2 and if you want build both make file then please use following commands
make -f makefile.m1
make -f makefile.m2
or use single Makefile that contains:
m1:
make -f makefile.m1
m2:
make -f makefile.m2
and use make m1 or make m2
Now lets clear your doubt about name of make file must not require Makefile
You can name makefile whatever you want. suppose i would like to give name myfirstmakefile.mk. To use it later you need to tell make what makefile you want. Use -f option for this:
make -f myfirstmakefile.mk
And again extantion .mk is also not manadatory you can use whatever you want but never forgot to use -f option.
so may this help make sense to you.
A makefile is a recipe for the make utility how to create some file (called a target) from some other files (called dependencies) using a set of commands run by the shell. A makefile typically looks like this:
target: dependency [...]
command1
command2
Try running man make for details.
Now for your task, really there is no need for a Makefile, since make has built-in rules that know how to compile a simple program. All you need to do is place your C source in a file named after the executable name (Hello) and with a .c extension, i.e. Hello.c.
Then a simple
$ make Hello
cc Hello.c -o Hello
does everything. If you want to use gcc instead of cc, you can run
$ rm Hello
$ make CC=gcc Hello
gcc Hello.c -o Hello
If you tell your instructor/teacher/prof that an empty makefile is all you need since you know the built-in rules do the right thing, you'll get some extra credit and maybe your instructor has learnt something new :-) If you are asked for a reference, you could quote the relevant parts of the make manual, or, do it like a pro, quote from the POSIX Standard for the make utility, section Default Rules.
before going for makefile you have to know what's it and why we need it
What is Makefile?
Makefile is a script written in a certain prescribed syntax which helps to build the target output (normally, one or more executables) from source files by compilation and linking. In simple words, makefile will compile your source code in simple & fast way.
Why we need Makefile?
=> Large projects can contain multiple source files which are dependent in one another or arranged in hierarchical manner for example, in order to compile file A, you have to first compile B; in order to compile B, you have to first compile C; and so on.
=> Make is a solution to these problems. It can be used to compile whole project in well arranged manner and generate your target according to your make rule(which we will discuss later) by entering single command that is make.
=> An important feature is that when a project is recompiled after a few changes, it will recompile only those files which are changed, and any other files that are dependent on it. This saves a lot of time.
=> For a large project, when a few changes are made to the source, manually recompiling the entire project each time is tedious, error-prone and time-consuming.
Here is nice link for it :How to write first makefile
A makefile is a recipe for computers with instructions how to perform certain tasks and with dependencies between those tasks.
In the simple form, it looks like so:
a.out: filename.c
gcc filename.c
Read: "To build a.out from filename.c, run the command gcc filename.c. If a.out is newer than filename.c, then don't do anything"
Note: The first character in the gcc line must be a tab.

How to make a makefile properly, Why is this makefile not correct

I am trying to understand how to make a make file in Linux, and some one suggested to me to use this:
target: mytalkc.c mytalkd.c
gcc mytalkc.c -o mytalkc
gcc mytalkd.c -o mytalkd
When executing the above code exactly using "make" in the terminal everything ran great and everything compiled and made a executable successfully. So I thought this was correct, and I went with this for my makefile.
After futher documentation I learned that the correct way to make a makefile was not what I had above....
My question is, why does "target:" work and why was make was able to complete everything with no errors. Also why is things like "all:" used in make files over "target:" ?
Thanks in advance and sorry if it seems obvious, but I am new to Linux programming.
Typically a makefile is structured into multiple target rules, which contain dependencies that may rely on other dependences and so on. The word "all" is suggestive of "all targets", which means any dependencies of the "all" target are built. Additionally, some implementations of make allow for phony targets, such as "all", that tell make not to look for a file with one of the suffixes in a predefined suffix list, such as "all.c" to build the binary (program) with the filename "all".
Your actual question regarding why "target" works pertains to the behavior of make. It automatically makes the first target in the makefile unless a specific target is given. In your case, "target" is the first target in your file, so "make" by itself will make it (often "all" is used instead, but it is just a name; you should use "all" to simply because it is common practice).
Here is an example of how your file might be reworked with multiple targets (see the documentation for your make utility to understand the syntax, such as "info make" or "man make"):
all: mytalkc mytalkd
mytalkc: mytalkc.c
gcc $< -o $#
mytalkd: mytalkd.c
gcc $< -o $#
There are a lot of other things to address outside the scope of this answer, including implicit suffix rules and compiling several individual parts of a program/library together to create the program (splitting makefile rules into program/library: object1.o object2.o main.o and then individual rules for e.g. object1.o: object1.c). However, those are the basics that you need to know for now.
For what i know if you compile using gcc mytalkc.c -o mytalkc you are just compiling the source file as an object, it means that the compilation went well, but the file is not executable still because you haven't done any liking.
Try with this:
all: mytalkc.o mytalkd.o
mytalkc.o: mytalkc.c
gcc mytalkc.c -c mytalkc.c
mytalkd.o: mytalkd.d
gcc mytalkc.c -c mytalkd.c
invoking make all

Where does 'All' belong in a Makefile?

Where do we put the all in a Makefiles?
I had a similar question found earlier, but I needed a little bit more details. I also looked at the GNU make manual, but got lost in the mountain of documentation. I tried the googles, but didn't find a good example. So, I did what was my last resort and tried to figure it out by hacking at a Makefile myself. I have:
CC=gcc
CFLAGS=-Wall -g
clean:
rm -f all: ex1
This didn't compile my ex1 in C. Also, if I wanted to add more to this make file. Like ex1, ex2, to exercise whatever. Would I just put the all at the top and repeat the
rm - f whatever
line below clean?
Appreciate your help and assistance. Patience appreciated too.
all is actually nothing special, just a target name commonly used. To make it work best, it should be the first target in the file. This makes it the default target, and gmake works the same as gmake all.
Normally, the all target has dependencies, which are the things which need to be built. E.g.
all: myexe
rm is related to the clean target (which is also nothing special, just a name commonly used). You define it this way:
clean:
rm -f myexe
This makes it delete myexe when gmake clean is run. If you makefile builds other files, they should also be listed there.
There's a lot more to know about makefiles. Normally you would use variables and template rules, which help you avoid repeating yourself. But this is far more than a simple answer can describe.

Resources