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

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.


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.


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.


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.


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.


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.


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

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

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ł.


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


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.


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!


0

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


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ą


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.


-1

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.