Makefile 如何在一个生成文件中包含多个生成?
我创建了一个makefile来编译hello.c,它如下所示:Makefile 如何在一个生成文件中包含多个生成?,makefile,cs50,Makefile,Cs50,我创建了一个makefile来编译hello.c,它如下所示: 1 #the compiler to use 2 CC = clang 3 4 #compiler flags: 5 # -g adds debugging information to the executable file 6 # -Wall turns on most, but not all, compiler warnings 7 CFLAGS = -g -Wa
1 #the compiler to use
2 CC = clang
3
4 #compiler flags:
5 # -g adds debugging information to the executable file
6 # -Wall turns on most, but not all, compiler warnings
7 CFLAGS = -g -Wall
8
9 #files to link:
10 LFLAGS = -lcs50
11
12 #the name to use for both the target source file and the output file:
13 TARGET = hello
14
15 all: $(TARGET)
16 $(TARGET): $(TARGET).c
17 $(CC) $(CFLAGS) -o $(TARGET) $(TARGET).c $(LFLAGS)
# The compiler to use
CC = clang
# Compiler flags:
# -g adds debugging information to the executable file
# -Wall turns on most, but not all, compiler warnings
CFLAGS = -g -Wall
# Files to link:
LFLAGS = -lcs50
# Find all the files ending with .c using the shell command
SOURCEFILES = $(shell find . -type f -name "*.c")
# Convert all of these files to have .o as their suffix with a substitution
OUTPUTFILES = ${SOURCEFILES:.c=.o}
# Our "PHONY" rules; all make targets correspond with a produced file
# (This is how it can be clever about knowing when it can skip rules
# if no files have changed. We never make a file called "all" or "clean"
# as these are rules for our convenience - aka PHONY rules.)
.PHONY: all clean
# Build all our output files (.o files)
all: ${OUTPUTFILES}
# Remove all our output files
clean:
rm -v ${OUTPUTFILES}
# The rule that tells us how to make a .o file from a .c file.
$.o: %.c
$(CC) $(CFLAGS) -o $@ $^ $(LFLAGS)
我还有另外两个程序名为:int.c和float.c,我希望将它们包含在目标中,但我得到了以下结果:
make: Circular hello <- hello dependency dropped.
make: Circular int <- hello dependency dropped.
make: Circular int <- int dependency dropped.
clang -g -Wall -o hello int float hello int float.c -lcs50
clang: error: no such file or directory: 'int'
clang: error: no such file or directory: 'float'
clang: error: no such file or directory: 'hello'
clang: error: no such file or directory: 'int'
make: *** [int] Error 1
make:Circular hello因此您的想法大致正确,但执行并不十分完美!关于可能出错的最大线索是输出中的以下行:
clang -g -Wall -o hello int float hello int float.c -lcs50
正如您所看到的,它只是在“hellointfloat”中被替换了两次,一次是在末尾添加了“.c”。那么我们能做些什么呢
虽然不太常见,但使用由空格分隔的变量列表(即TARGET=hello int float
)是有效的,并且您的规则(${TARGET}:…
)确实会对列表中的每个项计算一次。有很多方法可以将.c
后缀添加到列表中的每个项目(函数),但是我们可以用一种更“Make-y”的方式来完成
模式规则与自动变量
为了确定我们如何引用目标定义中的内容,您需要的是和。模式规则允许我们制定非常通用的规则,并遵循特定的模式,而自动变量允许我们在命令运行时引用部分规则定义
...
all: ${TARGETS}
%: %.c
$(CC) $(CFLAGS) -o $@ $^ $(LFLAGS)
我们在这里做了两件事,首先我们用%:%.c
替换了规则。也就是说,有一个具有某个名称的目标,它依赖于某个文件,该文件与末尾带有.c
的文件相同
其次,我们用自动变量替换make命令中对${TARGET}
的引用$@
指的是目标名称,$^
指的是依赖项列表(在本例中,只有一个)
一些进一步的改进
使用模式规则的一种稍微传统的方法是在输出上也有一个后缀:
TARGETS = hello.o int.o float.o
all: ${TARGETS}
%.o: %.c
$(CC) $(CFLAGS) -o $@ $^ $(LFLAGS)
但是,我们喜欢懒惰,因此我们可以通过我评论过的其他一些技巧进一步自动化此操作,生成一个类似以下内容的makefile:
1 #the compiler to use
2 CC = clang
3
4 #compiler flags:
5 # -g adds debugging information to the executable file
6 # -Wall turns on most, but not all, compiler warnings
7 CFLAGS = -g -Wall
8
9 #files to link:
10 LFLAGS = -lcs50
11
12 #the name to use for both the target source file and the output file:
13 TARGET = hello
14
15 all: $(TARGET)
16 $(TARGET): $(TARGET).c
17 $(CC) $(CFLAGS) -o $(TARGET) $(TARGET).c $(LFLAGS)
# The compiler to use
CC = clang
# Compiler flags:
# -g adds debugging information to the executable file
# -Wall turns on most, but not all, compiler warnings
CFLAGS = -g -Wall
# Files to link:
LFLAGS = -lcs50
# Find all the files ending with .c using the shell command
SOURCEFILES = $(shell find . -type f -name "*.c")
# Convert all of these files to have .o as their suffix with a substitution
OUTPUTFILES = ${SOURCEFILES:.c=.o}
# Our "PHONY" rules; all make targets correspond with a produced file
# (This is how it can be clever about knowing when it can skip rules
# if no files have changed. We never make a file called "all" or "clean"
# as these are rules for our convenience - aka PHONY rules.)
.PHONY: all clean
# Build all our output files (.o files)
all: ${OUTPUTFILES}
# Remove all our output files
clean:
rm -v ${OUTPUTFILES}
# The rule that tells us how to make a .o file from a .c file.
$.o: %.c
$(CC) $(CFLAGS) -o $@ $^ $(LFLAGS)
现在我们可以添加任何.c文件,它将使用您设置的选项进行编译!更改TARGET
变量现在已经成为过去 所以您的想法大致正确,但执行并不十分完美!关于可能出错的最大线索是输出中的以下行:
clang -g -Wall -o hello int float hello int float.c -lcs50
正如您所看到的,它只是在“hellointfloat”中被替换了两次,一次是在末尾添加了“.c”。那么我们能做些什么呢
虽然不太常见,但使用由空格分隔的变量列表(即TARGET=hello int float
)是有效的,并且您的规则(${TARGET}:…
)确实会对列表中的每个项计算一次。有很多方法可以将.c
后缀添加到列表中的每个项目(函数),但是我们可以用一种更“Make-y”的方式来完成
模式规则与自动变量
为了确定我们如何引用目标定义中的内容,您需要的是和。模式规则允许我们制定非常通用的规则,并遵循特定的模式,而自动变量允许我们在命令运行时引用部分规则定义
...
all: ${TARGETS}
%: %.c
$(CC) $(CFLAGS) -o $@ $^ $(LFLAGS)
我们在这里做了两件事,首先我们用%:%.c
替换了规则。也就是说,有一个具有某个名称的目标,它依赖于某个文件,该文件与末尾带有.c
的文件相同
其次,我们用自动变量替换make命令中对${TARGET}
的引用$@
指的是目标名称,$^
指的是依赖项列表(在本例中,只有一个)
一些进一步的改进
使用模式规则的一种稍微传统的方法是在输出上也有一个后缀:
TARGETS = hello.o int.o float.o
all: ${TARGETS}
%.o: %.c
$(CC) $(CFLAGS) -o $@ $^ $(LFLAGS)
但是,我们喜欢懒惰,因此我们可以通过我评论过的其他一些技巧进一步自动化此操作,生成一个类似以下内容的makefile:
1 #the compiler to use
2 CC = clang
3
4 #compiler flags:
5 # -g adds debugging information to the executable file
6 # -Wall turns on most, but not all, compiler warnings
7 CFLAGS = -g -Wall
8
9 #files to link:
10 LFLAGS = -lcs50
11
12 #the name to use for both the target source file and the output file:
13 TARGET = hello
14
15 all: $(TARGET)
16 $(TARGET): $(TARGET).c
17 $(CC) $(CFLAGS) -o $(TARGET) $(TARGET).c $(LFLAGS)
# The compiler to use
CC = clang
# Compiler flags:
# -g adds debugging information to the executable file
# -Wall turns on most, but not all, compiler warnings
CFLAGS = -g -Wall
# Files to link:
LFLAGS = -lcs50
# Find all the files ending with .c using the shell command
SOURCEFILES = $(shell find . -type f -name "*.c")
# Convert all of these files to have .o as their suffix with a substitution
OUTPUTFILES = ${SOURCEFILES:.c=.o}
# Our "PHONY" rules; all make targets correspond with a produced file
# (This is how it can be clever about knowing when it can skip rules
# if no files have changed. We never make a file called "all" or "clean"
# as these are rules for our convenience - aka PHONY rules.)
.PHONY: all clean
# Build all our output files (.o files)
all: ${OUTPUTFILES}
# Remove all our output files
clean:
rm -v ${OUTPUTFILES}
# The rule that tells us how to make a .o file from a .c file.
$.o: %.c
$(CC) $(CFLAGS) -o $@ $^ $(LFLAGS)
现在我们可以添加任何.c文件,它将使用您设置的选项进行编译!更改TARGET
变量现在已经成为过去 失败的Makefile
到底是什么样子的?失败的Makefile
到底是什么样子的?