Make uses same source file for different object files

試著忘記壹切 提交于 2019-12-02 09:50:13

The pattern rule does not put all objects in root directory, consider

CFILES := path/to/a.c b.c
OBJFILES := $(foreach f,$(CFILES),$(f:%.c=%.o))

all: $(OBJFILES)

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

Here is what you get:

cc -c path/to/a.c -o path/to/a.o
cc -c b.c -o b.o

The following is not a recommendation, but kind of an exercise in makefile programming.

If you have $(SRCFILES) and want to compile them one at a time, you can use:

define compile
$1.o: $1.c
    $(CC) $(CCFLAGS) -c $$< -o $$@
endef

$(foreach src,$(SRCFILES),$(eval $(call compile, $(src:%.c=%))))

If the correspondence of lists of sources and objects is not by name, but only by placement in list, you can destroy the CFILES list

define compile
src := $(CFILES)
CFILES := $(wordlist 2, $(words $(CFILES)), $(CFILES))
$1: $(src)
    $(CC) $(CCFLAGS) -c $$< -o $$@
endef

$(foreach obj,$(OBJFILES),$(eval $(call compile, $(obj))))

Or you may use a helper list, to keep CFILES unchanged:

helperlist := $(CFILES)

define compile
src := $(firstword $(helperlist))
helperlist := $(wordlist 2, $(words $(helperlist)), $(helperlist))
$1: $(src)
    $(CC) $(CCFLAGS) -c $$< -o $$@
endef

$(foreach obj,$(OBJFILES),$(eval $(call compile, $(obj))))

Consider the rule...

$(OBJFILES): $(SRCFILES)
        $(CC) $(CCFLAGS) -c $< -o $@

Let's say, for the sake of argument, that we have...

SRCFILES := a.c b.c
OBJFILES := a.o b.o

If you expand the rule manually it becomes...

a.o b.o: a.c b.c
        $(CC) $(CCFLAGS) -c $< -o $@

I think (correct me if I'm wrong) you are under the impression that this will be interpreted by make as a.o depends on a.c and, separately, b.o depends on b.c. That's not the case. What it actually states is that both of a.o and b.o depend on both of a.c and b.c.

So, when make tries to update the target a.o it sees the full prerequisite list of a.c and b.c and assigns the first of these, a.c, to the builtin variable $<. That's why you always see the first source file in $(SRCFILES) being compiled.

The best way to solve this probably depends on how you intend to structure your source file hierarchy and object files but you might want to take a look at using one or more vpath directives.

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