จะระบุแพลตฟอร์ม / คอมไพเลอร์จากมาโครตัวประมวลผลล่วงหน้าได้อย่างไร


115

ฉันกำลังเขียนโค้ดข้ามแพลตฟอร์มซึ่งควรรวบรวมที่ linux, windows, Mac OS บน windows ฉันต้องรองรับ visual studio และ mingw

มีโค้ดเฉพาะแพลตฟอร์มบางส่วนซึ่งฉันควรวางไว้ใน#ifdef .. #endifสภาพแวดล้อม ตัวอย่างเช่นที่นี่ฉันวางรหัสเฉพาะของ win32:

#ifdef WIN32
#include <windows.h>
#endif

แต่ฉันจะรู้จัก linux และ mac OS ได้อย่างไร ฉันควรใช้ชื่ออะไร (หรืออื่น ๆ )


3
นี่คือOS แมโครกำหนดรายการ
OCaml

คนหลอกลวงมีคำตอบที่ยอมรับได้ดีกว่ามาก
rubenvb

1
คำซ้ำที่แนะนำไม่ใช่คำถามเดียวกัน คำถามนั้นถามเฉพาะเกี่ยวกับการระบุระบบปฏิบัติการในขณะที่คำถามนี้ยังถามเกี่ยวกับการระบุคอมไพเลอร์ซึ่งเป็นสิ่งที่แตกต่างกันมาก
JBentley

@JBentley แต่คำตอบที่ได้รับการยอมรับไม่ได้กล่าวถึงคอมไพเลอร์และพูดถึงระบบปฏิบัติการเท่านั้น (และ "แพลตฟอร์ม" เดียว) ไม่ต้องพูดถึงมันเป็นคำตอบที่แย่มากเมื่อเทียบกับสิ่งที่คนหลอกลวงมีให้
rubenvb

1
@rubenvb จากนั้นเชื่อมโยงคำถามอื่นเป็นความคิดเห็น เพียงเพราะมีคำตอบที่ดีกว่าไม่ทำให้ซ้ำกัน คำถามคือสิ่งที่กำหนดว่ามันซ้ำกันไม่ใช่คำตอบ การปิดคำตอบนี้เท่านั้นทำให้มั่นใจได้ว่าเราจะไม่ได้รับคำตอบที่มีคุณภาพสำหรับส่วนที่เกี่ยวข้องกับคอมไพเลอร์ของคำถามซึ่งสิ่งที่เรียกว่า "ซ้ำ" ไม่สามารถตอบได้
JBentley

คำตอบ:


133

สำหรับMac OS :

#ifdef __APPLE__

สำหรับMingWบน Windows:

#ifdef __MINGW32__

สำหรับLinux :

#ifdef __linux__

สำหรับคอมไพเลอร์ Windows อื่น ๆ ให้ตรวจสอบเธรดนี้และสิ่งนี้สำหรับคอมไพเลอร์และสถาปัตยกรรมอื่น ๆ


2
ไม่__APPLE__แยกแยะระหว่าง OSX และ iOS?
gman

14
__APPLE__ถูกตั้งค่าสำหรับทั้ง OS X และ iOS คุณสามารถ#include <TargetConditionals.h>เข้าไปข้างใน#ifdef __APPLE__ซึ่งจะให้ไฟล์TARGET_OS_IPHONE #define.
Ted Mielczarek

2
__MINGW64__นอกจากนี้ยังสามารถใช้ได้เมื่อใช้ mingw64
scones

2
เนื่องจาก__MINGW64__มีการอ้างอิงคิดว่า_MSC_VERสำหรับ Windows / MSVC นั้นคุ้มค่าที่จะกล่าวถึง (ซึ่งสามารถใช้ตรวจสอบเวอร์ชัน MSVC ได้ด้วย)
ideasman42

ฉันขอโทษ แต่คำตอบนี้ไม่ถูกต้องในทุกบัญชีและไม่ได้ตอบคำถามด้วยซ้ำ
rubenvb

59

ดู: http://predef.sourceforge.net/index.php

โปรเจ็กต์นี้จัดเตรียมรายการที่กำหนดไว้ล่วงหน้า#definesสำหรับระบบปฏิบัติการคอมไพเลอร์มาตรฐานภาษาและแพลตฟอร์มและไลบรารีมาตรฐานที่ครอบคลุมอย่างสมเหตุสมผล


5
ในเวอร์ชัน 1.55 Predef รวมอยู่ในไลบรารี Boost C ++แล้ว
rvalue

ฉันรู้ว่ากฎแตกต่างกันเมื่อคุณโพสต์สิ่งนี้ แต่ฉันจะต้องขอให้คุณแก้ไขโพสต์นี้เพื่อให้มีรายละเอียดที่เกี่ยวข้องมากขึ้น ไม่แนะนำให้ใช้ a days link เฉพาะคำตอบและฉันต้องการให้คุณมีโอกาสบันทึกโพสต์นี้ก่อนที่จะนำออก
Mick MacCallum

1
เนื่องจากนี่เป็นคำตอบเดียวที่ตอบคำถามได้จริงตามที่ระบุไว้ในชื่อเรื่องและคำถามเป็นเรื่องทั่วไปและเกี่ยวข้องมากฉันขอแนะนำอย่างยิ่งให้ลบออก ฉันจะไม่เรียกมันว่า "ลิงก์เท่านั้น" อย่างใดอย่างหนึ่ง
ฮ็อบบ์

2
@ 0x7fffffff: จะมีประโยชน์อะไรกับทุกคนในการทำซ้ำเนื้อหาของคำตอบอื่น ๆ ในคำตอบนี้ หากคุณเชื่อว่าการมีคำตอบที่ชัดเจนเพียงคำเดียวนั้นสำคัญมากบางทีคุณควรสร้างคำตอบดังกล่าวด้วยตัวเอง (ไม่ควรยาก: เพียงแค่รวมคำตอบที่มีอยู่เข้าด้วยกันตามลำดับที่สมเหตุสมผล) โดยส่วนตัวแล้วฉันมีสิ่งที่ดีกว่าต้องทำกับเวลาของฉัน แต่ในฐานะผู้ดูแลเห็นได้ชัดว่า SO สำคัญสำหรับคุณมากกว่าสำหรับฉัน
John Bartholomew

47

นี่คือสิ่งที่ฉันใช้:

#ifdef _WIN32 // note the underscore: without it, it's not msdn official!
    // Windows (x64 and x86)
#elif __unix__ // all unices, not all compilers
    // Unix
#elif __linux__
    // linux
#elif __APPLE__
    // Mac OS, not sure if this is covered by __posix__ and/or __unix__ though...
#endif

แก้ไข:แม้ว่าการทำงานอาจข้างต้นสำหรับพื้นฐานที่จำได้ว่าในการตรวจสอบสิ่งที่คุณต้องการแมโครเพื่อตรวจสอบโดยดูที่หน้าอ้างอิง Boost.Predef หรือใช้ Boost.Predef โดยตรง


4
ใช้ __linux __ แทน linux ไม่ได้กำหนดไว้เมื่อคอมไพล์กับ GCC โดยปิดใช้งานส่วนขยาย GNU (เช่น -std = c ++ 0x)
Erbureth กล่าวว่า Reinstate Monica

1
@Erbureth คงที่ แต่ควรใช้ predef.sourceforge.net/index.php เป็นคำตอบที่ได้รับคะแนนสูงสุด
rubenvb

@rubenvb: แน่นอน และยังมีคะแนนโหวตน้อยเกินไปฉันคิดว่า :) ... ฉันหันไปที่ไซต์ของพวกเขาหลายครั้งแล้ว
0xC0000022L

เพื่อความสอดคล้อง (อาจจะเป็นการอวดดีเล็กน้อย): #ifคำถามแรกถามว่ากำหนดหรือไม่คนอื่นจะทดสอบคุณค่า ถ้าจะทำสม่ำเสมอกว่า#elif defined(__unix__) นี้ผมคิดว่า
leonbloy

20

หากคุณกำลังเขียน C ++ ฉันไม่สามารถแนะนำให้ใช้ไลบรารีBoost ได้มากพอ

เวอร์ชันล่าสุด (1.55) ประกอบด้วยไลบรารีPredefใหม่ซึ่งครอบคลุมสิ่งที่คุณกำลังมองหาพร้อมกับมาโครการจดจำแพลตฟอร์มและสถาปัตยกรรมอื่น ๆ อีกมากมาย

#include <boost/predef.h>

// ...

#if BOOST_OS_WINDOWS

#elif BOOST_OS_LINUX

#elif BOOST_OS_MACOS

#endif

เนื่องจากนี่เป็นการเพิ่มประสิทธิภาพโซลูชันนี้จะทำงานบนแพลตฟอร์ม / ระบบปฏิบัติการที่แตกต่างกันและคอมไพเลอร์ที่แตกต่างกัน
Trevor Boyd Smith

3
"ฉันไม่สามารถแนะนำให้ใช้ไลบรารี Boost ได้มากพอ .... " - ฉันประเมิน Boost สามครั้งแล้ว ไม่สามารถผ่านการประเมินผล ... รายงานข้อบกพร่องส่วนใหญ่โชคดีหากได้รับการยอมรับ การขาดการรับทราบชี้ให้เห็นถึงปัญหาที่ลึกซึ้งยิ่งขึ้นในกระบวนการวิศวกรรม ฉันเชื่อว่ามาโครตัวประมวลผลก่อนและสร้างขึ้นในไลบรารีมาตรฐาน C ++ เป็นตัวเลือกที่ปลอดภัยกว่า
jww
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.