Компиляция C ++ в Windows и Linux: переключатель ifdef

Я хочу запустить код на C ++ в Linux и Windows. Есть некоторые фрагменты кода, которые я хочу включить только для одной операционной системы, а не для другой. Есть ли стандартный #ifdef, который можно использовать один раз?

Что-то типа:

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

Вопрос действительно повторяется, но ответы здесь намного лучше, особенно принятый.


person Sardathrion - against SE abuse    schedule 11.07.2011    source источник
comment
@MooingDuck: Я подтверждаю, что хотел выбрать целевую ОС, а не обязательно использовать компилятор.   -  person Sardathrion - against SE abuse    schedule 21.12.2012


Ответы (7)


использовать:

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

#endif
person Muhammad Anjum Kaiser    schedule 11.07.2011
comment
этот ответ немного лучше, поскольку он напрямую отвечает на вопрос, а не просто предоставляет ссылку на какой-то третий сайт, который может умереть в один прекрасный день - person Petr; 06.03.2014
comment
На моем Ubuntu Trusty работает только __linux__. Ни __linux, ни linux не работают. - person SebMa; 24.09.2017
comment
Я только что понял, что проект, который я создаю, проходит в -std = c ++ 0x, который устанавливает __linux__, а не __linux. - person Christy; 02.04.2018

Ты можешь сделать:

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

где идентификатор может быть:

    __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
    _WIN32          Defined on Windows
person user1527227    schedule 24.03.2014

Я знаю, что это не ответ, но добавлен, если кто-то выглядит так же в Qt

В 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
}
person Yash    schedule 26.11.2014

Это зависит от используемого компилятора.

Например, определение Windows может быть WIN32 или _WIN32.

И определение Linux может быть UNIX, __unix__, LINUX или __linux__.

person Igor Oks    schedule 11.07.2011
comment
Есть такой стандарт. Те цепочки инструментов, которые его не придерживаются, либо глючны, либо устарели, либо просто плохи. - person rubenvb; 11.07.2011
comment
@rubenvb: а стандарт ...? Хотите опубликовать ответ или хотя бы URL-адрес? - person MestreLion; 25.03.2016
comment
@MestreLion С тех пор проект Predef был поглощен Boost, но все макросы по-прежнему перечислены в документации здесь: boost.org/doc/libs/release/libs/predef/doc/html/index.html - person rubenvb; 26.03.2016
comment
WIN32 определяется внутри Windows.h. Таким образом, если заголовок не был включен, переключатель типа работать не будет. _WIN32 должен быть определен по умолчанию. - person ivaigult; 18.04.2017

Этот ответ не о войне макросов, а об ошибке, если подходящая платформа не найдена.

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

Если #error не поддерживается, вы можете использовать ключевое слово static_assert (C ++ 0x). Или вы можете реализовать собственный STATIC_ASSERT, или просто объявить массив размером 0, или иметь переключатель, который имеет повторяющиеся случаи. Короче говоря, ошибка возникает в времени компиляции, а не во время выполнения.

person Ajay    schedule 11.07.2011
comment
#error должен поддерживаться (в отличие от #warning, который является расширением). Но я согласен с тем, что это не обязательно лучший способ провалить сборку. - person Thomas; 28.08.2014
comment
@ Томас: Конечно. К счастью, если #error не поддерживается в какой-либо несовместимой реализации, результатом неправильного оператора препроцессора будет, ну, ошибка. И если это тоже не ошибка, значит, компилятор ДЕЙСТВИТЕЛЬНО дрянный и в любом случае не заслуживает поддержки (хотя я очень сомневаюсь, что такой компилятор существует). - person Tim Čas; 24.12.2014

Это зависит от компилятора. Если вы компилируете, скажем, G ++ в Linux и VC ++ в Windows, это будет делать:

#ifdef linux
    ...
#elif _WIN32
    ...
#else
    ...
#endif
person user703016    schedule 11.07.2011
comment
Так будет всегда. Все компиляторы реализуют это одинаково. Clang в Linux имитирует GCC, Clang и GCC в Windows имитирует MSVC. - person rubenvb; 11.07.2011
comment
@rubenvb: все существующие компиляторы, по удобству. Это поведение не стандартизировано и может отличаться для некоторых компиляторов, которые никто не использует. - person user703016; 11.07.2011

Нет, эти определения зависят от компилятора. Что вы можете сделать, это использовать свой собственный набор определений и установить их в Makefile. Дополнительную информацию см. В этой ветке.

person Vitor    schedule 11.07.2011
comment
правильно, но бесполезно - person duedl0r; 11.07.2011
comment
@Cicada: зависимость от компилятора не имеет значения, когда все компиляторы (о которых стоит поговорить) делают одно и то же. - person rubenvb; 11.07.2011
comment
тем не менее, нет стандарта, определяющего это, и это то, что он просил. Я обновляю ответ, чтобы указать на полезную ссылку об этом - person Vitor; 11.07.2011
comment
Меня забавляет, что вы предлагаете make-файлы в качестве альтернативы определениям, зависящим от компилятора. Большинство компиляторов используют одни и те же определения, чем файлы сборки. - person Mooing Duck; 20.12.2012
comment
Компиляторы не используют make-файлы, make-файлы используют компиляторы. - person pattivacek; 13.09.2013
comment
Make-файлы - это решение, скорее похожее на unix, которое можно использовать в Windows, но не так часто. Во-первых, make не устанавливается по умолчанию. - person wheredidthatnamecomefrom; 15.03.2018