[SOLVED] In which cases should we keep multiple targets instead of one in a Makefile?
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Is there a reason why I should break this in multiple targets rather then keeping it as one?
In what cases do we need to have separate targets rather than one, in a Makefile?
Is there a reason why I should break this in multiple targets rather then keeping it as one?
In what cases do we need to have separate targets rather than one, in a Makefile?
I can think of one reason... you should not compile a source every time you want to build the application (in your case a.out). Consider building the object files separate from the application, and also check for dependencies. There's no need to rebuild something if its dependency has not changed.
Actually, I was under an impression that Makefile automatically detects which file is modified and compiles only that one!
Thanks for the clarification.
Is there any other reason that the targets should be separate?
Anisha, yes, Makefile only compiles the file(s) which has(have) been modified.
The other reason for which one can separate the targets is - suppose you want to use one (or more) of your *.o file for making multiples executables or libraries.
Actually, I was under an impression that Makefile automatically detects which file is modified and compiles only that one!
`make' automatically detects which prerequisite has been modified and runs corresponding commands.
From info make 'Rule Syntax':
Quote:
A rule tells `make' two things: when the targets are out of date,
and how to update them when necessary.
The criterion for being out of date is specified in terms of the
PREREQUISITES, which consist of file names separated by spaces.
(Wildcards and archive members (*note Archives::) are allowed here too.)
A target is out of date if it does not exist or if it is older than any
of the prerequisites (by comparison of last-modification times). The
idea is that the contents of the target file are computed based on
information in the prerequisites, so if any of the prerequisites
changes, the contents of the existing target file are no longer
necessarily valid.
If you have only one rule that compiles whole program and depend on everything, then the `make' is practically useless and can be simply replaced by shell script. If you carefully split your program into a number of modules (if it makes sense of course), you can reduce compilation time considerably by breaking the process into two separate stages: A) compilation of each module (file) into corresponding *.o file; B) linking these modules into an executable. This is especially important for C++ programs, as they tend to compile very slowly.
Note that very often you don't need to write lots of rules by hand -- implicit rules will do the job for you. Consider the following example:
Code:
$ cat mod1.c
void f1(){
}
$ cat mod2.c
int f2()
{
}
$ cat main.c
int main()
{
f1();
f2();
}
$ cat Makefile
a.out: mod1.o mod2.o main.o
$(CC) $^ -o $@
$ make
cc -c -o mod1.o mod1.c
cc -c -o mod2.o mod2.c
cc -c -o main.o main.c
cc mod1.o mod2.o main.o -o a.out
Now you do not need to recompile mod2.c if you modified mod1.c only:
Code:
$ make
make: `a.out' is up to date.
$ touch mod1.c
$ make
cc -c -o mod1.o mod1.c
cc mod1.o mod2.o main.o -o a.out
Hope that helps.
PS: Oops, just noticed that it is old and SOLVED.. My bad.
Then, the built-in rules will let make know whether or not to rebuild the specified object files. Optionally, the Makefile can include specific rules for how that is to be performed.
'Makefile only compiles the file(s) which has(have) been modified.' is incorrect. 'Makefiles' don't compile anything; they are recipes for make, and only if correctly crafted will result in the efficiencies to which you refer. Those efficiencies are one of the original reasons for the existence of make
In my analysis, the original Makefile sample is broken. The dependency relationship should use object files, not source files:
Indeed. One more problem with that Makefile is that `targetOne' will never be made (dwhitney67 already mentioned that). To fix it one should add `-o' option:
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.