Makefile目标文件生成、变量替换等问题
Makefile object file generation, variable substitution, and other questions
我目前正在尝试为一个 c 大学项目创建一个 Makefile,但是通读教程对我没有太大帮助(另外,makefile 不是评估过程的一部分,我们也没有被教导如何去做)
我的 objective 正在使 makefile 自动生成,因此它会自动从 src (src/*.c) 中的 .c 文件创建目标文件,将目标文件放入 bin 文件夹中,并将它们链接到主目录中的可执行文件。
project/
bin/
(object files)
src/
(source files)
executable
Makefile
到目前为止,我已经大致将这个 makefile 和测试源代码放在一起,但它并没有按照我想要的方式工作,我将在前面解释它是如何工作的:
#compiler used
COMPILER = gcc
#flags for individual object file compilation
FLAGS = -Wall -ansi -g
#RELEASE
# -Wall -ansi -O3
#DEVELOPMENT
# -Wall -ansi -g
#source .c files
SOURCE = $(wildcard src/*.c)
#object files created
OBJECTS = $(SOURCE:.c=.o)
OBJECTS = $(SOURCE: src/=bin/)
#executable name
EXECUTABLE = app
############################################################
all: $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(COMPILER) $(FLAGS) -o $(EXECUTABLE) $(OBJECTS)
%.o: %.c
$(COMPILER) $(FLAGS) -c %< -o %@
结果是以下命令:
user@user-lenovo:~/Desktop/C Projects/AED/project$ make
gcc -Wall -ansi -g -o app src/main.c src/test.c
具有讽刺意味的是,它有效,但实际上不应该。它也违背了拥有 makefile 的目的,因为一旦检测到一个更改,所有内容都会重新编译。
首先,我注意到的是OBJECTS直接复制了SOURCE,并没有用.c替换.o,或者用src/替换bin/。我试过用“=”代替“:=”,但结果是一样的,我一开始不太明白它们之间的区别。例如,我的想法是 src/main.c 变成 bin/main.o。
%.o: %.c
$(COMPILER) $(FLAGS) -c %< -o %@
这部分也是我尝试用一个目标单独生成所有目标文件的失败尝试。我尝试阅读它,但无法弄清楚它们是如何工作的:“%<”、“%@”或“%.o”和“%.c”
我相信它根本不是 运行,因为没有出现任何目标文件。
我希望你能帮我解决这个问题,提前致谢!
- 与任何其他变量一样,自动变量使用
$
前缀扩展,而不是 %
。
- 由于您的目标文件和源文件位于不同的目录中,因此您不能简单地
%.o: %.c
.
尝试:
CC = gcc
CFLAGS = -Wall -ansi -g
OBJECTS = $(patsubst src/%.c,bin/%.o,$(SOURCE))
bin/%.o: src/%.c
$(CC) $(CFLAGS) -c $< -o $@
注意:C 编译器的标准 make 变量是 CC
和 CFLAGS
标志。还是用它们比较好。
OBJECTS = $(SOURCE:.c=.o)
OBJECTS = $(SOURCE: src/=bin/)
您在那里向 OBJECTS
分配了两次 - 第一个结果被第二个结果覆盖,这不起作用。你想像这样将它们组合成一个语句
OBJECTS=$(SOURCE:src/%.c=bin/%.o)
你的下一个问题是你需要告诉 make
"bin/whatever.o" 是从 "src/whatever.c" 构建的。目前它会在 "bin/"
中寻找 "whatever.c"
因此您构建 .o 文件的方法需要添加目录
bin/%.o: src/%.c
$(COMPILER) $(FLAGS) -c $< -o $@
您还应该使用 $@
而不是 %@
和 $<
而不是 %<
我目前正在尝试为一个 c 大学项目创建一个 Makefile,但是通读教程对我没有太大帮助(另外,makefile 不是评估过程的一部分,我们也没有被教导如何去做)
我的 objective 正在使 makefile 自动生成,因此它会自动从 src (src/*.c) 中的 .c 文件创建目标文件,将目标文件放入 bin 文件夹中,并将它们链接到主目录中的可执行文件。
project/
bin/
(object files)
src/
(source files)
executable
Makefile
到目前为止,我已经大致将这个 makefile 和测试源代码放在一起,但它并没有按照我想要的方式工作,我将在前面解释它是如何工作的:
#compiler used
COMPILER = gcc
#flags for individual object file compilation
FLAGS = -Wall -ansi -g
#RELEASE
# -Wall -ansi -O3
#DEVELOPMENT
# -Wall -ansi -g
#source .c files
SOURCE = $(wildcard src/*.c)
#object files created
OBJECTS = $(SOURCE:.c=.o)
OBJECTS = $(SOURCE: src/=bin/)
#executable name
EXECUTABLE = app
############################################################
all: $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(COMPILER) $(FLAGS) -o $(EXECUTABLE) $(OBJECTS)
%.o: %.c
$(COMPILER) $(FLAGS) -c %< -o %@
结果是以下命令:
user@user-lenovo:~/Desktop/C Projects/AED/project$ make
gcc -Wall -ansi -g -o app src/main.c src/test.c
具有讽刺意味的是,它有效,但实际上不应该。它也违背了拥有 makefile 的目的,因为一旦检测到一个更改,所有内容都会重新编译。
首先,我注意到的是OBJECTS直接复制了SOURCE,并没有用.c替换.o,或者用src/替换bin/。我试过用“=”代替“:=”,但结果是一样的,我一开始不太明白它们之间的区别。例如,我的想法是 src/main.c 变成 bin/main.o。
%.o: %.c
$(COMPILER) $(FLAGS) -c %< -o %@
这部分也是我尝试用一个目标单独生成所有目标文件的失败尝试。我尝试阅读它,但无法弄清楚它们是如何工作的:“%<”、“%@”或“%.o”和“%.c”
我相信它根本不是 运行,因为没有出现任何目标文件。
我希望你能帮我解决这个问题,提前致谢!
- 与任何其他变量一样,自动变量使用
$
前缀扩展,而不是%
。 - 由于您的目标文件和源文件位于不同的目录中,因此您不能简单地
%.o: %.c
.
尝试:
CC = gcc
CFLAGS = -Wall -ansi -g
OBJECTS = $(patsubst src/%.c,bin/%.o,$(SOURCE))
bin/%.o: src/%.c
$(CC) $(CFLAGS) -c $< -o $@
注意:C 编译器的标准 make 变量是 CC
和 CFLAGS
标志。还是用它们比较好。
OBJECTS = $(SOURCE:.c=.o)
OBJECTS = $(SOURCE: src/=bin/)
您在那里向 OBJECTS
分配了两次 - 第一个结果被第二个结果覆盖,这不起作用。你想像这样将它们组合成一个语句
OBJECTS=$(SOURCE:src/%.c=bin/%.o)
你的下一个问题是你需要告诉 make
"bin/whatever.o" 是从 "src/whatever.c" 构建的。目前它会在 "bin/"
因此您构建 .o 文件的方法需要添加目录
bin/%.o: src/%.c
$(COMPILER) $(FLAGS) -c $< -o $@
您还应该使用 $@
而不是 %@
和 $<
而不是 %<