Make不编译好文件

时间:2022-10-26 09:41:59

I've got a problem with a Makefile, it just compiles many time the same file.

我有一个Makefile的问题,它只是编译了很多次同一个文件。

Here are my files:

这是我的文件:

$ ls *
carnet.data  carnet.l  carnet.y  Makefile

struct:
carnet.c  carnet.h  ihm.c  ihm.h  struct.c  struct.h

Here is my Makefile:

这是我的Makefile:

CC      = gcc
LEX     = lex
YACC    = yacc
FLAGS   = -Wall -Wextra -Werror -O3 -g
ELIB    = -lfl # Flex library
TARGET  = carnet

SRC     = $(shell find struct/ -name "*.c")
OBJ     = $(SRC:.c=.o)
SRCL    = $(shell find -name "*.l")
OBJL    = lex.yy.o
SRCY    = $(shell find -name "*.y")
OBJY    = y.tab.o

all : $(TARGET)

$(TARGET) : $(OBJ) $(OBJY) $(OBJL)
    @echo "Linking"
    @echo $(SRC)
    @echo $(OBJ)
    @$(CC) $^ -o $@ $(FLAGS) $(ELIB)


$(OBJY) : $(SRCY)
    @echo $<
    @$(YACC) -d $<
    @$(CC) -c y.tab.c -o $@

$(OBJL) : $(SRCL)
    @echo $<
    @$(LEX) $<
    @$(CC) -c lex.yy.c -o $@

$(OBJ) : $(SRC)
    @echo $<
    $(CC) -c $< -o $@ $(FLAGS)

clean :
    rm y.tab.c $(OBJY) y.tab.h lex.yy.c $(OBJL)
    rm $(OBJ)

destroy :
    rm $(TARGET)

rebuilt : destroy mrpropper

mrpropper : all clean

And here is the output when I do a 'make':

这是我做'make'时的输出:

struct/struct.c
gcc -c struct/struct.c -o struct/struct.o -Wall -Wextra -Werror -O3 -g
struct/struct.c
gcc -c struct/struct.c -o struct/carnet.o -Wall -Wextra -Werror -O3 -g
struct/struct.c
gcc -c struct/struct.c -o struct/ihm.o -Wall -Wextra -Werror -O3 -g
carnet.y
carnet.l
Linking
struct/struct.c struct/carnet.c struct/ihm.c
struct/struct.o struct/carnet.o struct/ihm.o

As we can see, when I do a 'echo $(SRC)' he finds all three files, but he only compiles the 'struct.c' file, and I don't understand why !

我们可以看到,当我执行'echo $(SRC)'时,他找到了所有三个文件,但他只编译了'struct.c'文件,我不明白为什么!

Thanks for your help, Phantom

感谢你的帮助,Phantom

1 个解决方案

#1


2  

SRC     = $(shell find struct/ -name "*.c")

You create a list here, $(SRC) will be struct/struct.c struct/carnet.c struct/ihm.c. Or any other order find may return, but according to your result, this seems to be the order.

你在这里创建一个列表,$(SRC)将是struct / struct.c struct / carnet.c struct / ihm.c。或者任何其他订单查找可能会返回,但根据您的结果,这似乎是顺序。

OBJ     = $(SRC:.c=.o)

This creates the modified list struct/struct.o struct/carnet.o struct/ihm.o

这将创建修改后的列表struct / struct.o struct / carnet.o struct / ihm.o

$(OBJ) : $(SRC)
    @echo $<
    $(CC) -c $< -o $@ $(FLAGS)

Here we go, (partial, for clarity) expansion leads to

在这里,我们去(部分,为清晰起见)扩展导致

struct/struct.o struct/carnet.o struct/ihm.o : struct/struct.c struct/carnet.c struct/ihm.c
    @echo $<
    $(CC) -c $< -o $@ $(FLAGS)

So you have a rule applied for building 3 targets, fine. Now, $< expands to the first prerequisite, which is struct/struct.c here.

所以你有一个规则申请建立3个目标,很好。现在,$ <扩展到第一个先决条件,这是struct struct.c。< p>

One possible (and common) solution if you use a make capable of it, e.g. GNU make, is to use pattern rules instead of this find-hack:

一种可能的(和常见的)解决方案,如果你使用具有它的make,例如GNU make,是使用模式规则而不是这个find-hack:

struct/%.o : struct/%.c
    @echo $<
    $(CC) -c $< -o $@ $(FLAGS)

Note that normally, you just maintain ONE list of the modules of your taget in your Makefile, usually the object files, manually, like here:

请注意,通常,您只需在Makefile中维护一个taget模块列表,通常是手动对象文件,如下所示:

OBJS:= struct/struct.o struct/carnet.o struct/ihm.o

#1


2  

SRC     = $(shell find struct/ -name "*.c")

You create a list here, $(SRC) will be struct/struct.c struct/carnet.c struct/ihm.c. Or any other order find may return, but according to your result, this seems to be the order.

你在这里创建一个列表,$(SRC)将是struct / struct.c struct / carnet.c struct / ihm.c。或者任何其他订单查找可能会返回,但根据您的结果,这似乎是顺序。

OBJ     = $(SRC:.c=.o)

This creates the modified list struct/struct.o struct/carnet.o struct/ihm.o

这将创建修改后的列表struct / struct.o struct / carnet.o struct / ihm.o

$(OBJ) : $(SRC)
    @echo $<
    $(CC) -c $< -o $@ $(FLAGS)

Here we go, (partial, for clarity) expansion leads to

在这里,我们去(部分,为清晰起见)扩展导致

struct/struct.o struct/carnet.o struct/ihm.o : struct/struct.c struct/carnet.c struct/ihm.c
    @echo $<
    $(CC) -c $< -o $@ $(FLAGS)

So you have a rule applied for building 3 targets, fine. Now, $< expands to the first prerequisite, which is struct/struct.c here.

所以你有一个规则申请建立3个目标,很好。现在,$ <扩展到第一个先决条件,这是struct struct.c。< p>

One possible (and common) solution if you use a make capable of it, e.g. GNU make, is to use pattern rules instead of this find-hack:

一种可能的(和常见的)解决方案,如果你使用具有它的make,例如GNU make,是使用模式规则而不是这个find-hack:

struct/%.o : struct/%.c
    @echo $<
    $(CC) -c $< -o $@ $(FLAGS)

Note that normally, you just maintain ONE list of the modules of your taget in your Makefile, usually the object files, manually, like here:

请注意,通常,您只需在Makefile中维护一个taget模块列表,通常是手动对象文件,如下所示:

OBJS:= struct/struct.o struct/carnet.o struct/ihm.o