จะใช้แฟล็ก -MG ใน cc 4.4.1 ได้อย่างไร

ฉันเพิ่งอัปเกรดการติดตั้ง Ubuntu จาก Jaunty เป็น Karmic เห็นได้ชัดว่ารวมถึงการอัปเดตคอมไพเลอร์ GNU C ด้วย เนื่องจากโค้ดที่คอมไพล์ก่อนหน้านี้ไม่มีอีกต่อไป

การรัน cc 4.4.1 (Ubuntu 4.4.1-4ubuntu8) ตอนนี้สร้างข้อผิดพลาดต่อไปนี้ในโค้ดที่ทำงานได้ดีใน cc 4.3.3 (Ubuntu 4.3.3-5ubuntu4):

$ make
cc -c -MMD -MG -MP -MF lex.d -g -Wall -O -o lex.o lex.c
cc1: error: -MG may only be used with -M or -MM

การเพิ่มแฟล็ก -M หรือ -MM ทำให้เกิดข้อความต่อไปนี้:

[...]
flex -o lex.c lex.l
cc -c -MM -MG -MP -MF lex.d -g -Wall -O -o lex.o lex.c
[...]
cc -g -Wall -O -o translate lex.o grammar.tab.o main.o list.o salloc.o suffixed.o expr.o emit.o optimize.o -lfl
lex.o: file not recognized: File truncated
collect2: ld returned 1 exit status
make: *** [translate] Error 1

ฉันได้รับแจ้งว่า -Mx บอกแฟล็ก make ว่าไฟล์ c ต่างๆ ขึ้นอยู่กับไฟล์ .h อย่างไร การแก้ไขที่ดีที่สุดของฉันจนถึงตอนนี้คือการบอก make อย่างชัดเจนว่าไฟล์ .c ทั้งหมดขึ้นอยู่กับไฟล์ .h ทั้งหมด เพื่อให้แน่ใจว่าทุกอย่างเป็นข้อมูลล่าสุด อย่างไรก็ตาม สิ่งนี้ทำให้เกิดงานที่ไม่จำเป็นจำนวนมากในขณะคอมไพล์

คำถามของฉันคือ: ฉันจะต้องปรับแฟล็กสำหรับ cc เพื่อให้จัดการการขึ้นต่อกันโดยอัตโนมัติอีกครั้งได้อย่างไร


person Evanesco    schedule 18.11.2009    source แหล่งที่มา
comment
ยินดีต้อนรับสู่ Super User! ดูเหมือนว่าคำถามนี้เกี่ยวข้องกับการพัฒนาซอฟต์แวร์ และด้วยเหตุนี้จึงอาจถูกย้ายไปยัง Stack Overflow เพียงเพื่อให้แน่ใจว่า: โปรดอย่าโพสต์คำถามเดียวกันบน Stack Overflow ด้วยตัวเองเช่นกัน คำถามนั้นจะถูกย้ายโดยอัตโนมัติหากจำเป็น หากมีการย้ายแล้ว ให้เข้าสู่ระบบ stackoverflow.com โดยใช้ OpenID เดียวกัน และเชื่อมโยงบัญชีของคุณที่ superuser.com/users/18508?tab=accounts ในขณะเดียวกัน อย่าลืมอ่านคำถามที่พบบ่อย! ความสำเร็จ. (และบางทีฉันอาจผิดและคุณจะเห็นคำตอบที่ดีที่ Super User ที่นี่!)   -  person Arjan    schedule 18.11.2009
comment
ฉันใส่ไว้ที่นี่เพราะมันเกี่ยวข้องกับการอัปเกรดจาก Jaunty เป็น Karmic แต่ในวินาทีนั้นคุณคิดถูก มันอาจจะเหมาะสมกว่าที่ Stack Overflow :)   -  person Evanesco    schedule 18.11.2009


คำตอบ (2)


วัตถุประสงค์ของสวิตช์ -MG คือเพื่อให้ตัวสร้างการพึ่งพาอัตโนมัติทำงานได้อย่างถูกต้องแม้ว่าจะยังไม่ได้สร้างไฟล์ส่วนหัวจริงก็ตาม อย่างไรก็ตาม เมื่อคุณพยายามคอมไพล์โค้ดจริงๆ สิ่งสำคัญคือต้องมีส่วนหัวอยู่ จึงจะสามารถเรียบเรียงได้

ด้วยเหตุนี้ -MG สามารถใช้ร่วมกับ -MM หรือ -M เท่านั้น ซึ่งทั้งสองอย่างนี้บ่งบอกถึงแฟล็ก -E ซึ่งหมายความว่าพวกเขาไม่ได้คอมไพล์โค้ดจริงๆ

ดังนั้นหากคุณต้องการใช้ -MG คุณจะต้องใช้คำสั่งแยกกันเพื่อสร้างการขึ้นต่อกันและการคอมไพล์ ตัวอย่างเช่น

cc -MM -MG -MP -MF lex.d lex.c
cc -c -g -Wall -O -o lex.o lex.c

หรือเขียนไฟล์ make ในลักษณะที่สร้างส่วนหัวก่อน เช่น

GENERATED=(list of headers that get created during the build process)

lex.o: lex.c | $(GENERATED)
    cc -c -MMD -MP -MF lex.d -g -Wall -O -o lex.o lex.c
##...
## individual build rules for generated headers.

โปรดทราบว่า '|' หมายความว่าต้องสร้าง lex.o ตามไฟล์ที่สร้างขึ้น แต่ไม่ได้ขึ้นอยู่กับไฟล์ที่สร้างขึ้นจริงๆ เช่น. มันจะถูกสร้างขึ้นหลังจากส่วนหัว แต่จะไม่ถูกสร้างขึ้นใหม่หากส่วนหัวเปลี่ยนแปลง เว้นแต่จะระบุไว้อย่างชัดเจน

person karadoc    schedule 30.05.2011

สวิตช์ -MMD ดูเหมือนจะเป็นปัญหา ลองเปลี่ยนเป็น -MM ซึ่งจะทำให้สวิตช์ -MG ทำงานได้ ตามเอกสาร GCC ที่ http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Preprocessor-Options.html, -MMD เหมือนกับ -MM ที่มีตัวเลือก -MF โดยนัย และเนื่องจากคุณได้ระบุไฟล์เอาต์พุตไว้แล้ว ด้วย -MF คุณควรใช้แบบฟอร์มที่เรียบง่ายกว่านี้ได้

person Ben Combee    schedule 20.11.2009
comment
ขอบคุณสำหรับข้อเสนอแนะของคุณ น่าเสียดายที่การแทนที่แฟล็ก -MMD ด้วย -MM ทำให้ไฟล์ข้อผิดพลาดไม่เป็นที่รู้จัก: ไฟล์ถูกตัดทอน :( ฉันได้อัปเดตคำถามพร้อมกับบริบทของข้อผิดพลาด บางทีข้อมูลนั้นอาจช่วยได้ - person Evanesco; 20.11.2009
comment
ปัญหาคือว่า -MM ใช้ในการคอมไพล์ผ่านครั้งแรกเพื่อสร้างการพึ่งพา ... โดยปกติแล้วคุณจะรัน gcc อีกครั้งเพื่อสร้างไฟล์อ็อบเจ็กต์จริงๆ การใช้ -MM กับ -o เป็นปัญหา เนื่องจากคุณกำลังเขียนข้อมูลการพึ่งพานั้นไปยังไฟล์ .o และทำให้คิดว่ามีการอัปเดตแล้ว แต่สิ่งที่คุณมีใน .o นั้นไม่ถูกต้อง - person Ben Combee; 21.11.2009