LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 07-02-2012, 07:17 AM   #1
Aquarius_Girl
Senior Member
 
Registered: Dec 2008
Posts: 4,731
Blog Entries: 29

Rep: Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940
In which cases should we keep multiple targets instead of one in a Makefile?


Code:
targetOne : source/sourceA.cpp source/sourceB.cpp source/main.cpp
         g++ -Wall source/sourceA.cpp source/sourceB.cpp source/main.cpp
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?
 
Old 07-02-2012, 07:27 AM   #2
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
Quote:
Originally Posted by Anisha Kaul View Post
Code:
targetOne : source/sourceA.cpp source/sourceB.cpp source/main.cpp
         g++ -Wall source/sourceA.cpp source/sourceB.cpp source/main.cpp
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.
 
1 members found this post helpful.
Old 07-02-2012, 07:28 AM   #3
Aquarius_Girl
Senior Member
 
Registered: Dec 2008
Posts: 4,731

Original Poster
Blog Entries: 29

Rep: Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940
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?
 
Old 07-04-2012, 03:32 AM   #4
kauuttt
Member
 
Registered: Dec 2008
Location: Atlanta, GA, USA
Distribution: Ubuntu
Posts: 135

Rep: Reputation: 26
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.

-kd
 
Old 07-06-2012, 12:17 PM   #5
firstfire
Member
 
Registered: Mar 2006
Location: Ekaterinburg, Russia
Distribution: Debian, Ubuntu
Posts: 709

Rep: Reputation: 428Reputation: 428Reputation: 428Reputation: 428Reputation: 428
Hi.

Quote:
Originally Posted by Anisha Kaul View Post
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.

Last edited by firstfire; 07-06-2012 at 12:35 PM.
 
Old 07-08-2012, 08:47 AM   #6
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
firstfire, it's not that old, and as far as I'm concerned, your post is the first to actually offer a correct answer.

In my analysis, the original Makefile sample is broken. The dependency relationship should use object files, not source files:
Code:
targetOne : source/sourceA.o source/sourceB.o source/main.o
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

--- rod.

Last edited by theNbomr; 07-08-2012 at 08:54 AM.
 
Old 07-08-2012, 12:30 PM   #7
firstfire
Member
 
Registered: Mar 2006
Location: Ekaterinburg, Russia
Distribution: Debian, Ubuntu
Posts: 709

Rep: Reputation: 428Reputation: 428Reputation: 428Reputation: 428Reputation: 428
Hi.

Quote:
Originally Posted by theNbomr View Post
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:
Code:
targetOne : source/sourceA.o source/sourceB.o source/main.o
         g++ $^ -o $@
Here automatic variable $^ expands to a list of all prerequisites of the rule and $@ expands to the name of the target.

The -Wall option is probably useless in the linking stage.

Last edited by firstfire; 07-08-2012 at 12:39 PM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
make: using targets, prerequisites from another Makefile Meson Programming 2 12-02-2011 12:53 PM
*** No targets specified and no makefile found ritam_bkp Linux - Software 16 09-27-2008 09:33 AM
Makefile: using targets to declare dependent vars blackcat_73 Linux - Software 0 11-21-2006 03:39 AM
makefile targets dand Programming 1 07-11-2005 03:28 PM
[makefile] Do header files need to be set targets? chuanyung Programming 2 03-11-2004 09:22 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 04:56 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration