1

I'm trying to write a makefile that generates assembly code, object code, and an executable from a .c file. This is the contents of my makefile:

good_echo.s: good_echo.c
    gcc -S -fstack-protector-all good_echo.c
good_echo.o: good_echo.s
    gcc -S good_echo.s -o good_echo.o
good_echo: good_echo.o
    gcc -v good_echo.o -o good_echo
clean:
    rm -f good_echo.o good_echo.s good_echo 

When I enter make into terminal, it only generates the assembly code. Can someone explain what's going on?

  • Can you show the actual make command you typed and the output you get (I mean like cut and paste the actual text not paraphrased)? – MadScientist Oct 10 '18 at 22:55
  • The command I type into terminal is literally "make". The output I get is "gcc -S -fstack-protector-all good_echo.c". When I check the folder contents only the .s file is added – chloap soap Oct 10 '18 at 23:06
  • Aha, you've updated the makefile though; it's not the same as it was when you originally posted it. – MadScientist Oct 10 '18 at 23:08
  • Yes I did it before I saw your reply. My apologies – chloap soap Oct 10 '18 at 23:12

1 Answers1

2

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.

MadScientist
  • 92,819
  • 9
  • 109
  • 136
  • Thank you so much for replying. I really appreciate it. I've gone and added the all: good echo to my program and I'm getting "gcc -S -fstack-protector-all good_echo.c / gcc -S good_echo.s -o good_echo.o / gcc -v good_echo.o -o good_echo / gcc: good_echo.o: No such file or directory / Using built-in specs. ......." – chloap soap Oct 10 '18 at 23:23
  • @chloapsoap: The gcc manual say `"-S ... do not assemble"`. So the command `gcc -S good_echo.s -o good_echo.o` looks odd to me (but I haven't tested it). – Joseph Quinsey Oct 11 '18 at 01:51