사전 처리기 지침으로 OS를 확인하려면 어떻게해야합니까?
-
02-07-2019 - |
문제
컴파일되는 운영 체제를 기반으로 다른 작업을 수행하려면 코드가 필요합니다. 나는 다음과 같은 것을 찾고 있습니다.
#ifdef OSisWindows
// do Windows-specific stuff
#else
// do Unix-specific stuff
#endif
이것을 할 방법이 있습니까? 똑같은 일을하는 더 좋은 방법이 있습니까?
해결책
그만큼 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__
다른 팁
GCC 표시는 Windows에서 정의합니다.
gcc -dM -E - <NUL:
Linux :
gcc -dM -E - </dev/null
Mingw의 사전 정의 된 매크로 :
WIN32 _WIN32 __WIN32 __WIN32__ __MINGW32__ WINNT __WINNT __WINNT__ _X86_ i386 __i386
Unixes :
unix __unix__ __unix
기반 nadeausoftware 그리고 람다 요정의 대답.
#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;
}
GCC 및 Clang으로 테스트 : :
- 데비안 8
- Windows (mingw)
- Windows (Cygwin)
대부분의 경우 주어진 기능이 존재하는지 여부를 확인하는 것이 좋습니다. 예를 들어 : 함수 인 경우 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
Microsoft C/C ++ 컴파일러 (MSVC) 사전 정의 된 매크로는 여기에서 찾을 수 있습니다.
https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros
나는 당신이 찾고 있다고 생각합니다.
_win32- 컴파일 대상이 32 비트 암, 64 비트 암, x86 또는 x64 인 경우 1으로 정의됩니다. 그렇지 않으면 정의되지 않았습니다
_win64- 컴파일 대상이 64 비트 암 또는 x64 인 경우 1으로 정의됩니다. 그렇지 않으면 정의되지 않았습니다.
GCC 컴파일러 사전 정의 된 매크로는 여기에서 찾을 수 있습니다.
나는 당신이 찾고 있다고 생각합니다.
__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은 a #define
'대상 OS를 식별 할 수있는 기호.
일반적으로 선택한 OS 기호를 정의하는 중앙 헤더 파일이 포함되며 OS 특정 포함 및 라이브러리 디렉토리를 사용하여 컴파일 및 빌드합니다.
개발 환경을 지정하지는 않았지만 컴파일러가 공통 플랫폼 및 OS에 대한 글로벌 정의를 제공 할 것이라고 확신합니다.
또한보십시오 http://en.wikibooks.org/wiki/c_programming/preprocessor
외부 참조에 대해 죄송하지만 질문에 적합하다고 생각합니다.
당신이 사용할 수있는 사전 프로세서 지시문 ~처럼 경고 또는 오류 컴파일 시간을 확인하려면 필요하지 않습니다 운영 이 프로그램은 전혀 간단합니다 엮다 그것 .
#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;
}
나는 찾지 못했다 하이쿠 여기서 정의. 완전하기 위해 Haiku-OS 정의는 간단합니다 __HAIKU__
당신이 사용할 수있는 Boost.Predef
여기에는 OS를 포함한 대상 플랫폼에 대한 다양한 사전 정의 된 매크로가 포함되어 있습니다. 예, 부스트는 종종 C ++ 라이브러리로 생각되지만 이것은 C에서도 작동하는 전처리 제 헤더입니다.
이 라이브러리는 C, C ++, 목표 C 및 목표 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)
...
#endif
나는 썼다 작은 도서관 운영 체제를 얻으려면 사용하여 설치할 수 있습니다. 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에 대한 문서.