我的工作目录如下所示:
我的生成文件如下所示:
CC := gcc
CFLAGS := -std=gnu99 -g -Wall -Wextra -Ic-timer-lib
TARGET := output
output: main.o my_memmove.o timer.o
$(CC) $(CFLAGS) main.o my_memmove.o timer.o -o $(TARGET)
main.o: main.c
gcc -c main.c
my_memmove.o: my_memmove.c my_memmove.h
gcc -c my_memmove.c
timer.o: c-timer-lib/timer.c c-timer-lib/timer.h
gcc -c c-timer-lib/timer.c -o $@
clean:
rm *.o $(TARGET)
我不明白为什么我一直收到“Makefile: No rule to make target 'timer.c', required by 'timer.o'. Stop。”错误。我相信是因为找不到timer.c和timer.h文件。
答案 0 :(得分:1)
这里太混乱了! :)
首先,这绝对是错误的:
$(CC) $(CFLAGS) -I main.o ...
-I main.o
告诉编译器它应该使用 main.o
作为目录名来搜索包含文件。那显然行不通。您应该删除此处的 -I
。
关于您的问题:您必须意识到这里有两个完全不同的程序在起作用:make
计算出如何运行命令,以及正在运行的命令,在这种情况下是编译器 { {1}}。
gcc
选项是 编译器 的一个选项,这样编译器就知道在哪里可以使用 -I
查找源代码中包含的头文件。>
那个选项没有任何意义;它不理解那个选项。它只是传递给编译器的一些文本。 Make 正在寻找源文件 #include
但它找不到它,因为你没有告诉 make 它在哪里。
您必须编写规则才能查看正确的位置,如下所示:
timer.c
(您应该始终使用 timer.o: c-timer-lib/timer.c c-timer-lib/timer.h
gcc -c c-timer-lib/timer.c -o $@
以便您的编译行将输出文件放在 make 期望找到它的位置,它会在评估您的配方之前由 make 放入 -o $@
变量中。)
预计到达时间
另外,您确定 $@
是正确的吗?如果不查看源代码中如何使用 -DUNITS="ms"
,我们就无法判断,但我怀疑您可能需要在这里使用额外的引号,例如 UNITS
真的,你在这个 makefile 中尝试做的太多了。 Make 已经知道如何从源文件正确构建目标文件。如果您不通过编写自己的规则来强迫问题,那么 make 的内置规则将为您完成这项工作。你的 makefile 可以这样写:
-DUNITS='"ms"'
make 不知道您的源需要哪些标头,因此您必须手动添加先决条件,尽管您可以添加额外的规则以使其自行解决。