전 처리기 지시문으로 OS를 어떻게 확인합니까?


195

컴파일 된 운영 체제에 따라 다른 작업을 수행하려면 코드가 필요합니다. 나는 이와 같은 것을 찾고있다 :

#ifdef OSisWindows
// do Windows-specific stuff
#else
// do Unix-specific stuff
#endif

이 방법이 있습니까? 같은 일을하는 더 좋은 방법이 있습니까?



8
@Cory Klein : 아니오. 이 질문은 몇 년 전에 요청되었습니다
John_West

이 약 C없습니다C++
ilgaar

답변:


290

미리 정의 된 매크로 OS 용 사이트는 검사의 매우 완전한 목록이 있습니다. 다음은 발견 된 곳으로 연결되는 링크입니다.

윈도우

_WIN32   32 비트 및 64 비트
_WIN64   64 비트 만

유닉스 (Linux, * BSD, Mac OS X)

이 점검을 사용하는 함정 중 일부에 대해서는이 관련 질문 을 참조 하십시오.

unix
__unix
__unix__

맥 OS X

__APPLE__
__MACH__

둘 다 정의됩니다. 둘 중 하나를 확인하면 작동합니다.

리눅스

__linux__
linux 폐기 됨 (POSIX 호환 아님)
__linux폐기 됨 (POSIX 호환 아님)

FreeBSD

__FreeBSD__

기계적 인조 인간

__ANDROID__


1
이 사이트에는 iOS가 포함되어 있지 않으므로 iOS와 OS X를 구별 할 수 없습니다.
Gary Makin

2
Mac OS는 정의하지 않습니다 __unix__. 왜 목록에 포함 하시겠습니까?
Victor Sergienko

1
CPP -dM을 / dev / null 설치 GCC의 버전에 당신에게 모든 GCC 미리 정의 된 매크로의 목록을 제공합니다
katta

1
Cygwin은 unix기호를 정의하고 기호를 정의하지 않으므로 win32주의하십시오. OTOH 정의 __CYGWIN__합니다.
David 주어진

__linux__동일 __ANDROID__??
아무도 없습니다.

72

Windows에서 GCC 정의 표시 :

gcc -dM -E - <NUL:

Linux에서 :

gcc -dM -E - </dev/null

MinGW에서 사전 정의 된 매크로 :

WIN32 _WIN32 __WIN32 __WIN32__ __MINGW32__ WINNT __WINNT __WINNT__ _X86_ i386 __i386

UNIX에서 :

unix __unix__ __unix

1
윈도우와 유닉스는 유일한 운영체제 아니다
phuclv의

35

nadeausoftwareLambda Fairy의 답변을 기반으로 합니다.

#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
const char *get_platform_name() {
    return (PLATFORM_NAME == NULL) ? "" : PLATFORM_NAME;
}

int main(int argc, char *argv[]) {
    puts(get_platform_name());
    return 0;
}

GCC 및 clang을 사용하여 다음과 같이 테스트했습니다.

  • 데비안 8
  • 윈도우 (MinGW)
  • 윈도우 (Cygwin)

친애하는 @MD XF 여러분, Windows, MinGW 및 Cygwin의 버전을 알려주십시오
PADYMKO

Windows 7 Enterprise 6.1.7601. Cygwin 2.7.0-1. MinGW 버전을 찾을 수 없지만 어제 다운로드했습니다.
MD XF

이 프로그램은 표준 C이므로 모든 호환 시스템에서 작동해야합니다.
MD XF

@MD XF님께,이 정보에 감사드립니다. 이 답변에 기여자로 당신을 추가했습니다.
PADYMKO

10

대부분의 경우 주어진 기능의 존재 여부를 확인하는 것이 좋습니다. 예를 들어, 함수 pipe()가 존재하는지 여부입니다.


3
함수가 정의되어 있는지 쉽게 확인할 수 있습니까?
hayalci

1
자동 구성을 사용하는 경우 AC_CHECK_FUNCS ()로 기능을 확인할 수 있습니다. AC_CHECK_FUNCS (pipe sqrt)는 함수가 사용 가능한 경우 HAVE_PIPE 및 HAVE_SQRT를 정의합니다. 나는 그것이 다른 건축 도구와 어떻게 관련되어 있는지 모르겠지만, 그것들이 어떤 방식으로도 이것을 지원한다고 생각합니다.
quinmars

@MDXF C ++ 17부터 __has_include가 있습니다. C에서는 아직 표준화되지 않았다고 생각하지만 모든 주요 컴파일러 (GCC, Clang, ICC, MSVC)는 C 모드에서도 벤더별 확장으로 구현합니다.
Alcaro

7
#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

5

Microsoft C / C ++ 컴파일러 (MSVC) 사전 정의 된 매크로는 여기 에서 찾을 수 있습니다.

나는 당신이 찾고 있다고 생각합니다 :

  • _WIN32-컴파일 대상이 32 비트 ARM, 64 비트 ARM, x86 또는 x64 인 경우 1로 정의됩니다. 그렇지 않으면 정의되지 않은
  • _WIN64-컴파일 대상이 64 비트 ARM 또는 x64 인 경우 1로 정의됩니다. 그렇지 않으면 정의되지 않습니다.

gcc 컴파일러 사전 정의 된 매크로는 여기 에서 찾을 수 있습니다

나는 당신이 찾고 있다고 생각합니다 :

  • __GNUC__
  • __GNUC_MINOR__
  • __GNUC_PATCHLEVEL__

적절한 컴파일러에 대해 사전 정의 된 Google을 수행하십시오.


4

C 표준에 따라 설정된 표준 매크로가 없습니다. 일부 C 컴파일러는 일부 플랫폼에서 하나를 설정합니다 (예 : Apple의 패치 된 GCC는 매크로를 설정하여 Apple 시스템과 Darwin 플랫폼에서 컴파일되고 있음을 나타냅니다). 플랫폼 및 / 또는 C 컴파일러도 무언가를 설정할 수 있지만 일반적인 방법은 없습니다.

hayalci가 말했듯이 빌드 프로세스에서 이러한 매크로를 설정하는 것이 가장 좋습니다. 코드를 수정하지 않고도 대부분의 컴파일러에서 매크로를 쉽게 정의 할 수 있습니다. 간단히 -D MACROGCC로 전달할 수 있습니다.

gcc -D Windows
gcc -D UNIX

그리고 당신의 코드에서 :

#if defined(Windows)
// do some cool Windows stuff
#elif defined(UNIX)
// do some cool Unix stuff
#else
#    error Unsupported operating system
#endif

4

MinGW에서 _WIN32정의 검사가 작동하지 않습니다. 해결책은 다음과 같습니다.

#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

자세한 내용은 https://sourceforge.net/p/predef/wiki/OperatingSystems/를 참조하십시오.


3
훌륭한 링크. ---
MD XF

2

사용 #define OSsymbol#ifdef OSsymbol 여기서 OSsymbol은 #define대상 OS를 식별 할 수있는 기호입니다.

일반적으로 선택한 OS 기호를 정의하는 중앙 헤더 파일을 포함하고 OS 별 포함 및 라이브러리 디렉토리를 사용하여 컴파일 및 빌드합니다.

개발 환경을 지정하지 않았지만 컴파일러가 공통 플랫폼 및 OS에 대한 전역 정의를 제공한다고 확신합니다.

http://en.wikibooks.org/wiki/C_Programming/Preprocessor 참조




2

Boost.PredefOS ( BOOST_OS_*)를 포함하여 대상 플랫폼에 대해 사전 정의 된 다양한 매크로를 포함하는를 사용할 수 있습니다 . 예, 부스트는 종종 C ++ 라이브러리로 생각되지만 C와 함께 작동 하는 전 처리기 헤더입니다 !

이 라이브러리는 C, C ++, Objective C 및 Objective C ++ 사전 정의 매크로 또는 일반적으로 사용 가능한 헤더에 정의 된 정보에서 수집 할 수있는 정보로부터 컴파일러, 아키텍처, 운영 체제, 라이브러리 및 기타 버전 번호 세트를 정의합니다. 이 라이브러리에 대한 아이디어는 Boost Config 라이브러리를 확장하여 지원하는 기능 정의보다 더 많은 정보를 일관성있게 제공하려는 제안에서 비롯되었습니다. 다음은 간략한 제안서의 수정 된 버전입니다.

예를 들어

#include <boost/predef.h>

#if defined(BOOST_OS_WINDOWS)
#elif defined(BOOST_OS_ANDROID)
#elif defined(BOOST_OS_LINUX)
#elif defined(BOOST_OS_BSD)
#elif defined(BOOST_OS_AIX)
#elif defined(BOOST_OS_HAIKU)
...
#endif

전체 목록은 운영 체제 매크로 에서 찾을 수 있습니다BOOST_OS


1

나는 여기에서 Haiku 정의를 찾지 못했습니다 . 완료하려면 Haiku-os 정의는 간단합니다__HAIKU__


0

일부 컴파일러는이를 지원할 수있는 #defines을 생성합니다. 컴파일러 설명서를 읽고 내용을 확인하십시오. MSVC가 의 하나를 정의 __WIN32__, GCC는 당신이 볼 수있는 몇 가지있다touch foo.h; gcc -dM foo.h


1
gcc : 오류 : 인식 할 수없는 명령 줄 옵션 '--show-defines'gcc : 치명적인 오류 : 입력 파일 컴파일이 종료되지 않았습니다.
Sebi2020

0

당신이 사용할 수있는 전 처리기 지시어경고 또는 오류를 당신이 할 필요가 없습니다 컴파일시에 확인하는 실행 단지 모두에서이 프로그램을 컴파일 을.

#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;
}

0

나는 운영 체제를 얻기 위해 작은 라이브러리 를 작성했으며 clib (C 패키지 관리자)를 사용하여 설치할 수 있으므로 프로젝트의 종속성으로 사용하는 것이 매우 간단합니다.

설치

$ clib install abranhe/os.c

용법

#include <stdio.h>
#include "os.h"

int main()
{
    printf("%s\n", operating_system());
    // macOS
    return 0;
}

char*사용중인 운영 체제 이름으로 문자열 ( )을 반환합니다. 이 프로젝트에 대한 자세한 내용은 Github의 설명서를 확인하십시오 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.