Makefile在子文件夹中找不到文件

时间:2018-11-27 23:23:31

标签: c gcc makefile gnu-make

我正在尝试使用C为我的项目编写Makefile。
我的.c文件位于src子文件夹中,
.o子文件夹中的build个文件,
.h子文件夹中的src/header个文件
 和.c个文件,用于在tests子文件夹中进行测试。

在我的Makefile中,我正在使用vpath:

 vpath %.c src:tests
 vpath %.h src/header
 vpath %.o build

当我想编译file1时,Makefile不会在子文件夹中找到file1.c并将目标文件编译为子文件夹build/file1.o时没有问题。但是,当将file1编译为可执行文件时,Makefile找不到file1.o

这是我在Makefile中针对特定文件的代码:

test_file1: test_file1.o file.o
    $(CC) $^ -o tests/$@

test_file1.o: test_file1.c file1.h  
    $(CC) $(CFLAGS) -c $< -o build/$@

file1.o: file1.c file1.h file2.h file3.h
    $(CC) $(CFLAGS) -c $< -o build/$@

test_file1.o我得到:
gcc -std=c99 -Wall -Wextra -pedantic -g -c tests/test_file1.c -o build/test_file1.o没有问题。

file1.o我得到:
gcc -std=c99 -Wall -Wextra -pedantic -g -c src/file1.c -o build/file1.o也没有问题。

但是从test_file1我得到的文件没有子文件夹的路径:
gcc test_file1.o file1.o -o tests/test_file1

并得到此错误:
gcc: error: test_file1.o: No such file or directory gcc: error: file1.o: No such file or directory gcc: fatal error: no input files

两个文件都位于子文件夹build中。
哪里有问题?

1 个答案:

答案 0 :(得分:2)

问题在于您的某些规则实际上并未建立他们声称要建立的规则,违反了Mad Scientist's Second Law of Makefiles

Make看到它必须构建file1.o。该文件一开始就不存在,并且 vpath无法找到尚不存在的文件。因此,Make寻找一条规则并找到了它:

file1.o: file1.c file1.h file2.h file3.h
    $(CC) $(CFLAGS) -c $< -o build/$@

此规则的目标是file1.o。 Make假设它将构建file1.o,执行它,然后尝试在另一个配方中使用file1.o,但由于file1.o仍然不存在而失败。

该规则实际上建立了build/file1.o。不,Make不够聪明,无法从食谱中推断出这一事实。

解决方案:更改规则。

build/file1.o: file1.c file1.h file2.h file3.h
    $(CC) $(CFLAGS) -c $< -o $@

类似:

build/test_file1.o: test_file1.c file1.h  
    $(CC) $(CFLAGS) -c $< -o $@