8

I was under an impression that the left hand side of the colon : represent target i.e. the executable file, and the right hand side represents 'dependencies', i.e. the files needed to produce the said target.

hello : hello.c
    gcc hello.c -Wall -o hello

So, I thought the target 'hello' is the name of the final executable file.

executableHelloWorldFile : hello.c
    gcc hello.c -Wall -o hello

but, when I changed 'hello' to 'executableHelloWorldFile', nothing changed in the output.

I know how to create the target, but here I wish to understand that in what matters does a target help a Makefile?

Aquarius_Girl
  • 21,790
  • 65
  • 230
  • 411

5 Answers5

12

Firstly, Target is assumed to be a file, which, if doesn't exist or its timestamp is later than any of its dependencies, is remade. If you change the target name from the actual filename to something random, your target will always be remade, because that arbitrary file you are fooling make with doesn't exist and it is not created when make runs the commands you specified.

Edit: your compiler has no idea make invokes it, it executes exactly the instructions you gave it (as every computer program does and should do). If you say '-o hello', it will write the binary to the file 'hello' regardless to the bogus target name you came up with.

  • 1
    No, a "target" isn't necessarily assumed to be a file. What about "make all" (for example)? – paulsm4 Jul 02 '12 at 06:33
  • 1
    Tou're partially right. All is a special target, but in this specific case target *is* assumed to be a file. –  Jul 02 '12 at 06:35
  • so why does the output file gets the name `hello` in the second case? I did delete the previous hello and ran make again. – Aquarius_Girl Jul 02 '12 at 06:37
  • 3
    The output file gets the name "hello" because your rule said "-o hello" ;) – paulsm4 Jul 02 '12 at 06:38
  • @paulsm4 ofcourse, so in this case- what does the target do? It isn't the name of the output file? Or it is getting over ridden by -o option? – Aquarius_Girl Jul 02 '12 at 06:42
  • 1
    It's not 'overridden'. Makw doesn't do anything to your compiler -- if you used '-o hello' the comiler will use '-o hello'. If you want to use the target name as the output filename, use `-o $@` instead. –  Jul 02 '12 at 06:43
  • 2
    No - the target is *not* necessarily the name of the output file!!!! That's just a convention. And there are metacharacters (like $< and $*, for example) that support that convention. – paulsm4 Jul 02 '12 at 06:43
3

make executes the command you gave it. If that command doesn't create the target, it's your fault for writing the wrong command. The significant difference is that if you have the target specified correctly, you can run make twice in a row and it will know the second time that the target is up to date and doesn't need to be rebuilt. When the target isn't actually created by the command, if you run make twice in a row, the second one will needlessly rerun the command.

Some targets (like all and clean) are conventionally included in Makefiles without actually being existing files. They represent bigger actions that the user can request with commands like make clean in which the commands must be run every time.

Alan Curry
  • 14,255
  • 3
  • 32
  • 33
3

A make target is basically a file that you want rebuilt.

Make can't divine what you want built, so you have to tell it, implicitly or explicitly, what it should build. Often, the first target in the file is a name such as 'all' and if you run 'make' without any explicit target, it will build the first target listed in the makefile. However, some makefiles do not specify any target; then you must specify one on the command line. Or, if you don't want the default target built, then you must specify the target that you do want built.

A makefile will usually include code to make your program, install your program, clean up afterward, and other things.

so the word target could be various keywords, such as all, install, clean, etc.

It's a way of saying make something. make all implies do everything

user1089679
  • 2,328
  • 8
  • 41
  • 51
  • so, finally, the target name is not necessarily the output files's name, but we can have same names for target and output files by keywords like '$@', '$^' etc. – Aquarius_Girl Jul 02 '12 at 07:00
  • @AnishaKaul ya its not necessarily. ya u are right in understanding – user1089679 Jul 02 '12 at 08:14
  • No! The correct term for "$@" etc are ["automatic variables"](http://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html#Automatic-Variables). Automatic variables "have values computed afresh for each rule that is executed, based on the target and prerequisites of the rule." The "target" names an action to be invoked. What the action is, is determined by the "rule". Whether calling the target actually invokes the rule depends on the "prerequisites". "Automatic variables" are just "pattern matching" - they make it easier to relate rules to prerequisites to targets. – paulsm4 Jul 02 '12 at 15:35
2
  1. Yes, in your example, the target "hello" happens to result in building the .exe "hello".

  2. But no, you can trigger any action (or combination of actions) with a target.

    For example, "make clean", "make build" and "make install" and "make all" are common commands. They trigger the makefile to 1) clean up any "junk" that's already been built, 2) recompile the project, 3) install the project or 4) do everything

  3. To answer your question, a "target" is just a way to tell a makefile to "do something".

    In your example, the target will invoke "gcc". But it will invoke it if - and only if - the source file "hello.c" is out of date.

  4. A makefile usually consists of many targets, rules and defines.

    A component usually consists of multiple sub-projects, each with its own makefile.

'Hope that helps .. PSM

paulsm4
  • 114,292
  • 17
  • 138
  • 190
  • you said *"But it will invoke it if - and only if - the source file "hello.c" is out of date."* This time I edited the hello.c with spaces. Ran make again, but it the output file's name was again 'hello', not 'executableHelloWorldFile'. This is Linux – Aquarius_Girl Jul 02 '12 at 06:40
  • PS: doniyor quote is absolutely correct: "Target tells what to do, and rule tells how to do it". – paulsm4 Jul 02 '12 at 06:41
  • 1
    @AnishaKaul You given your output file name is hello thats why you getting hello file as a output.executableHelloWorldFile is your target not yours output binary file name. – user1089679 Jul 02 '12 at 06:43
  • @user1089679 so, this means that target doesn't have anything to do with the executable file's name? – Aquarius_Girl Jul 02 '12 at 06:44
  • Paul - I think you should add "No - the target is not necessarily the name of the output file!!!! That's just a convention. And there are metacharacters (like $< and $*, for example) that support that convention. " to your answer to make it complete, I'll select it then. – Aquarius_Girl Jul 02 '12 at 06:50
  • @AnishaKaul ya that will not to do anything with executable – user1089679 Jul 02 '12 at 06:55
  • @AnishaKaul Please read my answer i mentioned there about different target like all clean and install etc. – user1089679 Jul 02 '12 at 06:55
  • 1
    @AnishaKaul - I'm still not sure you've really "got it". Please look at [my link](http://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html#Automatic-Variables) above, or the link doniyor cited: http://developers.sun.com/solaris/articles/make_utility.html. – paulsm4 Jul 02 '12 at 15:39
1

You need to use the appropriate variables in the rule: $@ is the target $^ are the dependencies. In your case this should be:

executableHelloWorldFile : hello.c
    gcc $^ -Wall -o $@

Or when you only need to refer to the first dependency, use $<:

executableHelloWorldFile : hello.c
    gcc $< -Wall -o $@
Thor
  • 45,082
  • 11
  • 119
  • 130