What does "all" stand for in a makefile? - makefile

I read some tutorials concerning Makefiles but for me it is still unclear for what the target "all" stands for and what it does.
Any ideas?

A build, as Makefile understands it, consists of a lot of targets. For example, to build a project you might need
Build file1.o out of file1.c
Build file2.o out of file2.c
Build file3.o out of file3.c
Build executable1 out of file1.o and file3.o
Build executable2 out of file2.o
If you implemented this workflow with makefile, you could make each of the targets separately. For example, if you wrote
make file1.o
it would only build that file, if necessary.
The name of all is not fixed. It's just a conventional name; all target denotes that if you invoke it, make will build all what's needed to make a complete build. This is usually a dummy target, which doesn't create any files, but merely depends on the other files. For the example above, building all necessary is building executables, the other files being pulled in as dependencies. So in the makefile it looks like this:
all: executable1 executable2
all target is usually the first in the makefile, since if you just write make in command line, without specifying the target, it will build the first target. And you expect it to be all.
all is usually also a .PHONY target. Learn more here.

The manual for GNU Make gives a clear definition for all in its list of standard targets.
If the author of the Makefile is following that convention then the target all should:
Compile the entire program, but not build documentation.
Be the the default target. As in running just make should do the same as make all.
To achieve 1 all is typically defined as a .PHONY target that depends on the executable(s) that form the entire program:
.PHONY : all
all : executable
To achieve 2 all should either be the first target defined in the make file or be assigned as the default goal:
.DEFAULT_GOAL := all

Not sure it stands for anything special. It's just a convention that you supply an 'all' rule, and generally it's used to list all the sub-targets needed to build the entire project, hence the name 'all'. The only thing special about it is that often times people will put it in as the first target in the makefile, which means that just typing 'make' alone will do the same thing as 'make all'.

The target "all" is an example of a dummy target - there is nothing on disk called "all". This means that when you do a "make all", make always thinks that it needs to build it, and so executes all the commands for that target. Those commands will typically be ones that build all the end-products that the makefile knows about, but it could do anything.
Other examples of dummy targets are "clean" and "install", and they work in the same way.
If you haven't read it yet, you should read the GNU Make Manual, which is also an excellent tutorial.

Related

Makefile wildcard target expansion

I'm a fairly new user of GNU Make. I want to get a list of Golang files and build each one of them using Make.
I want to create a target that will receive the apt Go file as a param.
In the snippet I've written the control of the program never reaches the %.go target.
Here is a snippet of a file.
EXECUTABLES := $(wildcard cmd/*/*/*.go)
%.go:
echo "Build the go file"
build: $(EXECUTABLES)
echo $<
Output:
echo cmd/abc/handler/main.go
cmd/abc/handler/main.go
I modified the script to this but I'm facing the same issue. Also tried replacing %.go with *.go and with cmd/abc/handler/main.go
Here is one of the variants mentioned above.
%.go:
echo "Hello world"
build: $(wildcard cmd/*/*/*.go)
echo $<
Anything I might be missing here?
You have a rule that tells make how to build a .go file. But, you already HAVE a .go file. Make doesn't have to build it, it's a source file that you wrote. That rule has no prerequisites, so as far as make is concerned if the file exists, it's up to date (it doesn't depend on any other file).
So, when you ask make to build that file make looks and says "this file exists already, and it doesn't depend on anything, so the thing you asked me to do is already done and I don't need to run any commands".
When you write a makefile you have to think of it from the end first back to the beginning. What is the thing you want to end up with? That is the first target you write. Then what files are used as inputs to that final thing? Those are the prerequisites of that target. And what commands are needed to create the target from the prerequisites? That is the recipe.
Then once you have that, you think about those prerequisites, considering them as targets. What prerequisites do they have? And what commands do you need to turn those prerequisites into that target?
And you keep going backwards like that until you come to a place where all the prerequisites are original source files that can't be built from anything, then you're done.

How to trigger the rebuild of a Makefile prerequisite file ONLY when a specific target is called?

I haven't found an answer so far, so I think this is not a repeat question.
I have some Makefile along the lines of:
include prerequisite_2
all: prerequisite_1 prerequisite_2
clean:
rm *.mod
prerequisite_1:
mkdir somedir
prerequisite_2:
re-write existing file
The issue is that I want the prerequisite_2 to rebuild whenever the default goal is called (all) or when prerequisite_2 is called from the command line, and I know I can use touch prerequisite_2, FORCE or .PHONY to achieve this. However, I DO NOT want it to run every time (the written file contains dependency information for the Fortran files involved) as it doesn't make sense to also rebuild this when calling: make clean
Is it possible to emulate the effects of FORCE or .PHONY only when the depending targets are called?
You can see what the goal targets are by looking at the MAKECMDGOALS variable.
So you can do something like:
ifeq (,$(if $(MAKECMDGOALS),$(filter-out all prerequisite-2,$(MAKECMDGOALS))))
include prerequisite-2
endif
The if condition will be true if MAKECMDGOALS is the empty string, or if it contains only all and/or prerequisite-2 but not if it contains any other target.
Usually, this is not what you want though. Usually you want to disable the include only if certain targets (clean is the classic example) are used.
This exact situation is even discussed in the GNU make manual.

Why "make all" works as expected without adding "all" to .PHONY target?

I know what a .PHONY does.
If in the folder where my Makefile is, I add an empty file called clean and after I run make clean all of the clean target will not be executed since there was not any change in the file, so the target will not run and this is correct.
If I add .PHONY: clean, than the clean is seen as a command and this is also correct.
My question is why this behavior does not happen the same to all target, since I added a all file in the folder.So basically the all target still executes like if it was a .PHONY: all
I have the fallowing makefile code.
all: test1 test2
test1: test1.o
test1.o: test1.c
test2: test2.o
test2.o: test2.c
clean:
rm -rf *.o test1 test2
How do you know that the all rule is "still executing"? That rule has no recipe, so there's no way it can be "executed".
If what you mean is that even though the all file exists in the local directory, make is still building the targets test1 and test2, that's how make works (this doesn't have anything to do with phony vs. non-phony targets). When make decides whether or not build a particular target first it tries to build all the prerequisites of that target, and all the prerequisites of those targets, etc. Only after all that is complete, can make know whether or not to build the first target (all in this case).
make clean here doesn't have any dependencies, so putting a file named clean there is enough for the target to be considered built.
make all on the other hand has dependencies. Even if you put a file named all there, Make has to check whether the all file is newer than test1 and test2. This process triggers builds of test1 and test2, and it happens to have the same effect as if all was a phony target.
The basis is that all: test1 test2 is a recipe for building a file named all, that depends on the files test1 and test2.
If you ran make all, Make would do something like this:
Analyse the Makefile.
Find out that all depends on test1 and test2.
Check the timestamp of all and see if it is "up to date".
It is "up to date" if none of the dependencies are newer than itself.
In other words, Make can skip building a file if it's newer than all it's dependencies.
Build outdated or missing files.
Now, if you would like to prevent Make from considering the targets as files, you could specify them as phony targets. That is best practice for non-file targets like all.
(This answer isn't disagreeing with either of the existing answers, but suggesting another way of thinking about this).
When you have a rule like
dst: src
action
you're saying two things (as you know):
if dst doesn't exist, or is older than src, then do action; and
when action completes, the file dst will exist.
With targets such as all or clean, the second statement is of course not true. Make doesn't hold you to the promise in (2), so when you say make all, it'll compute and generate the required dependencies, and not complain that there's no file all in place afterwards. You're lying to Make, but it doesn't mind (it's cool with that...). That is, this is basically a makefile hack.
Where this goes wrong, of course, is if for some reason there happens to be a file called all or clean. Then Make will take the modification date of the file all into account when calculating the dependencies, and possibly come to a conclusion you didn't expect.
So what .PHONY: all does is legitimise the hack, and tells Make ‘even if a file all exists, pretend that it doesn't’; you're basically cancelling promise (2).
Therefore, as the other answers state, mentioning .PHONY isn't necessary. It simply forestalls an error – easy to make but easy to miss – when a file matching a phony target is accidentally created.

Makefile pattern rules not working

I am learning makefiles, and can't just wrap my head around this problem i am having, and would like to understand how/why this fail.
I have half a dozen erlang files in a src directory. I want to compile these into a ebin directory, without having to define a rule for each and every one of them. According to the Gnu make documentation, pattern rules should be right up my alley.
However, with the following makefile, all I get from make is make: *** No targets. Stop. Why is that?
ebin/%.beam: src/%.erl
mkdir -p ebin
erlc -o ebin $<
Edit: Based on this answer, I now understand that i would have to explicitly declare the targets, for instance by using make ebin/cmplx.beam. However, i still do not understand how i should write my makefile to get my desired behaviour - since I have half a dozen targets (and in other projects even more), this seems like an unnecessary hassle. Is there not a way to define targets based on the source file names?
The target rule tells make that whenever it needs to produce a beam file in the ebin directory, and there exists a corresponding erl file in the src directory, it can use erlc.
However, this doesn't tell make that this is what it needs to do. You could explicitly tell make what it needs to do by giving it a target on the command line:
make ebin/foo.beam
If you don't give a target on the command line, make will pick the first non-pattern rule in the makefile as its target. However, your makefile doesn't have any non-pattern rules, so there is no target.
What you probably want is that for each existing erl file in src, make should consider the corresponding beam file in ebin to be a target. You can achieve that by calling wildcard and patsubst:
erl_files=$(wildcard src/*.erl)
beam_files=$(patsubst src/%.erl,ebin/%.beam,$(erl_files))
ebin/%.beam: src/%.erl
mkdir -p ebin
erlc -o ebin $<
all: $(beam_files)
(The indented lines need to be actual physical tabs, not spaces.)
That way, running make will rebuild all beam files that are out of date. all gets chosen as the default target, and it in turn depends on all beam existing or potential, each of which in turn depends on the corresponding erl file.
This trick is described in the GNU make manual.

make variables that depend on a target

I have a Variable in make that is dependant on a file that must be built before the variable can be set, is there a way to get this to work?
parsable_file: dependancies
commands to make parsable_file
targets=$(shell parse_cmd parsable_file)
$(targets): parsable_file
command to make targets
.phony: all
all:$(targets)
If I run $ make parsable_file && make all this will work (I get an error that parse_cmd cant find parsable_file but it works), but just make all will not work. Is there a Make idiom for this?
Set the variable in a file that you include in the main makefile and include a rule in the main makefile for how to build it (the one you already have should be fine).
I believe that will do what you want.
See Including Other Makefiles and How Makefiles Are Remade (which is linked from the first section) for more details on this concept.
Also, unless parseable_file has a usage independent from that parse_cmd call, it should be possible to do the creation and the parsing at the same time and just have the resulting makefile contain the correct value for $(targets) in one step.

Resources