You could do something like the following:
CC=gcc
CFLAGS=-Wall -Werror -Wextra -O2 -g
SOURCE=file.c
all: binary assembly
binary: $(SOURCE)
$(CC) $(CFLAGS) $(SOURCE)
assembly: $(SOURCE)
$(CC) $(CFLAGS) -fverbose-asm -S -masm=intel $(SOURCE)
clean:
rm -f file.s a.out
And use it like this:
$ make # same as `make all`
$ make all # makes both executable (binary) and assembly
$ make binary # makes binary file only
$ make assembly # makes assembly only
It seems that you can execute other labels from other labels. However
how do they differ from just writing the desired filename like I did?
Remember that Makefiles
consist of "rules" with the format:
target: dependencies
system command(s)
See more here.
The make
program decides on what should be done based on how you invoke it and how you define your rules. For example, the first rule with target all
depends on binary
and assembly
, so make
checks those rules, and carries out the relevant steps (in this case executing gcc
).
How does gcc differentiate between them?
The gcc
program is a compiler, which is a completely separate program. It is merely invoked by make
, just like rm
is for the clean
rule. It has no involvement in processing the Makefile
itself, so it doesn't need to "differentiate" anything -- make
does all the processing of the Makefile
.
Also, the $() variables you use, do they only exist for gcc or could
you also define them globally in your operating system?
The variables have nothing to do with gcc
. The make
program parses the Makefile
and performs the necessary substitutions before invoking the commands (e.g. gcc
).
The variables could be used elsewhere in the Makefile
too, for example with the rm
command. They are not specific to any command in particular.
You can also make use of environment variables in a Makefile
, as explained in this post.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…