Błąd makefile gcc: „Brak reguły określającej cel…”

355

Próbuję użyć GCC (linux) z makefile do skompilowania mojego projektu.

Pojawia się następujący błąd, którego nie można odczytać w tym kontekście:

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

To jest plik makefile:

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
Meir
źródło
2
Typowym przykładem „spowodowania”, że plik źródłowy „nie istnieje” jest przez przypadkowe zresetowanie zmiennej VPATH lub SRC, gdy trzeba ją dodać. Mam na myśli usnig VPATH=zamiast VPATH+=. To sprawia, że ​​plik Makefile nie widzi plików, gdy plik faktycznie tam jest.
Chan Kim

Odpowiedzi:

424

Dzieje się tak zwykle dlatego, że nie masz vertex.cppdostępnego pliku o nazwie . Sprawdź to:

  • ten plik istnieje.
  • kiedy robisz, jesteś we właściwym katalogu.

Poza tym nie mam wiele innych sugestii. Być może mógłbyś podać nam katalog tego katalogu.

paxdiablo
źródło
2
Tak, niektóre z moich klas nie mają plików .cpp, więc nie były przyczyną błędu. Dzięki.
Meir
4
możesz również otrzymać taki błąd, jeśli niektóre pliki nagłówków zostały usunięte, ale nadal znajdują się w pliku Makefile
ady
@par, to dla mnie wygląda na inne pytanie. Prawdopodobnie dostaniesz więcej ekspozycji, jeśli zadasz to pytanie.
paxdiablo
Pamiętaj też, aby zapisać plik Makefile po edycji ... Właśnie to mnie dostało. Zrobiłem wszystkie moje zmiany, a następnie zapomniałem nacisnąć CTRL + S
Tim
80

Z mojego doświadczenia wynika, że ​​ten błąd jest często spowodowany błędem w pisowni .

Mam ten błąd dzisiaj.

make [1]: *** Brak reguły, która spowoduje, że docelowy maintenaceDialog.cpp', needed bykeepenaceDialog.o '. Zatrzymać.

W moim przypadku błąd był po prostu błędem pisowni. Brakowało słowa KONSERWACJA, jest to trzecie N.

Sprawdź także pisownię w swoich nazwach plików.

Wes
źródło
2
Meta dlaczego w tym przypadku wynika z jawnej listy relacji obiekt / źródło / nagłówek. Jeśli nowsze narzędzia, takie jak SubCons lub CMake, nie mają smaku, gcc -MT a gnu tworzy wzory, może to rozwiązać. Zobacz także .
Nathan Kidd
Uratowałeś mi dzień! Dziękuję Ci! :)
Sunit Gautam
W moim przypadku ścieżka była błędna, ../../src/file.cale tak naprawdę była../../src/folder/file.c
Rasmi Ranjan Nayak
31

Najczęstszym powodem drukowania tego komunikatu jest to, że zapomniałeś dołączyć katalog, w którym znajduje się plik źródłowy. W rezultacie gcc „myśli”, że ten plik nie istnieje.

Możesz dodać katalog za pomocą argumentu -I do gcc.


źródło
14

W moim przypadku bezmyślnie użyłem przecinków jako separatorów. Aby skorzystać z twojego przykładu, zrobiłem to:

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

Zmiana na odpowiednik

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

naprawione.

Nick Knowlson
źródło
11

Czy to dokładnie to? Pamiętaj, że składnia Makefile rozpoznaje białe znaki i wymaga wciskania tabulatorów do wcięcia poleceń w akcjach.

workmad3
źródło
7

Problem, który znalazłem, był jeszcze głupszy niż to, o czym wspominali inni ludzie.

Nasze makefile otrzymują listę rzeczy do zbudowania. Ktoś dodał TheOtherLibrarydo jednej z list, jak pokazano poniżej.

LIBRARYDIRS = src/Library
LIBRARYDIRS = src/TheOtherLibrary

Powinni byli to zrobić:

LIBRARYDIRS = src/Library
LIBRARYDIRS += src/TheOtherLibrary

Gdyby zrobili to w drugą stronę, nie zniszczyliby Librarykompilacji. Plus w +=jest bardzo ważny.

kmort
źródło
6

W moim przypadku było to spowodowane błędem reguły wieloliniowej w pliku Makefile. Miałem coś takiego:

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

Ukośnik odwrotny na końcu listy plików w CONFIG_OBJ1regule spowodował ten błąd. Powinno być jak:

OBJS-$(CONFIG_OBJ1)            += file1.o file2.o \
                                  file3.o file4.o
OBJS-$(CONFIG_OBJ2)            += file5.o
...
uluorta
źródło
5

Jednym z częstych błędów może być literówka w innej nazwie pliku .

Twój przykład jest dość prosty, ale czasem mylące są makesame wiadomości . Rozważmy przykład.

Zawartość mojego folderu to:

$ ls -1
another_file
index.md
makefile

Podczas gdy mój makefilewygląda

all: index.html

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

Chociaż mam to, index.mdgdzie powinno być i nie ma pomyłki w jego nazwie, wiadomość od makebędzie

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

Szczerze mówiąc, wiadomość jest myląca . Mówi tylko, że nie ma reguły. W rzeczywistości oznacza to, że reguła jest nieprawidłowa, ale z powodu symboli wieloznacznych (wzorców) reguły makenie mogą określić, co dokładnie spowodowało problem.

Zmieńmy makefiletrochę, co oznacza zastąpienie wzorców wyraźnymi regułami:

index.html: index.md wrong_path_to_another_file

A teraz otrzymamy wiadomość:

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

Cud! Można wyciągnąć następujące wnioski:

  • Wiadomości makezależą od reguł i nie zawsze wskazują na źródło problemów

  • Mogą występować inne problemy makefileniż określone w tym komunikacie

Teraz wpadliśmy na pomysł sprawdzenia innych zależności w regule :

all: index.html

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

Tylko to zapewni nam pożądany rezultat:

$ make
index.html index.md
Nick Roz
źródło
3

W moim przypadku komunikat o błędzie odwoływał się do starej nazwy pliku, która już nie istniała, ponieważ zmieniono jej nazwę. Okazało się, że nieaktualne informacje nie pochodziły z Makefile, ale z plików w .depskatalogach.

Wystąpił ten błąd po skopiowaniu plików z jednego komputera na inny. W tym procesie zakładam, że znaczniki czasu uzyskały niespójny stan, co pomieszało „make” podczas uruchamiania wielu zadań równolegle (podobnie do tego raportu o błędzie ).

make -j 1Nie wpłynęło to na kompilacje sekwencyjne , ale zajęło mi to trochę czasu, ponieważ użyłem aliasu ( make -j 8).

Aby wyczyścić stan, usunąłem wszystkie .depspliki i ponownie wygenerowałem plik Makefile. Oto polecenia, których użyłem:

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

Następnie budynek znów działał.

Philipp Claßen
źródło
2

Jeśli próbujesz zbudować John the Ripper „bleeding-jumbo” i otrzymujesz błąd taki jak „make: *** Brak reguły, aby cel„ linux-x86-64 ””. Zamiast tego spróbuj uruchomić to polecenie:./configure && make

Ogglas
źródło
0

W moim przypadku źródłowy i / lub stary plik (i) obiektu zostały zablokowane (tylko do odczytu) przez częściowo zawieszone IDE lub z usługi kopii zapasowej w chmurze, która przestała działać poprawnie. Ponowne uruchomienie wszystkich programów i usług powiązanych ze strukturą folderów rozwiązało problem.

sskoog
źródło
0

Kolejny przykład dziwnego problemu i jego rozwiązanie:

To:

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

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

Ale jeśli Poco_LIBRARIESgo usunę , działa:

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

Używam clang8 na Macu i clang 3.9 na Linuxie Problem występuje tylko w systemie Linux, ale działa na komputerze Mac!

Zapomniałem wspomnieć: Poco_LIBRARIESbyło źle - nie zostało ustawione przez cmake / find_package!

Mike Mitterer
źródło
0

W moim przypadku ścieżka nie jest ustawiona w VPATH, po dodaniu zniknął błąd.

tzuhsun
źródło
0

Istnieje wiele przyczyn tego błędu.

Jednym z powodów, dla których napotkałem ten błąd, jest budowanie systemu Linux i Windows.

Mam nazwę pliku z dużymi literami BaseClass.h SubClass.h Unix utrzymuje konwencję rozróżniania wielkości liter w nazwach plików, a Windows nie rozróżnia wielkości liter.

C ++ dlaczego ludzie nie używają wielkich liter w nazwach plików nagłówkowych?

Spróbuj skompilować clean build przy użyciu gmake clean, jeśli używasz gmake

Niektóre edytory tekstu mają ustawienia domyślne, aby ignorować nazwy plików, w których rozróżniana jest wielkość liter. Może to również prowadzić do tego samego błędu.

jak dodać plik c ++ w Qt Creator, którego nazwa zaczyna się od wielkich liter? Automatycznie czyni to małą literą

Corning
źródło
0

Ten błąd wystąpił dla mnie w Travis, gdy zapomniałem dodać nowe pliki do mojego repozytorium git. Głupia pomyłka, ale widzę, że jest to dość powszechne.

Ryan Deschamps
źródło
-1

W moim przypadku było to spowodowane tym, że zadzwoniłem do Makefile: MAKEFILE (wszystkie wielkie litery)

ninjaPixel
źródło