컴파일 된 운영 체제에 따라 다른 작업을 수행하려면 코드가 필요합니다. 나는 이와 같은 것을 찾고있다 :
#ifdef OSisWindows
// do Windows-specific stuff
#else
// do Unix-specific stuff
#endif
이 방법이 있습니까? 같은 일을하는 더 좋은 방법이 있습니까?
C
없습니다C++
컴파일 된 운영 체제에 따라 다른 작업을 수행하려면 코드가 필요합니다. 나는 이와 같은 것을 찾고있다 :
#ifdef OSisWindows
// do Windows-specific stuff
#else
// do Unix-specific stuff
#endif
이 방법이 있습니까? 같은 일을하는 더 좋은 방법이 있습니까?
C
없습니다C++
답변:
미리 정의 된 매크로 OS 용 사이트는 검사의 매우 완전한 목록이 있습니다. 다음은 발견 된 곳으로 연결되는 링크입니다.
_WIN32
32 비트 및 64 비트
_WIN64
64 비트 만
이 점검을 사용하는 함정 중 일부에 대해서는이 관련 질문 을 참조 하십시오.
unix
__unix
__unix__
__APPLE__
__MACH__
둘 다 정의됩니다. 둘 중 하나를 확인하면 작동합니다.
__linux__
linux
폐기 됨 (POSIX 호환 아님)
__linux
폐기 됨 (POSIX 호환 아님)
__FreeBSD__
__ANDROID__
__unix__
. 왜 목록에 포함 하시겠습니까?
unix
기호를 정의하고 기호를 정의하지 않으므로 win32
주의하십시오. OTOH 정의 __CYGWIN__
합니다.
__linux__
동일 __ANDROID__
??
nadeausoftware 및 Lambda 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을 사용하여 다음과 같이 테스트했습니다.
대부분의 경우 주어진 기능의 존재 여부를 확인하는 것이 좋습니다. 예를 들어, 함수 pipe()
가 존재하는지 여부입니다.
#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
나는 당신이 찾고 있다고 생각합니다 :
_WIN32
-컴파일 대상이 32 비트 ARM, 64 비트 ARM, x86 또는 x64 인 경우 1로 정의됩니다. 그렇지 않으면 정의되지 않은_WIN64
-컴파일 대상이 64 비트 ARM 또는 x64 인 경우 1로 정의됩니다. 그렇지 않으면 정의되지 않습니다.
나는 당신이 찾고 있다고 생각합니다 :
__GNUC__
__GNUC_MINOR__
__GNUC_PATCHLEVEL__
적절한 컴파일러에 대해 사전 정의 된 Google을 수행하십시오.
C 표준에 따라 설정된 표준 매크로가 없습니다. 일부 C 컴파일러는 일부 플랫폼에서 하나를 설정합니다 (예 : Apple의 패치 된 GCC는 매크로를 설정하여 Apple 시스템과 Darwin 플랫폼에서 컴파일되고 있음을 나타냅니다). 플랫폼 및 / 또는 C 컴파일러도 무언가를 설정할 수 있지만 일반적인 방법은 없습니다.
hayalci가 말했듯이 빌드 프로세스에서 이러한 매크로를 설정하는 것이 가장 좋습니다. 코드를 수정하지 않고도 대부분의 컴파일러에서 매크로를 쉽게 정의 할 수 있습니다. 간단히 -D MACRO
GCC로 전달할 수 있습니다.
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
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/를 참조하십시오.
사용 #define OSsymbol
및 #ifdef OSsymbol
여기서 OSsymbol은 #define
대상 OS를 식별 할 수있는 기호입니다.
일반적으로 선택한 OS 기호를 정의하는 중앙 헤더 파일을 포함하고 OS 별 포함 및 라이브러리 디렉토리를 사용하여 컴파일 및 빌드합니다.
개발 환경을 지정하지 않았지만 컴파일러가 공통 플랫폼 및 OS에 대한 전역 정의를 제공한다고 확신합니다.
Boost.Predef
OS ( 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
당신이 사용할 수있는 전 처리기 지시어 로 경고 또는 오류를 당신이 할 필요가 없습니다 컴파일시에 확인하는 실행 단지 모두에서이 프로그램을 컴파일 을.
#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;
}
나는 운영 체제를 얻기 위해 작은 라이브러리 를 작성했으며 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의 설명서를 확인하십시오 .