2011-07-11 9 views
111

chcę uruchomić jakiś kod C++ na Linux i Windows. Jest kilka fragmentów kodu, które chcę dołączyć tylko do jednego systemu operacyjnego, a nie do drugiego. Czy istnieje standardowa wersja #ifdef, której można użyć raz?C++ kompilowanie na Windows i Linux: przełącznik ifdef

Coś jak:

#ifdef LINUX_KEY_WORD 
    ... // linux code goes here. 
    #elif WINDOWS_KEY_WORD 
    ... // windows code goes here. 
    #else 
    #error "OS not supported!" 
    #endif 

Pytanie jest rzeczywiście duplikat ale tutaj odpowiedzi są znacznie lepiej, zwłaszcza przyjętej jeden.

+1

@MooingDuck: Potwierdzam, że chciałem, aby zdecydował się na docelowej OS niekoniecznie na kompilator używany. – Sardathrion

Odpowiedz

98

zastosowanie:

#ifdef __linux__ 
    //linux code goes here 
#elif _WIN32 
    // windows code goes here 
#else 

#endif 
+10

ta odpowiedź jest nieco lepsza, ponieważ bezpośrednio odpowiada na pytanie, zamiast tylko podać link do jakiejś trzeciej strony, która może umrzeć pewnego dnia – Petr

+0

Na moim Ubuntu Trusty działa tylko '__linux__'. Ani '__linux' ani' linux' nie działają. – SebMa

0

Nie, te definiuje to kompilator zależne. Co możesz zrobić, użyj własnego zestawu definicji i umieść je w Makefile. Aby uzyskać więcej informacji, patrz this thread.

+10

poprawne, ale nie pomocny – duedl0r

+0

@Cicada: Kompilator zależne nie ma znaczenia, gdy wszystkie kompilatory (gadać) zrobić to samo. – rubenvb

+0

jednak nie ma standardu określającego to i o to prosił. Aktualizuję odpowiedź, aby wskazać przydatne odniesienie do tego – Vitor

7

To zależy od używanych kompilator.

Na przykład definicja Windows może być WIN32 lub _WIN32.

Definicja Linuxa może być UNIX lub __unix__ lub LINUX lub __linux__.

+1

Istnieje taki standard. Te narzędzia narzędziowe, które nie są z nimi zgodne, są albo błędne, stare jak kamień, albo po prostu złe. – rubenvb

+0

@rubenvb: a standardem jest ...? Chcesz opublikować odpowiedź lub co najmniej URL? – MestreLion

+2

@MestreLion Projekt Predef został w międzyczasie zaabsorbowany przez Boost, ale wszystkie makra są nadal wymienione w dokumentacji tutaj: http://www.boost.org/doc/libs/release/libs/predef/doc/html/index .html – rubenvb

4

To zależy od kompilatora. Jeśli skompilować z, powiedzmy, G ++ na Linux i VC++ w Windows, będzie to zrobić:

#ifdef linux 
    ... 
#elif _WIN32 
    ... 
#else 
    ... 
#endif 
+0

To zawsze zrobi. Wszystkie kompilatory implementują to w taki sam sposób. Clang na linuxie naśladuje GCC, Clang i GCC na Windowsie naśladuje MSVC. – rubenvb

+6

@rubenvb: Wszystkie * istniejące * kompilatory, przez * wygodę *. To zachowanie nie jest znormalizowane i może być inne w przypadku niektórych kompilatorów, których nikt nie używa. –

11

Ta odpowiedź nie jest o wojnie makro, ale produkujących błąd, jeśli nie zostanie znaleziony platforma.

#ifdef LINUX_KEY_WORD 
... // linux code goes here. 
#elif WINDOWS_KEY_WORD  
... // windows code goes here. 
#else  
#error Platform not supported 
#endif 

Jeśli #error nie jest obsługiwany, można użyć static_assert (C++ 0x) słowa kluczowego. Możesz też zaimplementować niestandardowy STATIC_ASSERT lub po prostu zadeklarować tablicę o rozmiarze 0 lub mieć przełącznik, który ma duplikaty. W skrócie, produkują błąd w czasie kompilacji a nie na wykonywania

+0

Dziękuję. Kod w pytaniu został zmodyfikowany. – Sardathrion

+3

'# błąd' ** musi ** być obsługiwane (w przeciwieństwie do' # warning', które jest rozszerzeniem). Zgadzam się jednak, że niekoniecznie jest to najlepszy sposób na niepowodzenie kompilacji. – Thomas

+0

@Thomas: Rzeczywiście. Na szczęście jeśli "# error" nie jest obsługiwane w niektórych niezgodnych implementacjach, wynikiem niepoprawnego oświadczenia preprocesora jest, no cóż - błąd. A jeśli to nie jest błąd, to kompilator jest * NAPRAWDĘ NAPRAWDĘ * kiepski i nie warto go wspierać (chociaż bardzo * wątpię, żeby taki kompilator istniał). –

19

Można zrobić

#if MACRO0 
    //code... 
#elif MACRO1 
    //code... 
#endif 

Gdzie Makro może być:

__linux__  Defined on Linux 
    __sun   Defined on Solaris 
    __FreeBSD__  Defined on FreeBSD 
    __NetBSD__  Defined on NetBSD 
    __OpenBSD__  Defined on OpenBSD 
    __APPLE__  Defined on Mac OS X 
    __hpux   Defined on HP-UX 
    __osf__   Defined on Tru64 UNIX (formerly DEC OSF1) 
    __sgi   Defined on Irix 
    _AIX   Defined on AIX 
+38

LOL Dlaczego brakuje biblioteki _WIN32 dla systemu Windows? :-) – jamadagni

+3

@jamadagni Ponieważ jest to lista systemów operacyjnych. –

+2

@ sorush-r A Win32 nie oznacza jednego? – jamadagni

24

wiem, że to nie jest odpowiedź, ale dodał jeśli ktoś szuka sama w Qt

w Qt

https://wiki.qt.io/Get-OS-name-in-Qt

QString Get::osName() 
{ 
#if defined(Q_OS_ANDROID) 
    return QLatin1String("android"); 
#elif defined(Q_OS_BLACKBERRY) 
    return QLatin1String("blackberry"); 
#elif defined(Q_OS_IOS) 
    return QLatin1String("ios"); 
#elif defined(Q_OS_MAC) 
    return QLatin1String("osx"); 
#elif defined(Q_OS_WINCE) 
    return QLatin1String("wince"); 
#elif defined(Q_OS_WIN) 
    return QLatin1String("windows"); 
#elif defined(Q_OS_LINUX) 
    return QLatin1String("linux"); 
#elif defined(Q_OS_UNIX) 
    return QLatin1String("unix"); 
#else 
    return QLatin1String("unknown"); 
#endif 
} 
Powiązane problemy