Question

I'm trying to improve the naive solution (single rules for compiling targets and additional one for linking all the previous targets together) which I used im my makefile. I came up with the following Makefile (clipped):

.PHONY: clean

BASE_DIR = ../

CC = gcc
CROSS_COMPILE = arm-none-eabi-
CFLAGS =-g -I${BASE_DIR}/include 
LDFLAGS =-L${BASE_DIR}/lib -Ttarget.ld -nostdlib 

SOURCES = first.c second.c third.c fourth.c
OBJECTS = $(SOURCES:.c=.o)
EXECUTABLE = $(OBJECTS:.o=)

all: $(EXECUTABLE)

%:
    ${CROSS_COMPILE}$(CC) $(CFLAGS) $(LDFLAGS) $*.c -o $*

clean:
    rm ${EXECUTABLE}

This works fine but I'd like to separate the compilation and linking processes. Therefore I tried to modify it as follows:

.PHONY: clean

BASE_DIR = ../

CC = gcc
CROSS_COMPILE = arm-none-eabi-

CFLAGS =-c -g -I${BASE_DIR}/include 
LDFLAGS =-L${BASE_DIR}/lib -Ttarget.ld -nostdlib 

SOURCES = first.c second.c third.c fourth.c
OBJECTS = $(SOURCES:.c=.o)
EXECUTABLE = $(OBJECTS:.o=)

all : $(EXECUTABLE)

%.o : %.c
    @echo "Compiling c file into o file"
    ${CROSS_COMPILE}$(CC) $(CFLAGS) $< -o $@

% : %.o
    @echo "Linking o file into executable"
    ${CROSS_COMPILE}$(CC) $(LDFLAGS) $< -o $@

clean:
    rm ${EXECUTABLE}

This works ok then I invoke the Makefile as e.g. make first.o; make first or if I modify the EXECUTABLE = $(OBJECTS:.o=) to EXECUTABLE = $(OBJECTS:.o=.out) and % : %.o to %.out : %.o. If, however, I try to invoke compilation as make or make first the implicit rules are used.

I tried going through the Makefile manual but there is really a lot of information in there, I got a little confused.

How can I modify the Makefile to be allowed to invoke building separate targets as make <target> or all the targets as make as the same time?

Was it helpful?

Solution

The paragraph where you describe your problem is very confusing and hard to understand. When asking questions please be sure that the section describing the problem is the most clear: it's helpful if you provide sample output showing exactly what commands you typed and the results you got, and explain what you expected to get instead.

However, my interpretation is that if you run make first it uses the built-in rule to compile first directly from first.c, rather than your pattern rules (note that both the built-in rules and your pattern rules are considered "implicit rules").

That's because make will choose the "shorter" implicit rule chain so the rule building an executable directly from source, in one step, rather than building the object then the executable in two steps, will be preferred. If you don't want to use the built-in implicit rule then you need to either invoke make with the -r flag, or else delete it by adding:

% : %.c

(just that) to your makefile.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top