Lỗi gcc makefile: Không có quy tắc nào để thực hiện mục tiêu


356

Tôi đang cố gắng sử dụng GCC (linux) với tệp tạo tệp để biên dịch dự án của tôi.

Tôi nhận được lỗi sau đây dường như không thể giải mã trong ngữ cảnh này:

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

Đây là tệp thực hiện:

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
Một ví dụ điển hình mà bạn 'làm cho' tệp nguồn 'không tồn tại' là bằng cách đặt lại biến VPATH hoặc SRC do nhầm lẫn khi bạn phải thêm vào nó. Tôi có nghĩa là usnig VPATH=thay vì VPATH+=. Điều này làm cho tệp Makefile không thể xem các tệp khi tệp thực sự ở đó.
Chân Kim

Câu trả lời:


425

Điều đó thường là do bạn không có vertex.cppsẵn tệp để tạo. Kiểm tra xem:

  • tập tin đó tồn tại
  • Bạn đang ở đúng thư mục khi bạn thực hiện.

Ngoài ra, tôi không có nhiều đề xuất khác. Có lẽ bạn có thể cho chúng tôi một danh sách thư mục của thư mục đó.


2
Có, Một số lớp của tôi không có tệp .cpp, vì vậy chúng không có ở đó - gây ra lỗi. Cảm ơn.
Meir

4
bạn cũng có thể gặp lỗi như vậy nếu có một số tệp tiêu đề bạn đã xóa nhưng vẫn còn trong Makefile của bạn
ady

@par, có vẻ như là một câu hỏi khác với tôi. Có lẽ bạn sẽ tiếp xúc nhiều hơn nếu bạn hỏi nó như một câu hỏi.
paxdiablo

Ngoài ra, hãy đảm bảo bạn lưu Makefile sau khi chỉnh sửa nó ... Đó là những gì đã giúp tôi. Tôi đã thực hiện tất cả các chỉnh sửa của mình sau đó quên nhấn CTRL + S
Tim

80

Theo kinh nghiệm của tôi, lỗi này thường xuyên do một lỗi chính tả .

Tôi đã nhận được lỗi này ngày hôm nay.

make [1]: *** Không có quy tắc nào để thực hiện mục tiêu maintenaceDialog.cpp', needed byduy trìDialog.o '. Dừng lại.

Trong trường hợp của tôi, lỗi chỉ đơn giản là một lỗi chính tả. Từ MAINTENANCE bị thiếu là chữ N thứ ba.

Ngoài ra kiểm tra chính tả trên tên tệp của bạn.


2
Các meta tại sao , trong trường hợp này là do liệt kê rõ ràng các mối quan hệ đối tượng / nguồn / tiêu đề. Nếu các công cụ mới hơn như SubCons hoặc CMake không được nếm thử, gcc -MT và gnu tạo ra các mẫu có thể giải quyết điều này. Xem cũng .
Nathan Kidd

Bạn đã cứu ngày của tôi! Cảm ơn bạn! :)
Sunit Gautam

Trong trường hợp của tôi, con đường đã sai như thế ../../src/file.cnhưng thực ra là vậy../../src/folder/file.c
Rasmi Ranjan Nayak

31

Lý do phổ biến hơn cho thông báo này được in là vì bạn quên bao gồm thư mục chứa tệp nguồn. Do đó, gcc "nghĩ" tệp này không tồn tại.

Bạn có thể thêm thư mục bằng cách sử dụng đối số -I cho gcc.


14

Trong trường hợp của tôi, tôi đã sử dụng dấu phẩy bằng xương làm dấu phân cách. Để sử dụng ví dụ của bạn, tôi đã làm điều này:

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

Thay đổi nó thành tương đương với

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

Đã sửa nó.


11

Có chính xác không? Hãy nhớ rằng cú pháp Makefile là khoảng trắng nhận biết và yêu cầu các tab để thụt lề các lệnh theo hành động.


7

Vấn đề tôi tìm thấy thậm chí còn khôn ngoan hơn những gì những người khác đã đề cập.

Makefiles của chúng tôi được thông qua danh sách những thứ để xây dựng. Ai đó đã thêm TheOtherLibraryvào một trong các danh sách, như hiển thị bên dưới.

LIBRARYDIRS = src/Library
LIBRARYDIRS = src/TheOtherLibrary

Họ nên làm điều này:

LIBRARYDIRS = src/Library
LIBRARYDIRS += src/TheOtherLibrary

Nếu họ thực hiện theo cách thứ hai, họ sẽ không xóa sổ bản Librarydựng. Điểm cộng +=là rất quan trọng.


6

Trong trường hợp của tôi, đó là do lỗi quy tắc nhiều dòng trong Makefile. Tôi đã có một cái gì đó như:

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

Dấu gạch chéo ngược ở cuối danh sách tệp trong CONFIG_OBJ1quy tắc của nguyên nhân gây ra lỗi này. Nó sẽ giống như:

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

5

Một trong những lỗi thường gặp có thể là lỗi đánh máy trong tên tệp khác .

Ví dụ của bạn khá đơn giản nhưng đôi khi có thể nhầm lẫn là các thông điệp của make chính nó. Hãy xem xét một ví dụ.

Nội dung thư mục của tôi là:

$ ls -1
another_file
index.md
makefile

Trong khi đó, makefilengoại hình của tôi

all: index.html

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

Mặc dù tôi có index.mdnơi cần phải có và không có lỗi trong tên của nó, thông điệp từ makesẽ là

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

Thành thật mà nói , thông điệp là khó hiểu . Nó chỉ nói rằng, không có quy tắc. Trong thực tế, điều đó có nghĩa là quy tắc sai, nhưng do quy tắc ký tự đại diện (mẫu)make không thể xác định chính xác nguyên nhân gây ra sự cố.

Hãy thay đổi makefilemột chút, nghĩa là thay thế các mẫu bằng các quy tắc rõ ràng:

index.html: index.md wrong_path_to_another_file

Và bây giờ thông điệp chúng tôi nhận được sẽ là:

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

Phép màu! Sau đây có thể được kết luận:

  • Thông điệp makephụ thuộc vào quy tắc và không phải lúc nào cũng chỉ ra gốc rễ của vấn đề

  • Có thể có những vấn đề khác trong bạn makefilekhác với thông báo của thông báo này

Bây giờ chúng tôi cũng nảy ra ý tưởng kiểm tra các phụ thuộc khác theo một quy tắc :

all: index.html

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

Chỉ điều này sẽ cung cấp cho chúng tôi kết quả mong muốn:

$ make
index.html index.md

3

Trong trường hợp của tôi, thông báo lỗi đề cập đến một tên tệp cũ, không còn tồn tại vì nó đã được đổi tên. Hóa ra thông tin lỗi thời không đến từ Makefile, mà từ các tệp trong .depsthư mục.

Tôi gặp phải lỗi này sau khi sao chép tệp từ máy này sang máy khác. Trong quá trình đó, tôi giả sử các dấu thời gian có trạng thái không nhất quán, điều này làm "nhầm lẫn" khi chạy nhiều công việc song song (tương tự như báo cáo lỗi này ).

Các bản dựng tuần tự make -j 1không bị ảnh hưởng, nhưng phải mất một thời gian tôi mới nhận ra vì tôi đang sử dụng một bí danh ( make -j 8).

Để dọn dẹp trạng thái, tôi xóa tất cả .depscác tệp và tạo lại Makefile. Đây là những lệnh mà tôi đã sử dụng:

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

Sau đó, tòa nhà hoạt động trở lại.


2

Nếu bạn đang cố gắng xây dựng John the Ripper "ble-jumbo" và gặp lỗi như "make: *** Không có quy tắc nào để tạo mục tiêu 'linux-x86-64'". Thay vào đó, hãy thử chạy lệnh này:./configure && make


0

Trong trường hợp của tôi, (và) tệp đối tượng cũ đã bị khóa (chỉ đọc) bởi một IDE bị lỗi bán hoặc từ một dịch vụ đám mây dự phòng đã ngừng hoạt động bình thường. Khởi động lại tất cả các chương trình và dịch vụ được liên kết với cấu trúc thư mục đã giải quyết vấn đề.


0

Một ví dụ khác về một vấn đề kỳ lạ và giải pháp của nó:

Điều này:

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

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

Nhưng nếu tôi loại bỏ Poco_LIBRARIESnó hoạt động:

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

Tôi đang sử dụng clang8 trên Mac và clang 3.9 trên Linux Vấn đề chỉ xảy ra trên Linux nhưng hoạt động trên Mac!

Tôi quên đề cập: Poco_LIBRARIESđã sai - nó không được đặt bởi cmake / find_package!


0

Trong trường hợp của tôi, đường dẫn không được đặt trong VPATH, sau khi thêm lỗi.


0

Có nhiều lý do cho lỗi này.

Một trong những lý do khiến tôi gặp phải lỗi này là trong khi xây dựng cho linux và windows.

Tôi có một tên tệp với mũ BaseClass.h SubClass.h Unix duy trì có quy ước về tên tệp phân biệt chữ hoa chữ thường và các cửa sổ không phân biệt chữ hoa chữ thường.

C ++ tại sao mọi người không sử dụng chữ hoa trong tên của tệp tiêu đề?

Hãy thử biên dịch bản dựng sạch bằng gmake clean nếu bạn đang sử dụng gmake

Một số trình soạn thảo văn bản có cài đặt mặc định để bỏ qua tên tệp phân biệt chữ hoa chữ thường. Điều này cũng có thể dẫn đến lỗi tương tự.

Làm cách nào để thêm tệp c ++ trong Qt Creator có tên bắt đầu bằng chữ in hoa? Nó tự động làm cho nó nhỏ chữ


0

Lỗi này xảy ra với tôi bên trong Travis khi tôi quên thêm tệp mới vào kho git của mình. Sai lầm ngớ ngẩn, nhưng tôi có thể thấy nó khá phổ biến.


-1

Trong trường hợp của tôi, đó là do tôi gọi Makefile: MAKEFILE (tất cả các chữ hoa)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.