vamirio-chan
vamirio-chan

Reputation: 351

makefile: No rule to make target '%.o'

I have 3 files: Source.cpp 2ndfile.cpp 2ndfile.hpp And I'm trying to compile them with mingw32-make

makefile that doesn't work:

all: launch.exe

launch.exe: %.o
    g++ -o $@ $^

%.o: %.cpp
    g++ -c $< -std=gnu++11

makefile that works:

all: launch.exe

launch.exe: source.o 2ndfile.o
    g++ -o $@ $^

source.o: source.cpp
    g++ -c source.cpp -std=gnu++11

2ndfile.o: 2ndfile.cpp
    g++ -c 2ndfile.cpp -std=gnu++11

My question is: why the first one doesn't work? What's my problem with '%' patterns? The error I get: mingw32-make: *** No rule to make target '%.o', needed by 'launch.exe'. Stop.

Upvotes: 1

Views: 2594

Answers (2)

vamirio-chan
vamirio-chan

Reputation: 351

Substitute % with *.

all: launch.exe

launch.exe: *.o
    g++ -o $@ $^

*.o: *.cpp
    g++ -c $^ -std=gnu++11

EDIT: there's an answer below why this is a bad idea. Here's what works:

all: launch.exe

launch.exe: Source.o 2ndfile.o
    g++ -o $@ $^

%.o: %.cpp
    g++ -c $^ -std=gnu++11

Upvotes: 0

John Bollinger
John Bollinger

Reputation: 180331

My question is: why the first one doesn't work? What's my problem with '%' patterns?

A pattern rule matches targets to prerequisites via a common element in their names, represented by the % wildcard. You present your own example in the form of this rule:

%.o: %.cpp
    g++ -c $< -std=gnu++11

On the other hand, this rule ...

launch.exe: %.o
    g++ -o $@ $^

... is not a pattern rule, because the target name does not contain a %. There, you seem to be trying to use % in an entirely different sense, analogous to * in a glob pattern. It does not serve that purpose, even in pattern rules. That would give pattern rules a very different (and much less useful) meaning. Instead, in your non-pattern rule, the % is treated as an ordinary character.

There are many ways to write makefiles, but a good, simple model to start from for exploring pattern rules would be a combination of your first and second examples:

all: launch.exe

launch.exe: source.o 2ndfile.o
    g++ -o $@ $^

%.o: %.cpp
    g++ -c $< -std=gnu++11

Upvotes: 1

Related Questions