Como faço para verificar OS com uma directiva de pré-processador?
-
02-07-2019 - |
Pergunta
Eu preciso do meu código para fazer coisas diferentes com base no sistema operacional em que ele é compilado. Eu estou procurando algo como isto:
#ifdef OSisWindows
// do Windows-specific stuff
#else
// do Unix-specific stuff
#endif
Existe uma maneira de fazer isso? Existe uma maneira melhor de fazer a mesma coisa?
Solução
O Macros predefinidas para OS site tem um lista muito completa de cheques. Aqui estão alguns deles, com links para onde eles são encontrados:
o Windows
_WIN32
de 32 bits e 64 bits
_WIN64
64 bits somente
Unix (Linux, * BSD, Mac OS X)
Veja este pergunta relacionada em algumas das armadilhas de usar essa verificação.
unix
__unix
__unix__
Mac OS X
__APPLE__
__MACH__
Ambos são definidos; verificando quer deve funcionar.
Linux
__linux__
linux
Obsoleto (não compatível com POSIX)
__linux
Obsoleto (não compatível com POSIX)
FreeBSD
__FreeBSD__
Outras dicas
define espectáculo GCC no Windows:
gcc -dM -E - <NUL:
no Linux:
gcc -dM -E - </dev/null
macros pré-definidas em MinGW:
WIN32 _WIN32 __WIN32 __WIN32__ __MINGW32__ WINNT __WINNT __WINNT__ _X86_ i386 __i386
em UNIXes:
unix __unix__ __unix
Com base nadeausoftware e a resposta de Lambda Fada .
#include <stdio.h>
/**
* Determination a platform of an operation system
* Fully supported supported only GNU GCC/G++, partially on Clang/LLVM
*/
#if defined(_WIN32)
#define PLATFORM_NAME "windows" // Windows
#elif defined(_WIN64)
#define PLATFORM_NAME "windows" // Windows
#elif defined(__CYGWIN__) && !defined(_WIN32)
#define PLATFORM_NAME "windows" // Windows (Cygwin POSIX under Microsoft Window)
#elif defined(__ANDROID__)
#define PLATFORM_NAME "android" // Android (implies Linux, so it must come first)
#elif defined(__linux__)
#define PLATFORM_NAME "linux" // Debian, Ubuntu, Gentoo, Fedora, openSUSE, RedHat, Centos and other
#elif defined(__unix__) || defined(__APPLE__) && defined(__MACH__)
#include <sys/param.h>
#if defined(BSD)
#define PLATFORM_NAME "bsd" // FreeBSD, NetBSD, OpenBSD, DragonFly BSD
#endif
#elif defined(__hpux)
#define PLATFORM_NAME "hp-ux" // HP-UX
#elif defined(_AIX)
#define PLATFORM_NAME "aix" // IBM AIX
#elif defined(__APPLE__) && defined(__MACH__) // Apple OSX and iOS (Darwin)
#include <TargetConditionals.h>
#if TARGET_IPHONE_SIMULATOR == 1
#define PLATFORM_NAME "ios" // Apple iOS
#elif TARGET_OS_IPHONE == 1
#define PLATFORM_NAME "ios" // Apple iOS
#elif TARGET_OS_MAC == 1
#define PLATFORM_NAME "osx" // Apple OSX
#endif
#elif defined(__sun) && defined(__SVR4)
#define PLATFORM_NAME "solaris" // Oracle Solaris, Open Indiana
#else
#define PLATFORM_NAME NULL
#endif
// Return a name of platform, if determined, otherwise - an empty string
char *
get_platform_name() {
return (PLATFORM_NAME == NULL) ? "" : PLATFORM_NAME;
}
int main(int argc, char *argv[]) {
puts(get_platform_name());
return 0;
}
Testado com GCC e clang em:
- Debian 8
- Windows (MinGW)
- Windows (Cygwin)
Na maioria dos casos, é melhor para verificar se um determinado funcionalidade está presente ou não. Por exemplo:. Se a função pipe()
existe ou não
#ifdef _WIN32
// do something for windows like include <windows.h>
#elif defined __unix__
// do something for unix like include <unistd.h>
#elif defined __APPLE__
// do something for mac
#endif
Microsoft C / C ++ compilador (MSVC) Macros predefinidas pode ser encontrada aqui:
https://docs.microsoft.com/en-us / CPP / pré-processador / pré-definida-macros
Eu acho que você está procurando:
_WIN32 - definido como 1, quando o alvo é compilação de 32 bits ARM de 64 bits ARM, x86, ou x64. Caso contrário, indefinido
_WIN64 - definido como 1, quando o alvo é compilação de 64 bits ARM ou x64. Caso contrário, indefinido.
gcc compilador Macros predefinidas pode ser encontrada aqui:
Eu acho que você está procurando:
__ GNUC__
__GNUC_MINOR__
__GNUC_PATCHLEVEL__
Fazer um google para seus compiladores apropriadas pré-definido.
Não há nenhuma macro padrão que é definido de acordo com o padrão C. Alguns compiladores C irá definir um em algumas plataformas (por exemplo GCC remendada da Apple define uma macro para indicar que ele está compilando em um sistema Apple e para a plataforma de Darwin). Sua plataforma e / ou seu compilador C pode definir algo tão bem, mas não há nenhuma maneira geral.
Como hayalci disse, é melhor ter essas macros definidos no seu processo de construção de alguma forma. É fácil definir uma macro com a maioria dos compiladores sem modificar o código. Você pode simplesmente passar -D MACRO
para GCC, i.
gcc -D Windows
gcc -D UNIX
E em seu código:
#if defined(Windows)
// do some cool Windows stuff
#elif defined(UNIX)
// do some cool Unix stuff
#else
# error Unsupported operating system
#endif
Em MinGW, o _WIN32
definir cheque não está funcionando. Aqui está uma solução:
#if defined(_WIN32) || defined(__CYGWIN__)
// Windows (x86 or x64)
// ...
#elif defined(__linux__)
// Linux
// ...
#elif defined(__APPLE__) && defined(__MACH__)
// Mac OS
// ...
#elif defined(unix) || defined(__unix__) || defined(__unix)
// Unix like OS
// ...
#else
#error Unknown environment!
#endif
Para mais informações, por favor olhar: https://sourceforge.net/p/predef/ wiki / operatingSystems /
Use #define OSsymbol
e #ifdef OSsymbol
onde OSsymbol é um símbolo #define
'able identificar seu sistema operacional alvo.
Normalmente, você incluir um arquivo de cabeçalho central de definir o símbolo OS selecionado e específicos do OS uso incluir e diretórios de biblioteca para compilar e construção.
Você não especificou o seu ambiente de desenvolvimento, mas eu tenho certeza que o seu compilador fornece define globais para plataformas e sistemas operacionais comuns.
Veja também http://en.wikibooks.org/wiki/C_Programming/Preprocessor
Só para resumir tudo, aqui estão um monte de links úteis.
- GCC Comum Macros predefinidas
- SourceForge predefinido Sistemas operacionais
- MSDN Macros predefinidas
- O Much-Linked NaudeaSoftware Página
- Wikipedia !!!
- SourceForge da "Visão geral de macros pré-definidas do compilador para padrões, compiladores, sistemas operacionais e arquiteturas de hardware. "
- do FreeBSD "Diferenciando sistemas operacionais"
- Todos os tipos de predefinido macros
-
libportable
Desculpem a referência externa, mas eu acho que é adequado à sua pergunta:
C / C ++ dica: Como detectar o tipo de sistema operacional usando o compilador predefinidos macros
Você pode usar diretivas pré-processador como aviso ou erro para verificar em tempo de compilação que você não precisa Executar este programa em tudo simplesmente compilação -lo.
#if defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__)
#error Windows_OS
#elif defined(__linux__)
#error Linux_OS
#elif defined(__APPLE__) && defined(__MACH__)
#error Mach_OS
#elif defined(unix) || defined(__unix__) || defined(__unix)
#error Unix_OS
#else
#error Unknown_OS
#endif
#include <stdio.h>
int main(void)
{
return 0;
}
Eu não encontrei definição Haiku aqui. Para ser completa, definição Haiku-os é simples __HAIKU__
Você pode usar Boost.Predef
que contém vários macros pré-definidas para a plataforma de destino, incluindo a oS. Sim impulso é muitas vezes visto como uma biblioteca C ++, mas este é um cabeçalho pré-processador que funciona com C, bem
Esta biblioteca define um conjunto de compilador, arquitetura, sistema operacional, biblioteca e outros números de versão a partir das informações que pode coletar de C, C ++, Objective C e Objective C ++ macros predefinidos ou aqueles definidos em cabeçalhos geralmente disponíveis. A ideia para esta biblioteca cresceu a partir de uma proposta para estender a biblioteca de configuração impulso para fornecer mais e consistente, informação do que as definições de recursos que ele suporta. O que se segue é uma versão editada de que a proposta breve.
Por exemplo
#include <boost/predef.h>
#if defined(BOOST_OS_WINDOWS)
#elif defined(BOOST_OS_ANDROID)
#elif defined(BOOST_OS_LINUX)
#elif defined(BOOST_OS_BSD)
...
#endif
Eu escrevi um pequena biblioteca para obter o sistema operacional que você está, ele pode ser instalado usando clib (O gerenciador de pacotes C), por isso é realmente simples para usá-lo como uma dependência para seus projetos.
Instalar
$ clib install abranhe/os.c
Uso
#include <stdio.h>
#include "os.h"
int main()
{
printf("%s\n", operating_system());
// macOS
return 0;
}
Ele retorna um string (char*
) com o nome do sistema operacional que você estiver usando, para mais informações sobre este projeto verificá-la a documentação no Github .