Ошибка make-файла gcc: «Нет правила для создания цели…»


356

Я пытаюсь использовать GCC (Linux) с make-файлом для компиляции моего проекта.

Я получаю следующую ошибку, которая не может расшифровать в этом контексте:

"No rule to make target 'vertex.cpp', needed by 'vertex.o'.  Stop."

Это make-файл:

a.out: vertex.o edge.o elist.o main.o vlist.o enode.o vnode.o
    g++ vertex.o edge.o elist.o main.o vlist.o enode.o vnode.o

main.o: main.cpp main.h
    g++ -c main.cpp

vertex.o: vertex.cpp vertex.h
    g++ -c vertex.cpp

edge.o: edge.cpp edge.h
    g++ -c num.cpp

vlist.o: vlist.cpp vlist.h
    g++ -c vlist.cpp

elist.o: elist.cpp elist.h
    g++ -c elist.cpp

vnode.o: vnode.cpp vnode.h
    g++ -c vnode.cpp

enode.o: enode.cpp enode.h
    g++ -c node.cpp

2
Типичный пример, которым вы «делаете» исходный файл «не существующим», - это сброс переменной VPATH или SRC по ошибке, когда вам нужно добавить к ней. Я имею в виду usnig VPATH=вместо VPATH+=. Это делает Makefile файл не может видеть файлы, когда файл на самом деле там.
— Чан Ким

Ответы:


425

Обычно это потому, что у вас нет файла, который vertex.cppможно сделать доступным. Проверь это:

  • этот файл существует.
  • вы находитесь в правильном каталоге, когда вы делаете.

Кроме этого, я не могу больше предложить. Возможно, вы могли бы дать нам список каталогов этого каталога.


2
Да, у некоторых из моих классов нет файлов .cpp, поэтому их там не было, что вызвало ошибку. Спасибо.
— Меир

4
Вы также можете получить такую ​​ошибку, если есть некоторые заголовочные файлы, которые вы удалили, но все еще есть в вашем Makefile
— ady

@par, это похоже на другой вопрос для меня. Вы, вероятно, получите больше информации, если зададите вопрос.
— paxdiablo

Кроме того, убедитесь, что вы сохранили свой Makefile после его редактирования ... Это то, что досталось мне. Я сделал все свои правки, затем забыл нажать CTRL + S
— Тим

80

По моему опыту, эта ошибка часто вызвана орфографической ошибкой.

Я получил эту ошибку сегодня.

make [1]: *** Нет правила для создания цели maintenaceDialog.cpp', needed by maintenaceDialog.o '. Стоп.

В моем случае ошибка была просто орфографической ошибкой. Слово ТЕХНИЧЕСКОЕ ОБСЛУЖИВАНИЕ отсутствовало, это третий Н.

Также проверьте правильность написания ваших имен файлов.


2
Мета почему в этом случае из-за явного перечисления отношений объект / источник / заголовок. Если новые инструменты, такие как SubCons или CMake , не нужны, gcc -MT и gnu make pattern может решить эту проблему. См также .
— Натан Кидд

Ты спас мой день! Спасибо! :)
— Сунит Гаутам

В моем случае путь был неправильным, ../../src/file.cно на самом деле это было../../src/folder/file.c
— Расми Ранджан Наяк

31

Более распространенная причина для печати этого сообщения заключается в том, что вы забыли включить каталог, в котором находится исходный файл. В результате gcc «думает», что этот файл не существует.

Вы можете добавить каталог, используя аргумент -I для gcc.


14

В моем случае я использовал запятые в качестве разделителей. Чтобы использовать ваш пример, я сделал это:

a.out: vertex.o, edge.o, elist.o, main.o, vlist.o, enode.o, vnode.o
    g++ vertex.o edge.o elist.o main.o vlist.o enode.o vnode.o

Меняя его на эквивалент

a.out: vertex.o edge.o elist.o main.o vlist.o enode.o vnode.o
    g++ vertex.o edge.o elist.o main.o vlist.o enode.o vnode.o

починил это.


11

Это точно? Помните, что синтаксис Makefile учитывает пробелы и требует вкладок для отступа команд под действиями.


7

Проблема, которую я обнаружил, была еще глупее, чем то, о чем говорили другие.

Наши make-файлы получают списки объектов для сборки. Кто-то добавил TheOtherLibraryв один из списков, как показано ниже.

LIBRARYDIRS = src/Library
LIBRARYDIRS = src/TheOtherLibrary

Они должны были сделать это:

LIBRARYDIRS = src/Library
LIBRARYDIRS += src/TheOtherLibrary

Если бы они сделали это вторым способом, они бы не уничтожили Libraryсборку. Плюс в +=это очень важно.


6

В моем случае это было связано с ошибкой многострочного правила в Makefile. У меня было что-то вроде:

OBJS-$(CONFIG_OBJ1)            += file1.o file2.o \
                                  file3.o file4.o \
OBJS-$(CONFIG_OBJ2)            += file5.o 
OBJS-$(CONFIG_OBJ3)            += file6.o
...

Обратная косая черта в конце списка файлов в CONFIG_OBJ1правиле вызвала эту ошибку. Это должно быть как:

OBJS-$(CONFIG_OBJ1)            += file1.o file2.o \
                                  file3.o file4.o
OBJS-$(CONFIG_OBJ2)            += file5.o
...

5

Одной из частых ошибок может быть опечатка в другом имени файла .

Ваш пример довольно прост, но то, что иногда может сбивать с толку, - это сообщения о makeсебе. Давайте рассмотрим пример.

Содержимое моей папки:

$ ls -1
another_file
index.md
makefile

В то время как мой makefileвыглядит

all: index.html

%.html: %.md wrong_path_to_another_file
    @echo $@ $<

Хотя у меня есть , index.mdгде она должна быть , и нет никакой ошибки в названии этого, сообщение от makeбудет

make: *** No rule to make target `index.html', needed by `all'.  Stop.

Если честно, сообщение сбивает с толку . Это просто говорит, что нет правила. На самом деле это означает, что правило неверно, но из-за правил подстановочных знаков (шаблонов)make невозможно определить, что именно вызвало проблему.

Давайте makefileнемного изменим , то есть заменим шаблоны явными правилами:

index.html: index.md wrong_path_to_another_file

И теперь мы получим сообщение:

make: *** No rule to make target `wrong_path_to_another_file', needed by `index.html'.  Stop.

Чудо! Можно сделать следующие выводы:

  • Сообщения makeзависят от правил и не всегда указывают на корень проблем

  • Могут быть и другие проблемы, makefileотличные от указанных в этом сообщении.

Теперь у нас есть идея проверить и другие зависимости в правиле :

all: index.html

%.html: %.md another_file
    @echo $@ $<

Только это даст нам желаемый результат:

$ make
index.html index.md

3

В моем случае сообщение об ошибке ссылается на старое имя файла, которого больше не существует, поскольку оно было переименовано. Оказалось, что устаревшая информация пришла не из Makefile, а из файлов в .depsкаталогах.

Я столкнулся с этой ошибкой после копирования файлов с одного компьютера на другой. В этом процессе я предполагаю, что временные метки оказались в несогласованном состоянии, что приводило в замешательство «make» при параллельном запуске нескольких заданий (аналогично этому отчету об ошибке ).

Последовательные сборки с make -j 1не были затронуты, но мне потребовалось время, чтобы понять, потому что я использовал псевдоним ( make -j 8).

Чтобы очистить состояние, я удалил все .depsфайлы и восстановил Makefile. Это команды, которые я использовал:

find | grep '.deps' | xargs rm
find | grep '.deps' | xargs rmdir
autoreconf --install # (optional, but my project is using autotools) 
./configure

После этого здание снова заработало.


2

Если вы пытаетесь собрать Джона Потрошителя "bleeding-jumbo" и получить сообщение об ошибке "make: *** Нет правила для создания цели 'linux-x86-64'". Попробуйте выполнить эту команду вместо:./configure && make


0

В моем случае исходный и / или старый объектный файл (ы) были заблокированы (только для чтения) в полуразрушенной IDE или из облачной службы резервного копирования, которая перестала работать должным образом. Перезапуск всех программ и служб, связанных со структурой папок, решил проблему.


0

Еще один пример странной проблемы и ее решения:

Эта:

target_link_libraries(
    ${PROJECT_NAME}
    ${Poco_LIBRARIES}
    ${Poco_Foundation_LIBRARY}
    ${Poco_Net_LIBRARY}
    ${Poco_Util_LIBRARY}
    )

дает: make[3]: *** No rule to make target '/usr/lib/libPocoFoundationd.so', needed by '../hello_poco/bin/mac/HelloPoco'. Stop.

Но если я удаляю Poco_LIBRARIESэто работает:

target_link_libraries(
    ${PROJECT_NAME}
    ${Poco_Foundation_LIBRARY}
    ${Poco_Net_LIBRARY}
    ${Poco_Util_LIBRARY}
    )

Я использую clang8 на Mac и clang 3.9 на Linux Проблема возникает только в Linux, но работает на Mac!

Я забыл упомянуть: Poco_LIBRARIESбыл неправ - он не был установлен cmake / find_package!


0

В моем случае путь не задан в VPATH, после того, как добавлена ​​ошибка, исчезла.


0

Есть несколько причин этой ошибки.

Одна из причин, по которой я столкнулся с этой ошибкой, - сборка для Linux и Windows.

У меня есть имя файла с заглавными буквами BaseClass.h SubClass.h, который поддерживает Unix, имеет соглашение о именовании файлов с учетом регистра, а в Windows регистр не учитывается.

C ++, почему люди не используют прописные буквы в именах заголовочных файлов?

Попробуйте скомпилировать чистую сборку с помощью gmake clean, если вы используете gmake

Некоторые текстовые редакторы имеют настройки по умолчанию для игнорирования имен файлов с учетом регистра. Это также может привести к той же ошибке.

как добавить файл C ++ в Qt Creator, имя которого начинается с заглавных букв? Это автоматически делает его маленькой буквой


0

Эта ошибка произошла для меня в Travis, когда я забыл добавить новые файлы в мой репозиторий git. Глупая ошибка, но я вижу это довольно часто.


-1

В моем случае это произошло из-за того, что я вызвал Makefile: MAKEFILE (все заглавные буквы)

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.