RRGT19
RRGT19

Reputation: 1677

Writing a Makefile to generate the modified, assembly, relocatable and executable file from a C program

I'm using CentOS to write a Makefile to generate these files from a C program:

  1. hello.i (Modified source program, text)
  2. hello.s (Assembly program, text)
  3. hello.o (Relocatable object program, binary)
  4. hello (Executable object program, binary)

The idea is to open each file to see its content.

C program (called hello.c)

#include <stdio.h>
int main() {
   printf("Hello, World!");
   return 0;
}

Makefile

all: hello

hello:
      gcc -I hello.c -o hello.i

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

hello.s:
      gcc -S hello.i -o hello.s

hello.i:
      gcc ???

clean:
      rm -rf *.o hello

Also, a clean command to delete all.

Error that I receive when I do: make all

compilation terminated. make: *** [hello] Error 4

I know that there is a single command to generate all at once, but, I want to do it by steps. This is my first Makefile that I try to do and I'm not 100% familiar yet.

What I'm doing wrong, maybe a wrong flag?

My goal is to generate all the files mentioned above to open them and see their content.

Upvotes: 1

Views: 354

Answers (2)

Chelmy88
Chelmy88

Reputation: 1116

Without the hello.i, which is for me unclear what is should be, your make file should look like that:

all: hello hello.s

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

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

hello.s: hello.c
    gcc -S hello.c -o hello.s

clean:
    rm -rf *.o

You issue is that in Makefile, after the semicolon you should indicate the dependencies (the files the current output will need to be produced).

In you case, all declares that helloand hello.s are required. Then make looks to produce them using the given commands. Hello declares that hello.o is required, so it also look to the given command to produce it.

hello.o and hello.o declare that hello.c is required, so make will check if it finds the file and in yes it will run the gcc command. Now that hello.o is produced, it will go back to produce hello.

The commands should be indented with proper tabs, so if you copy paste check that you have tabs and no multiple spaces.

Upvotes: 2

Marco Bonelli
Marco Bonelli

Reputation: 69276

Well, you did not declare a recipe for hello.i, and you did not declare the appropriate dependencies for the other recipes. Additionally, the command line option to create hello.i is -E, not -I.

Let's see:

  • hello needs the file hello.o
  • hello.i needs the file hello.c
  • hello.o needs the file hello.c
  • hello.s needs the file hello.i

This would be the correct makefile:

all: hello

hello: hello.o
    gcc hello.o -o hello

hello.i: hello.c
    gcc -E hello.c -o hello.i

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

hello.s: hello.i
    gcc -S hello.i -o hello.s

clean:
    rm -rf *.o hello

Additionally, taking advantage of Make special variables, you can use $@ to indicate the current recipe, and $< to indicate the first dependency, making it less verbose, like this:

all: hello

hello: hello.o
    gcc $< -o $@

hello.i: hello.c
    gcc -E $< -o $@

hello.o: hello.c
    gcc -c $< -o $@

hello.s: hello.i
    gcc -S $< -o $@

clean:
    rm -rf *.o hello

Upvotes: 1

Related Questions