Makefile Make:使用所有对象文件的通配符

Makefile Make:使用所有对象文件的通配符,makefile,Makefile,我有一个Makefile,如下所示: CC=cc CFLAGS=-g -std=c99 -Wfatal-errors OBJS=$(wildcard *.o) all: main.o cmdargs.o io.o $(CC) -o app $(OBJS) main.o: main.c $(CC) -c main.c $(CFLAGS) cmdargs.o: cmdargs.c $(CC) -c cmdargs.c $(CFLAGS) io.o: io.c $(

我有一个Makefile,如下所示:

CC=cc
CFLAGS=-g -std=c99 -Wfatal-errors
OBJS=$(wildcard *.o)

all: main.o cmdargs.o io.o
    $(CC) -o app $(OBJS)

main.o: main.c
    $(CC) -c main.c $(CFLAGS)
cmdargs.o: cmdargs.c
    $(CC) -c cmdargs.c $(CFLAGS)
io.o: io.c
    $(CC) -c io.c $(CFLAGS)

clean:
    @rm -rf app $(OBJS)
每当我在清理后运行
makeall
时,都会出现一个错误

cc-o

对“main”的未定义引用

但当我第二次运行它时,一切都按预期运行。脚本有什么问题,我们如何修复它?

语句

收集文件系统中当前的所有
*.o
文件,但它不知道将来可能创建的任何对象文件

当您第一次运行
make
时,周围没有
.o
文件,因此变量
OBJS
将是一个空字符串,并且最终的链接命令不会传递到命令中,该命令将告诉您要使用哪些对象文件。但是,所有其他编译步骤都会运行。在第二次调用时,
make
将跳过编译阶段,因为目标文件已经存在,但由于链接失败且最终二进制文件丢失,它将运行该步骤,现在将生成一些内容,因为有一些文件要通过通配符收集


经验教训:不要在Makefile中使用文件系统通配符,这只会带来麻烦。如果您想让自己从工作中解脱出来,请学习隐式规则。

如果您小心地包含所有源文件,则可以自动创建对象文件的名称

# --------------------------------------
#  list all source files
CPP_SOURCES := $(wildcard *.cpp)
C_SOURCES   := $(wildcard *.c)
# other source files here

# consolidate all sources
SOURCES := $(CPP_SOURCES) $(C_SOURCES)


# --------------------------------------
# list all object files
CPP_OBJECTS := $(CPP_SOURCES:.cpp=.o)
C_OBJECTS   := $(C_SOURCES:.c=.o)
# other object files here

# consolidate all objects
OBJECTS := $(CPP_OBJECTS) $(C_OBJECTS)


all:
    echo $(SOURCES)
    echo $(OBJECTS)

PS:更紧凑的生成文件:

#  list all source files
SOURCES := $(wildcard *.cpp) $(wildcard *.c)

# determine all object files
OBJECTS := $(addsuffix .o, $(basename $(notdir $(SOURCES))))

all:
    echo $(SOURCES)
    echo $(OBJECTS)

之前的受访者给出了很好的答案,但不完整。所以,让我也发布一个

首先,在makefile中使用
通配符是个坏主意。最好不要偷懒,并明确列出您的文件

如果你一定是懒惰的,使用通配符的方法是,正如shawncorey所写的,将其用于源代码

此外,不要有虚假目标的配方,例如
all
。在您的示例中,
all
的配方将始终运行,这是低效的

CC := gcc

SRCS := $(wildcard *.c)
OBJS := $(SRCS:c=o)

.PHONY: all clean

all: app 

app: $(OBJS) Makefile
    $(CC) -o $@ $(OBJS)

$(OBJS): %.o: %.c Makefile
    $(CC) -c $< $(CFLAGS)

clean:
    @rm -rf app $(OBJS)
CC:=gcc
SRCS:=$(通配符*.c)
OBJS:=$(SRCS:c=o)
.骗子:都是干净的
全部:应用程序
app:$(OBJS)Makefile
$(CC)-o$@$(OBJS)
$(OBJS):%.o:%.c生成文件
$(CC)-c$<$(CFLAGS)
清洁:
@rm-rf应用程序$(OBJS)
CC := gcc

SRCS := $(wildcard *.c)
OBJS := $(SRCS:c=o)

.PHONY: all clean

all: app 

app: $(OBJS) Makefile
    $(CC) -o $@ $(OBJS)

$(OBJS): %.o: %.c Makefile
    $(CC) -c $< $(CFLAGS)

clean:
    @rm -rf app $(OBJS)