C makefile编译多个目标
这是我在这个论坛上的第一篇帖子。抱歉打扰了,我一直在找类似的东西,奇怪的是我找不到。问题就在这里。 我有三个没有标题的(主)文件,我想一次编译它们(如果我简单地键入“make”),或者逐个编译它们(如果我指定了没有扩展名的文件名)。因此,我构建了makefile,但命令中出现了一些错误C makefile编译多个目标,c,makefile,C,Makefile,这是我在这个论坛上的第一篇帖子。抱歉打扰了,我一直在找类似的东西,奇怪的是我找不到。问题就在这里。 我有三个没有标题的(主)文件,我想一次编译它们(如果我简单地键入“make”),或者逐个编译它们(如果我指定了没有扩展名的文件名)。因此,我构建了makefile,但命令中出现了一些错误 $(TARGETS): $(BUILDS_DIR)% : $(SRCS_DIR)%.c 我从哪里得到这个错误的 make:**无规则生成目标 这是完整的文件 .SUFFIXES: .c ROOT = $(add
$(TARGETS): $(BUILDS_DIR)% : $(SRCS_DIR)%.c
我从哪里得到这个错误的
make:**无规则生成目标
这是完整的文件
.SUFFIXES: .c
ROOT = $(addprefix $(PWD), /)
BUILDS_DIR = $(addprefix $(ROOT), builds/)
SRCS_DIR = $(addprefix $(ROOT), src/)
SRCS = $(wildcard $(SRCS_DIR)*.c)
TARGETS = ${SRCS:$(SRCS_DIR)%.c=%}
EXES = ${addprefix $(BUILDS_DIR), $(TARGETS)}
CC = gcc
CFLAGS = -Wall -O3
RM = rm -f
.PHONY: all $(TARGETS) clean
all: $(TARGETS)
$(TARGETS): $(BUILDS_DIR)% : $(SRCS_DIR)%.c
$(CC) $(CFLAGS) \
$< \
-o $@
@echo -e "\n\n\t\t*** Compile successfully! ***\n" ;
clean:
$(RM) $(EXES) \
$(SRCS_DIR)*~
@echo -e "\n\n\t\t*** Cleanup complete! ***\n"
。后缀:.c
根=$(addprefix$(PWD),/)
BUILDS\u DIR=$(addprefix$(ROOT),BUILDS/)
SRCS_DIR=$(addprefix$(根),src/)
SRCS=$(通配符$(SRCS_DIR)*.c)
TARGETS=${SRCS:$(SRCS_DIR)%.c=%}
EXES=${addprefix$(BUILDS\u DIR),$(TARGETS)}
CC=gcc
CFLAGS=-Wall-O3
RM=RM-f
.虚假:所有美元(目标)都是干净的
全部:$(目标)
$(目标):$(构建目录)%:$(SRCS目录)%
$(CC)$(CFLAGS)\
$< \
-o$@
@echo-e“\n\n\t\t***编译成功!***\n”;
清洁:
$(RM)$(前任)\
$(SRCS_目录)*~
@echo-e“\n\n\t\t***清理完成!***\n”
我错在哪里?我猜答案很愚蠢,可能是基于一个基本的错误
提前感谢假设GNU Make(因为您使用了它的语法)
第一个问题是,您试图将目标目录连接到模式,而不是简单地使用目标文件名,从而错误地重写目标
你有:
$(TARGETS): $(BUILDS_DIR)% : $(SRCS_DIR)%.c
$(CC) $(CFLAGS) $< -o $@
$(目标):$(构建目录)%:$(SRCS目录)%
$(CC)$(CFLAGS)$<-o$@
解决方案是使用在命令行上添加目录路径
$(TARGETS): % : $(SRCS_DIR)%.c
$(CC) $(CFLAGS) $< -o $(BUILDS_DIR)$@
$(目标):%:$(SRCS_DIR)%.c
$(CC)$(CFLAGS)$<-o$(构建目录)$@
假设您的三个源文件是file1.c
、file2.c
和file3.c
。我将创建如下所示的makefile(假设GNU make)
使用这个make文件的一个示例是(我使用-n来显示将运行哪些规则,但没有实际运行它们,因为我的源文件是用于测试的空文件。)
我们可以利用通配符缩短上述文件
CC=gcc
CFLAGS=-ansi-墙壁-迂腐
RM=RM-f
OBJS=file1.o file2.o file3.o
PROG=我的程序
$(进度):$(OBJS)
$(CC)$(CFLAGS)$(OBJS)-o$(PROG)
全部:清洁$(进度)
%:%c
$(CC)$(CFLAGS)-c$<-o$@.o
清洁:
$(RM)*.o$(PROG)~
我们需要在输出文件名后面附加一个“.o”,这样我们就可以按照第一个生成规则的$(OBJ)
变量所定义的格式创建文件。执行此操作将提供以下示例运行:
[******@broadsword junk]$ make -n
gcc -ansi -Wall -pedantic -c -o file1.o file1.c
gcc -ansi -Wall -pedantic -c -o file2.o file2.c
gcc -ansi -Wall -pedantic -c -o file3.o file3.c
gcc -ansi -Wall -pedantic file1.o file2.o file3.o -o my_program
[******@broadsword junk]$ make -n file2
gcc -ansi -Wall -pedantic -c file2.c -o file2.o
顺便说一句,我个人不介意多输入两个字符,我喜欢让我的目标与运行的规则集的输出相匹配,所以我会将规则编写为
file1.o : file1.c
$(CC) $(CFLAGS) -c file1.c -o file1.o
或
%.o:%.c
$(CC)$(CFLAGS)-c$<-o$@
最后,我强烈怀疑,当我们执行
make
或make all
时,我们并没有运行makefile下半部分的文件特定规则,而是运行GNU手册中描述的内置规则:“n.o是从n.c自动生成的,其格式为$(CC)$(CPPFLAGS)$(CFLAGS)-c
“无规则设定目标
。。。什么?完全错误是什么?运行make-d…
,这将显示make
正在做什么。您正在使用哪个make
?它可以在大多数/所有GNU/Linux系统上找到,或者从中的一个或第三方端口make
?GNU make有时被称为gmake
NetBSD make有时被称为或作为一个包提供,称为。注意,cmake是一个不同的构建系统。我认为addprefix
和wildcard
是GNU Make-specific,而后缀
是相当古老的样式,应该是不必要的。后缀行始终需要是一个列表,包含所有将要使用的后缀。一般来说,最好不要在make文件中放入.后缀语句,除非在非常特殊的情况下。然后将使用默认列表。我看不到在make文件中包含文件或库的引用。这让我想知道,当这些文件没有I/O、没有数学、什么都没有的时候,它们能做些什么。非常感谢!!实际上,通过这种修正,它可以完美地工作!谢谢,这也行,但我的想法是跳过对象文件,因为我以后不需要链接任何东西。但应用经典方法可能更清晰、更简单。谢谢!不建议使用您的示例生成文件。除了不必要的复杂之外,它还不如内置的标准功能强大。最后,让all
依赖于clear
目标是不正常的。它违背了只重新编译已更改内容的make
的目的。@mctylr,在您放入pastebin的内容中,为什么要使用all目标?您拥有无规则的all:$(PROG)
,然后下一个目标行是$(PROG):$(OBJS)
,其中包含用于构建程序的规则。因此,执行make asmake
,我们得到trigger all目标,它反过来触发$(PROG)
目标。删除“all”目标并将“$(PROG)”目标作为makefile中的第一个目标似乎更简单。此外,对我来说,makeall
命令意味着重新编译所有内容,而不仅仅是最近更改的内容,因此对clean的依赖性。对于只有一个可执行文件的小项目来说,这是不必要的。您可以在GNU Make命令行中使用多个目标,例如,makecleanlall
来干净地重建所有内容。或者创建一个cleanbuild
或rebuild
目标来执行相同的操作<代码>清除构建:清除所有。
[******@broadsword junk]$ make -n
gcc -ansi -Wall -pedantic -c -o file1.o file1.c
gcc -ansi -Wall -pedantic -c -o file2.o file2.c
gcc -ansi -Wall -pedantic -c -o file3.o file3.c
gcc -ansi -Wall -pedantic file1.o file2.o file3.o -o my_program
[******@broadsword junk]$ make -n file2
gcc -ansi -Wall -pedantic -c file2.c -o file2.o
file1.o : file1.c
$(CC) $(CFLAGS) -c file1.c -o file1.o
%.o :%.c
$(CC) $(CFLAGS) -c $< -o $@