มีวิธีสำหรับ gcc / g ++ เพื่อถ่ายโอนข้อมูลตัวประมวลผลล่วงหน้าที่กำหนดจากบรรทัดคำสั่งหรือไม่? ผมหมายถึงสิ่งที่ชอบ__GNUC__
, __STDC__
และอื่น ๆ
มีวิธีสำหรับ gcc / g ++ เพื่อถ่ายโอนข้อมูลตัวประมวลผลล่วงหน้าที่กำหนดจากบรรทัดคำสั่งหรือไม่? ผมหมายถึงสิ่งที่ชอบ__GNUC__
, __STDC__
และอื่น ๆ
คำตอบ:
ใช่ใช้-E -dM
ตัวเลือกแทน -c ตัวอย่าง (ส่งออกไปยัง stdout):
gcc -dM -E - < /dev/null
สำหรับ C ++
g++ -dM -E -x c++ - < /dev/null
จากคู่มือ gcc :
แทนที่จะสร้างเอาต์พุตปกติให้สร้างรายการคำสั่ง `#define 'สำหรับมาโครทั้งหมดที่กำหนดในระหว่างการเรียกใช้งานโปรเซสเซอร์ล่วงหน้ารวมถึงมาโครที่กำหนดไว้ล่วงหน้า วิธีนี้ช่วยให้คุณสามารถค้นหาสิ่งที่กำหนดไว้ล่วงหน้าในเวอร์ชันของตัวประมวลผลล่วงหน้าของคุณ สมมติว่าคุณไม่มีไฟล์ foo.h คำสั่ง
touch foo.h; cpp -dM foo.h
จะแสดงมาโครที่กำหนดไว้ล่วงหน้าทั้งหมด
หากคุณใช้ -dM โดยไม่มีตัวเลือก -E ระบบจะตีความ -dM เป็นคำพ้องสำหรับ -fdump-rtl-mach
echo | gcc -dM -E -
ทำงานบน windows เช่นกัน
cpp -dM -E - < NUL
สามารถใช้บน Windows ได้
ฉันมักจะทำเช่นนี้:
$ gcc -dM -E - < /dev/null
โปรดทราบว่าการกำหนดพรีโปรเซสเซอร์บางตัวนั้นขึ้นอยู่กับตัวเลือกบรรทัดคำสั่ง - คุณสามารถทดสอบสิ่งเหล่านี้ได้โดยการเพิ่มตัวเลือกที่เกี่ยวข้องเข้ากับบรรทัดคำสั่งด้านบน ตัวอย่างเช่นเพื่อดูว่าตัวเลือก SSE3 / SSE4 ใดที่เปิดใช้งานโดยค่าเริ่มต้น:
$ gcc -dM -E - < /dev/null | grep SSE[34]
#define __SSE3__ 1
#define __SSSE3__ 1
แล้วเปรียบเทียบสิ่งนี้เมื่อ-msse4
มีการระบุ:
$ gcc -dM -E -msse4 - < /dev/null | grep SSE[34]
#define __SSE3__ 1
#define __SSE4_1__ 1
#define __SSE4_2__ 1
#define __SSSE3__ 1
ในทำนองเดียวกันคุณสามารถดูว่าตัวเลือกใดที่แตกต่างกันระหว่างชุดตัวเลือกบรรทัดคำสั่งที่ต่างกันสองชุดเช่นเปรียบเทียบตัวประมวลผลล่วงหน้ากำหนดระดับการปรับให้เหมาะสม-O0
(ไม่มี) และ-O3
(เต็ม):
$ gcc -dM -E -O0 - < /dev/null > /tmp/O0.txt
$ gcc -dM -E -O3 - < /dev/null > /tmp/O3.txt
$ sdiff -s /tmp/O0.txt /tmp/O3.txt
#define __NO_INLINE__ 1 <
> #define __OPTIMIZE__ 1
ตอบล่าช้า - ฉันพบคำตอบอื่น ๆ ที่เป็นประโยชน์ - และต้องการเพิ่มอีกเล็กน้อย
ฉันจะถ่ายทำมาโครตัวประมวลผลล่วงหน้าที่มาจากไฟล์ส่วนหัวได้อย่างไร
echo "#include <sys/socket.h>" | gcc -E -dM -
หรือ (ขอบคุณ @mymedia สำหรับคำแนะนำ):
gcc -E -dM -include sys/socket.h - < /dev/null
โดยเฉพาะอย่างยิ่งฉันต้องการที่จะเห็นสิ่งที่ SOMAXCONN ถูกกำหนดไว้ในระบบของฉัน ฉันรู้ว่าฉันสามารถเปิดไฟล์ส่วนหัวมาตรฐานได้ แต่บางครั้งฉันต้องค้นหาข้อมูลเล็กน้อยเพื่อค้นหาตำแหน่งไฟล์ส่วนหัว แต่ฉันสามารถใช้สายการบินเดียวนี้แทน:
$ gcc -E -dM -include sys/socket.h - < /dev/null | grep SOMAXCONN
#define SOMAXCONN 128
$
วิธีการง่าย ๆ ( gcc -dM -E - < /dev/null
) ทำงานได้ดีสำหรับ gcc แต่ล้มเหลวสำหรับ g ++ เมื่อเร็ว ๆ นี้ฉันต้องการการทดสอบสำหรับคุณลักษณะ C ++ 11 / C ++ 14 คำแนะนำสำหรับชื่อแมโครที่สอดคล้องกันของพวกเขามีการเผยแพร่ที่https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations แต่:
g++ -dM -E - < /dev/null | fgrep __cpp_alias_templates
มักจะล้มเหลวเพราะมันเงียบ ๆเรียก C-ไดรเวอร์ (เช่นถ้าเรียกโดยgcc
) คุณสามารถดูสิ่งนี้ได้โดยการเปรียบเทียบเอาต์พุตกับ gcc หรือโดยการเพิ่มตัวเลือกบรรทัดคำสั่งเฉพาะ g ++ เช่น (-std = c ++ 11) ซึ่งส่งข้อความข้อผิดพลาดcc1: warning: command line option ‘-std=c++11’ is valid for C++/ObjC++ but not for C
ซึ่งส่งเสียงเกิดข้อผิดพลาด
เนื่องจาก (ไม่ใช่ C ++) gcc จะไม่สนับสนุน "Templates Aliases" (ดูhttp://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf ) คุณต้องเพิ่ม-x c++
ตัวเลือกในการ บังคับให้เรียกใช้คอมไพเลอร์ C ++ (เครดิตสำหรับการใช้-x c++
ตัวเลือกแทนไฟล์ดัมมี่ที่ว่างเปล่าไปที่หยูเฉาดูด้านล่าง):
g++ -dM -E -x c++ /dev/null | fgrep __cpp_alias_templates
จะไม่มีเอาต์พุตเนื่องจาก g ++ (แก้ไข 4.9.1 ค่าเริ่มต้นที่ -std = gnu ++ 98) ไม่ได้เปิดใช้งานคุณลักษณะ C ++ 11 ตามค่าเริ่มต้น ในการทำเช่นนั้นให้ใช้
g++ -dM -E -x c++ -std=c++11 /dev/null | fgrep __cpp_alias_templates
ซึ่งในที่สุดก็ให้ผลตอบแทน
#define __cpp_alias_templates 200704
สังเกตว่ากรัม ++ 4.9.1 ไม่สนับสนุน "แม่นามแฝง" -std=c++11
เมื่อเรียกด้วย
-x
โต้แย้งดังนั้นg++ -x c++ -dM -E -std=c++11 - < /dev/null | grep cpp
ควรใช้งานได้
วิธีการพกพาที่ทำงานได้ดีบน Linux หรือ Windows (ในกรณีที่ไม่มี / dev / null):
echo | gcc -dM -E -
สำหรับ c ++ คุณสามารถใช้ (แทนที่c++11
ด้วยเวอร์ชันที่คุณใช้):
echo | gcc -x c++ -std=c++11 -dM -E -
มันทำงานโดยบอก gcc เพื่อ preprocess stdin (ซึ่งผลิตโดย echo) และพิมพ์กำหนด preprocessor ทั้งหมด (ค้นหา-dletters
) หากคุณต้องการทราบว่ามีการเพิ่มคำนิยามใดบ้างเมื่อคุณรวมไฟล์ส่วนหัวคุณสามารถใช้-dD
ตัวเลือกที่คล้ายกับ -dM แต่ไม่รวมมาโครที่กำหนดไว้ล่วงหน้า:
echo "#include <stdlib.h>" | gcc -x c++ -std=c++11 -dD -E -
หมายเหตุอย่างไรก็ตามอินพุตว่างนั้นยังคงสร้าง-dD
ตัวเลือกจำนวนมากด้วย
NUL
คุณจะกลับไปที่รูปสี่เหลี่ยมจัตุรัส: มันจะไม่ทำงานบนระบบที่ไม่มี
sort
จะทำงานแตกต่างกันเล็กน้อย):echo | gcc -x c++ -std=c++17 -dM -E - | sort
ในขณะที่ทำงานในโครงการขนาดใหญ่ที่มีระบบการสร้างที่ซับซ้อนและเป็นเรื่องยากที่จะได้รับ (หรือแก้ไข) คำสั่ง gcc / g ++ โดยตรงมีวิธีอื่นในการดูผลลัพธ์ของการขยายแมโคร เพียงแค่กำหนดแมโครใหม่แล้วคุณจะได้ผลลัพธ์คล้ายกับการแสดงผลต่อไปนี้:
file.h: note: this is the location of the previous definition
#define MACRO current_value