If you check the GNU make manual How make Processes a Makefile you'll notice this sentence:
make reads the makefile in the current directory and begins by processing the first rule.
Followed by in the next paragraph:
If some other rule is not depended on by the goal (or anything it depends on, etc.), that rule is not processed, unless you tell make to do so (with a command such as make clean).
Here your first rule says to build good_echo.s
, and none of the other targets are prerequistes of that, so it's the only one built.
If you run make good_echo
then all will be built. Alternatively you can ensure that the rule to build the target good_echo
is the first rule in your makefile.
Or, you can use an often-used idiom and create a target all
as the first rule which depends on the things you want to generate:
all: good_echo
To be clear, other than the first rule in the makefile it's not important in which order the rules are defined.
ETA
As pointed out by Joseph Quinsey in the comments, your rule here:
good_echo.o: good_echo.s
gcc -S good_echo.s -o good_echo.o
is incorrect. The -S
option tells the compiler to stop after generating assembly and write it out, but already have assembly as your input. You want an object file, so you should use the -c
option to tell the compiler to stop after generating an object file (and not try to link):
good_echo.o: good_echo.s
gcc -c good_echo.s -o good_echo.o
To be more clear: the compiler can infer what type of input it's given by using the extension to the file (in this case .s
means assembly)--or you can force it with the -x
option if you prefer--but it won't infer the type of output you want: you always have to tell it that with options such as -c
, -S
, and -E
. If you don't use any of those then it will run all steps and try to generate an executable program.