ข้อผิดพลาด gcc makefile:“ ไม่มีกฎที่จะทำให้เป้าหมาย…”


356

ฉันพยายามใช้ GCC (linux) กับ makefile เพื่อรวบรวมโครงการของฉัน

ฉันได้รับข้อผิดพลาดต่อไปนี้ซึ่งดูเหมือนจะไม่สามารถถอดรหัสในบริบทนี้:

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

นี่คือ 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
ตัวอย่างทั่วไปที่คุณ 'ทำให้' ไฟล์ต้นฉบับ 'ไม่มีอยู่' คือการรีเซ็ต VPATH หรือตัวแปร SRC โดยไม่ได้ตั้งใจเมื่อคุณต้องเพิ่มมัน ผมหมายถึง usnig แทนVPATH= VPATH+=สิ่งนี้ทำให้ไฟล์ Makefile ไม่สามารถดูไฟล์เมื่อมีไฟล์จริง
Chan Kim

คำตอบ:


425

นั่นเป็นเพราะคุณไม่มีไฟล์ที่เรียกว่าvertex.cppพร้อมใช้งาน ตรวจสอบว่า:

  • มีไฟล์นั้นอยู่
  • คุณอยู่ในไดเรกทอรีที่ถูกต้องเมื่อคุณทำ

นอกจากนั้นฉันไม่ได้แนะนำอะไรมาก บางทีคุณอาจให้รายชื่อไดเรกทอรีของไดเรกทอรีนั้นกับเรา


2
ใช่บางคลาสของฉันไม่มีไฟล์. cpp ดังนั้นพวกเขาจึงไม่ได้ทำให้เกิดข้อผิดพลาด ขอบคุณ
เมียร์

4
คุณสามารถได้รับข้อผิดพลาดดังกล่าวหากมีไฟล์ส่วนหัวที่คุณลบออก แต่ยังอยู่ใน Makefile ของคุณ
ady

@par นั่นเป็นคำถามที่แตกต่างสำหรับฉัน คุณอาจได้รับการเปิดเผยมากขึ้นถ้าคุณถามว่าเป็นคำถาม
paxdiablo

นอกจากนี้ให้แน่ใจว่าคุณบันทึก Makefile ของคุณหลังจากแก้ไขมัน ... นั่นคือสิ่งที่ฉันได้รับ ฉันทำการแก้ไขทั้งหมดของฉันแล้วลืมกด CTRL + S
Tim

80

จากประสบการณ์ของฉันข้อผิดพลาดนี้มักเกิดจากข้อผิดพลาดในการสะกดคำ

ฉันได้รับข้อผิดพลาดนี้วันนี้

ทำให้ [1]: *** ไม่มีกฎที่จะทำให้เป้าหมายmaintenaceDialog.cpp', needed bymaintenaceDialog.o ' หยุด.

ในกรณีของฉันข้อผิดพลาดเป็นเพียงข้อผิดพลาดการสะกดคำ คำว่าการบำรุงรักษาหายไปมันเป็นที่สาม N.

ตรวจสอบการสะกดชื่อไฟล์ของคุณด้วย


2
เมตาทำไมในกรณีนี้เป็นเพราะการแสดงรายการความสัมพันธ์ของวัตถุ / แหล่งที่มา / ส่วนหัวอย่างชัดเจน หากเครื่องมือที่ใหม่กว่าเช่นSubConsหรือCMakeไม่ได้ลิ้มรสgcc -MT และ gnu สร้างรูปแบบสามารถแก้ปัญหานี้ได้ ดูยัง
นาธาน Kidd

คุณบันทึกวันของฉัน! ขอบคุณ! :)
Sunit Gautam

ในกรณีของฉันเส้นทางผิดปกติ../../src/file.cแต่จริงๆแล้วมันคือ../../src/folder/file.c
Rasmi Ranjan Nayak

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

ปัญหาที่ฉันพบคือยิ่งกว่าสิ่งที่คนอื่นพูดถึง

makefiles ของเราผ่านรายการสิ่งที่ต้องสร้าง มีคนเพิ่ม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ไดเรกทอรี

ฉันพบข้อผิดพลาดนี้หลังจากคัดลอกไฟล์จากเครื่องหนึ่งไปยังอีกเครื่องหนึ่ง ในกระบวนการนั้นฉันคิดว่าการประทับเวลาได้รับในสถานะที่ไม่สอดคล้องกันซึ่งทำให้ "สับสน" เมื่อทำงานหลายงานพร้อมกัน (เช่นรายงานข้อผิดพลาดนี้ )

Sequential สร้างด้วย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

หากคุณกำลังพยายามสร้าง John the Ripper "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 ยืนยันว่ามีการจัดการชื่อไฟล์ที่คำนึงถึงขนาดตัวพิมพ์และหน้าต่างไม่คำนึงถึงขนาดตัวพิมพ์

C ++ ทำไมคนไม่ใช้ตัวพิมพ์ใหญ่ในชื่อไฟล์ส่วนหัว?

ลองคอมไพล์ clean build โดยใช้ gmake clean หากคุณใช้ gmake

เครื่องมือแก้ไขข้อความบางตัวมีการตั้งค่าเริ่มต้นเพื่อเพิกเฉยต่อชื่อไฟล์ สิ่งนี้อาจนำไปสู่ข้อผิดพลาดเดียวกันได้

วิธีเพิ่มไฟล์ c ++ ใน Qt Creator ซึ่งชื่อขึ้นต้นด้วยตัวอักษรพิมพ์ใหญ่? มันทำให้มันเป็นอักษรตัวเล็กโดยอัตโนมัติ


0

ข้อผิดพลาดนี้เกิดขึ้นกับฉันใน Travis เมื่อฉันลืมเพิ่มไฟล์ใหม่ไปยังที่เก็บ git ของฉัน ความผิดพลาดโง่ ๆ แต่ฉันเห็นได้ว่ามันค่อนข้างธรรมดา


-1

ในกรณีของฉันมันเป็นเพราะฉันเรียก Makefile: MAKEFILE (ตัวพิมพ์ใหญ่ทั้งหมด)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.