Ошибка 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.