lewiatan
lewiatan

Reputation: 1176

makefile - define dependency using variable with objects when building many executables

I'm following great tutorial about ffmpeg (http://dranger.com/ffmpeg) and I'm trying to build a generic makefile for it.

My problem is that I cannot define a generic rule for executables to be depenent on an object of the same name but with ".o" suffix.

Example: when invoked make all I want to build 2 executables tutorial01 and tutorial02 out of 2 files tutorial01.cpp and tutorial02.cpp, but first I want to compile them into *.o and then link them.

My whole Makefile is like so:

CC=g++
CXXFLAGS="-std=c++11"
CXXFLAGS+=`sdl-config --cflags`

LDFLAGS=-L/usr/lib/x86_64-linux-gnu/
LDFLAGS+=-L/lib/x86_64-linux-gnu/
LDFLAGS+=-lavutil-ffmpeg -lavcodec-ffmpeg -lavformat-ffmpeg -lswscale-ffmpeg
LDFLAGS+=`sdl-config --libs`

SOURCES=$(wildcard *.cpp)
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLES=$(SOURCES:.cpp=)
all : $(EXECUTABLES)

# Not working:
#%$(EXECUTABLES) : $(OBJECTS)
#   $(CC) $< -o $@ $(LDFLAGS) $(LD_LIBS)
#
# Not working (always substitutes the first found):
#$(EXECUTABLES) : $(OBJECTS)
#   $(CC) $< -o $@ $(LDFLAGS) $(LD_LIBS)
#
# Not working:
#for exec in $(EXECUTABLES) ; do \
#$(exec) : $(exec).o ; \
#done
#
# Working:
#tutorial01:tutorial01.o
#tutorial02:tutorial02.o
#tutorial03:tutorial03.o

%: %.o
    $(CC) $< -o $@ $(LDFLAGS) $(LD_LIBS)

%.o : %.cpp
    $(CC) $(CXXFLAGS) -c $< -o $@

clean:
    rm -rf $(OBJECTS) $(EXECUTABLES)

I tried what is stated above as "not working" and also gave an example of what is working but not generic.

Upvotes: 0

Views: 209

Answers (1)

Beta
Beta

Reputation: 99144

# Not working (always substitutes the first found):
$(EXECUTABLES) : $(OBJECTS)
    $(CC) $< -o $@ $(LDFLAGS) $(LD_LIBS)

This fails because $(OBJECTS) expands to something like tutorial01.o tutorial02.o tutorial03.o for all targets, and $< expands to the first prerequisite, which is the same (tutorial01.o) for all targets.

# Not working:
for exec in $(EXECUTABLES) ; do \
$(exec) : $(exec).o ; \
done

This fails because it is for-loop written in shell syntax. You can write a for-loop in Make syntax, but it is not needed here.

I would use a pattern rule:

tutorial%: tutorial%.o
    $(CC) $< -o $@ $(LDFLAGS) $(LD_LIBS)

or a static pattern rule:

$(EXECUTABLES): %: %.o
    $(CC) $< -o $@ $(LDFLAGS) $(LD_LIBS)

Upvotes: 1

Related Questions