有如下程序:
mypro 目录里包含 一个 main 目录和一个 include 目录,main 目录里有一个 主函数 main.c,include 目录里有一个头文件 myinclude.h
myinclude.h 里内容如下:
#ifndef __MYINCLUDE_H__
#define __MYINCLUDE_H__
define N 5
#endif
main.c 里内容如下:
#inlcude <stdio.h>
#include "myinclude.h"
int main(void)
{
int i;
i = N;
printf("i = %d\n", i);
return 0;
}
有以下几种情况:
1、在 main 目录下新建一个 Makefile,内容如下:
test: main.o
gcc $< -o $@
%.o: %.c
gcc -c -I ../include $< -o $@
执行情况:正常执行
2、在 mypro 目录下新建一个 Makefile,内容如下:
test: ./main/main.o
gcc $< -o $@
./main/%.o: ./main/%.c
gcc -c -I ./include $< -o $@
执行情况:正常执行
3、把上面的 Makefile 稍微修改一下:
执行情况:错误
4、在 mypro 目录下新建一个 Makefile,内容如下:
test: ./main/main.o
gcc $< -o $@
./main/%.o: %.c
gcc -c -I ./include $< -o $@
执行情况:错误
如果把头文件拷贝到 main 目录下后,当 mypro 下的 Makefile 为以下时:
5、
执行结果:通过,但是为什么不执行设定的语句,而是执行了默认的:cc -c -o main.o main.c
6、
执行结果:通过,但是为什么不执行设定的语句,而是执行了默认的cc -c -o main.o main.c
7、
执行结果:通过,执行了设定的语句
8、
执行结果:通过,只执行了默认的cc -c -o main.o main.c
疑问:为什么写成 ./main/%.o: ./main/%.c 会有两套智能选择标准,而写成 ./main/%.o: %.c 就不行了呢?
原因:是
1、gcc 执行 test: ./main/main.o 时会先从下面找有没有指令能生成我要的 main.o 文件
2、当发现有一条 ./main/%.o 这段代码有可能会生成我所要的 main.o,那么就会到下面查看依赖文件
3、当发现 %.c 时,这下面语句有可能会生成 main.o(如果出现一条 gcc -c -$^ -o ./main/main.o 这不就生成想要的目标文件了吗?),gcc 就会看下面的语句,结果发现根本不可能生成main.o 的可能性(因为根据依赖语句 gcc -c -I ./include $^ -o %@ 只有 main.c 才会生成 main.o,当然目录 mypro 下没有文件也属于不能生成 main.o 的),于是 gcc 就忽略了当前代码(不会去执行)
4、既然后面没有可能生成我所需要的 main.o 的代码,那么我就自己推导看有没有可能成功,于是就开始默认的自动推导
cc -c -o ./main/main.o ./main/main.c
当发现 main.c 需要的 myinclude.h 文件找不到时就报错了,这就是上面 4 出错的原因,当发现能成功的时候他就自动执行了,这就是其他中成功的原因
5、至于最后一种成功的原因,同样如此,即便我 ./main 下有我想要的 main.c ,但是 ./main/main.o 的依赖文件却变成了两个,可是我找不到第二个文件,这条语句执行不下去了,于是就 pass ,直接走的步骤 4
6、./main/%.o: %.c 实际上是在目录 mypro 下寻找,而 ./main/%.o: ./main/%.c 是在目录 ./main/ 下寻找。