2
votes

I seem to be using % wrongly in Makefiles. This simple makefile shows the problem

Makefile:

mylib:  mylib-%.dll

mylib-%.dll:
    touch mylib-13.dll


myotherlib: myotherlib-13.dll

myotherlib-13.dll:
    touch myotherlib-13.dll

Output:

> make mylib
touch mylib-13.dll
> make mylib
touch mylib-13.dll

> make myotherlib
touch myotherlib-13.dll
> make myotherlib
make: Nothing to be done for `myotherlib'.  

mylib is always rebuilt (the second make mylib call is again executing the touch command), while myotherlib is only built once.

Why is this and what do I need to change so that mylib is not always rebuilt, i.e. the second call to make mylib also returns make: Nothing to be done for 'mylib'.?

1

1 Answers

1
votes

Explanation

The target of the rule (the left-hand part of the :), unless marked under the .PHONY special rule, is supposed to be created at the end of the make process and to exist if you reissue the command right after.

Here your rule myotherlib-13.dll does correctly create that target because your rule myotherlib directly depends on it and it is a basic rule.

However, your rule mylib-%.dll is a pattern rule, it will match a target if possible. The trick lies in your rule mylib which depends on the mylib-%.dll target. You're telling make mylib must depend on a file nammed mylib-%.dll, so it looks for a matching rule and finds it, but this rule create a file named mylib-13.dll instead so the target creation is never done.

Demo

If you want a demo of what is happening, change your touch xxx commands with touch $@ (the $@ is an automatic variable replaced with the name of the rule after replacing the pattern-matching part).

So with

mylib: mylib-%.dll

mylib-%.dll:
    touch $@

myotherlib: myotherlib-13.dll

myotherlib-13.dll:
    touch $@

And doing

$ make mylib

You will get the output

touch mylib-%.dll

Solution

Simply change mylib: mylib-%.dll to mylib: mylib-13.dll and it will work as intended.

Use the code in the demo and you will see that the $@ will now correctly be replaced with mylib13.dll.