skip to Main Content

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.

2

Answers


  1. 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
    
    Login or Signup to reply.
  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search