GNU make: Circular dependency when VPATH is specified

357 Views Asked by At

Does anybody can help me to understand why GNU make considers "circular dependency" in the following example. If the VPATH is not specified and the source file presents in the current directory everything is Ok.

$ cat Makefile
VPATH = src

src%.o: %.cpp
        @echo ECHO: $@: $<

lib%.o: %.cpp
        @echo ECHO: $@: $<

dll%.so: %.cpp
        @echo ECHO: $@: $<

lib%.so: lib%.o dll%.so
        @echo ECHO: $@: $<

A.exe: libA.so

%.exe: src%.o
        @echo ECHO: $@: $<

$ make
make: Circular dllA.so <- A.cpp dependency dropped.
ECHO: libA.o: src/A.cpp
ECHO: dllA.so:
ECHO: libA.so: libA.o
ECHO: srcA.o: src/A.cpp
ECHO: A.exe: srcA.o

Thank you, Alex

2

There are 2 best solutions below

0
On BEST ANSWER

This looks like a known bug in GNUMake, fixed in version 3.82.

0
On

It is not a real solution, just different workarounds. I did not find the root of the problem.

Case #1 src/A.cpp exists, makefile a little bit modified:

#!/usr/bin/make -f

VPATH = src

src%.o: %.cpp
        @echo ECHO_1: $@: $<,

lib%.o: %.cpp
        @echo ECHO_2: $@: $<,

dll%.so: %.cpp
        @echo ECHO_3: $@: $<,

lib%.so: lib%.o dll%.so
        @echo ECHO_4: $@: $<,

A.exe: libA.so
#       @echo ECHO_45: $@: $<,

%.exe: src%.o
        @echo ECHO_5: $@: $<,

yy.mak: ;

Output contains the error

make: Circular dllA.so <- A.cpp dependency dropped.
ECHO_2: libA.o: src/A.cpp,
ECHO_3: dllA.so: ,
ECHO_4: libA.so: libA.o,
ECHO_1: srcA.o: src/A.cpp,
ECHO_5: A.exe: srcA.o,

Case #2 ./A.cpp exists, VPATH is commented:

Output (no error):

ECHO_2: libA.o: A.cpp,
ECHO_3: dllA.so: A.cpp,
ECHO_4: libA.so: libA.o,
ECHO_1: srcA.o: A.cpp,
ECHO_5: A.exe: srcA.o,

Case #3 VPATH is in the code and uncomment @echo ECHO_45: $@: $<, line

Output:

ECHO_2: libA.o: src/A.cpp,
ECHO_3: dllA.so: src/A.cpp,
ECHO_4: libA.so: libA.o,
ECHO_45: A.exe: libA.so,

Case #4 Modify lib%.so: lib%.o dll%.so as lib%.so: lib%.o #dll%.so, so remove dllA.so from dependency:

Output (no error):

ECHO_2: libA.o: src/A.cpp,
ECHO_4: libA.so: libA.o,
ECHO_1: srcA.o: src/A.cpp,
ECHO_5: A.exe: srcA.o,

I tried to use make -d to print detailed information about what is done, but I could not get a final result. It seems the problem is because of there are two targets for A.exe and one has no receipt line.