Makefile не может найти файлы в подпапках - PullRequest
0 голосов
/ 28 ноября 2018

Я пытаюсь написать Makefile для моего проекта в C.
У меня есть .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/$@

From 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 голосов
/ 28 ноября 2018

Беда в том, что некоторые из ваших правил на самом деле не строят то, что, как они утверждают, строят, нарушая Второй закон создания файлов безумного ученого .

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 $@
...