Multiple targets but same dependency

旧街凉风 提交于 2021-02-05 09:11:42

问题


This is a part of my makefile :

SRC     =   ./
DIRS    =   src libs/maths libs/struct
BIN_DIR =   ./bin/

SRC_DIRS=   $(foreach dir, $(DIRS), $(addprefix $(SRC), $(dir)))
SRC_TEST=   $(sort $(SRC_DIRS))

SRCS    =   $(foreach msrc, $(SRC_DIRS), $(wildcard $(msrc)/*.c))

DEL_PRE =   $(foreach target, $(SRCS), $(notdir $(target)))
ADD_PRE =   $(foreach target, $(DEL_PRE), $(addprefix $(BIN_DIR), $(target)))
OBJS    =   $(ADD_PRE:.c=.o)

.PHONY: all clean re

all:        $(EXEC)

$(EXEC):    $(OBJS)
    $(CC) $(OBJS) -o $@ $(LDLIBS)

$(OBJS):    $(SRCS)
    $(CC) -o $@ -c $<

When i use make all, i have in output :

gcc -o bin/main.o -c src/main.c
gcc -o bin/cosin.o -c src/main.c
gcc -o bin/pears.o -c src/main.c
gcc -o bin/outil.o -c src/main.c
gcc -o bin/verif.o -c src/main.c

But i would like to have for each target, it assigned dependency :

gcc -o bin/main.o -c src/main.c
gcc -o bin/cosin.o -c libs/maths/cosin.c
gcc -o bin/pears.o -c libs/maths/pears.c
gcc -o bin/outil.o -c libs/struct/outil.c
gcc -o bin/verif.o -c libs/struct/verif.c

How can i fix it ?


回答1:


This seems like a very common misconception; I just answered effectively this same question yesterday. I'm not sure where it comes from or how to combat it.

This rule:

$(OBJS):    $(SRCS)
       $(CC) -o $@ -c $<

does not somehow magically combine the contents of the OBJS variable and the SRCS variable to figure out how they match up. The variable references are simply expanded, and the result is this:

bin/main.o bin/cosin.o ... : src/main.c libs/maths/cosin.c ...
       $(CC) -o $@ -c $<

which is the same as if you'd written this:

bin/main.o : src/main.c libs/maths/cosin.c ...
       $(CC) -o $@ -c $<
bin/cosin.o : src/main.c libs/maths/cosin.c ...
       $(CC) -o $@ -c $<
...

Now, you can hopefully see why you compile the same file: in every rule you have the same prerequisites, so $< is always the first one, which is always src/main.c.

There are multiple ways to work this but if you really want to have all the source files from different directories compiled into object files in the same directory your job is harder, because there's no common pattern that will match them all. In this case the simplest thing to do is use VPATH for directory search: replace the above rule with this:

$(BIN_DIR)/%.o : %.c
       $(CC) -o $@ -c $<

then tell make how to find your source files, like this:

VPATH := $(sort $(dir $(SRCS))

Be aware this method can't be used for any source files that are themselves generated output that make is expected to create.



来源:https://stackoverflow.com/questions/64947957/multiple-targets-but-same-dependency

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!