这是一个示例程序,使它更容易解释。有这4个文件,main.c,sum.c和header.h。最后是Makefile。
main.c
#include <stdio.h>
#include "header.h"
int main()
{
int a = 1;
int b = 1;
int c = sum(a, b);
printf("Sum: %i\n",c);
return (0);
}
sum.c
#include "header.h"
int sum(int a, int b)
{
return (a + b);
}
header.h
int sum(int a, int b);
生成文件
TEST_SRCS = *.c
TEST_OBJS = $(TEST_SRCS:%.c=%.o)
%.o : %.c *.h
gcc -c $^
assemble_test: $(TEST_OBJS);
test: assemble_test
gcc -o test *.o
./test
clean:
@rm -rf *.o *.gch test
@echo "Cleaned"
重现步骤:
- 呼叫测试规则:使测试〉全部正常。
- 故意引入任何错误,例如两个逗号:
printf("Sum: %i\n",,c);
- 呼叫测试规则:make test〉获取常规语法错误。
- 删 debugging 误。保存文件。
- 呼叫测试规则:make test〉无论如何都会得到链接器错误。
gcc -o test *.o
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [test] Error 1
- 每次使用清理规则重新启动。
有这样的行为一段时间了,我想不出问题所在。老实说,我是makefiles的新手,所以我一定是做错了什么。
关于调用assemble_test的测试规则。这是因为一个更大的Makefile的一部分,我需要不同的规则用于不同的目的来编译对象,所以不要介意。
你能帮我搞清楚到底是怎么回事吗?
谢谢。
1条答案
按热度按时间but5z9lq1#
在目标文件中使用通配符是错误的,通配符匹配的是
make
运行时磁盘上 * 已经存在 * 的文件,这没有帮助,因为它们显然不会匹配 * 还不存在 * 的文件,而makefile的全部意义就是创建不存在的文件。所以这个:
将
TEST_SRCS
的值保留为字符串*.c
,将TEST_OBJS
的值保留为字符串*.o
(也许您认为通配符会立即扩展,但不,事实并非如此)。然后这一行:
使目标
assemble_test
将*.o
列为先决条件:这将扩展到目录 * 中已经存在的所有目标文件。当然,它不会扩展到您希望make创建但还不存在的目标文件。这里还有很多其他的问题:例如,你不想编译
$^
,因为它扩展到了 * 所有 * 先决条件,但你只想编译源文件,而不是头文件。假设您使用的是GNU make,您可能需要这样的代码:
通过使用
wildcard
函数,您可以在将结果替换为.o
之前扩展sources glob first 的值。