简体   繁体   中英

Makefile: Circular - Dependency dropped

I have designed a Makefile that compiles all the .c files individually and produces a .o respectively (I think this happens Implicitly and works perfectly fine).

The executable (.out) is not being generated from the .o files.

Makefile:

TARGET = all.out
OBJS = file1.o file2.o file3.o
CC = gcc
CFLAGS = -g -Wall
all : $(TARGET)
$(TARGET) : $(OBJS)
#   gcc $^ -o $@
run : $(TARGET)
    ./$<
clean :
    rm -rf *.o $(TARGET)

Output:

$ make 
make: Circular all.out <- all dependency dropped.
gcc -g -Wall    -c -o file1.o file1.c
gcc -g -Wall    -c -o file2.o file2.c
gcc -g -Wall    -c -o file3.o file3.c
cp file1.o a.out

Note: The Makefile works perfectly and produces the perfect results if the line no. 7 present in it is uncommented.

line no.7:

#   gcc $^ -o $@

Output when line no. 7 is uncommented (Works perfectly as intended):

gcc -g -Wall    -c -o file1.o file1.c
gcc -g -Wall    -c -o file2.o file2.c
gcc -g -Wall    -c -o file3.o file3.c
gcc file1.o file2.o file3.o -o a.out

I am new to Makefiles.

Queries:

  1. why does commenting line no. 7 causing this issue and uncommenting it works perfectly?
  2. What is cp in the first output when line no.7 was commented?
  3. What does circular - dependency dropped error occur?

I can't explain how you are seeing the problem you showed to us. Either what you wrote above is not actually what you're using, or you have a buggy version of GNU make. I can't reproduce the behavior you're seeing.

But, I'm sure it's related to this: GNU make has a built-in rule that knows how to build an xx.out file from a file xx for any xx :

# make -p -f/dev/null
  ...
%.out: %
#  recipe to execute (built-in):
        @rm -f $@
        cp $< $@

If you comment out your own recipe as an explicit rule, then make will search for one among the pattern rules it knows about and it will find this built-in pattern rule.

However this rule shouldn't match based on what you've shown us: in order for it to match with a target of a.out , make would have to find or know how to build a target a and that doesn't seem to be available. Also, knowing how to build a would show a circular dependency on a.out .

If your makefile was:

TARGET = all.out

THEN it would all make perfect sense because you would have:

all : all.out
all.out : file1.o file2.o file3.o

and after the implicit rule match %.out: % it would expand like this:

all : all.out
all.out : all file1.o file2.o file3.o
        @rm -f all.out
        cp all all.out

So I assume that when you copied the output into your question you changed it: best to not do that. You should post exactly the problem you have (and verify you still have the problem with what you posted).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM