可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I need my code to do different things based on the operating system on which it gets compiled. I\'m looking for something like this:
#ifdef OSisWindows
// do Windows-specific stuff
#else
// do Unix-specific stuff
#endif
Is there a way to do this? Is there a better way to do the same thing?
回答1:
The Predefined Macros for OS site has a very complete list of checks. Here are a few of them, with links to where they\'re found:
Windows
_WIN32
Both 32 bit and 64 bit
_WIN64
64 bit only
Unix (Linux, *BSD, Mac OS X)
See this related question on some of the pitfalls of using this check.
unix
__unix
__unix__
Mac OS X
__APPLE__
__MACH__
Both are defined; checking for either should work.
Linux
__linux__
linux
Obsolete (not POSIX compliant)
__linux
Obsolete (not POSIX compliant)
FreeBSD
__FreeBSD__
回答2:
show GCC defines on Windows:
gcc -dM -E - <NUL:
on Linux:
gcc -dM -E - </dev/null
Predefined macros in MinGW:
WIN32 _WIN32 __WIN32 __WIN32__ __MINGW32__ WINNT __WINNT __WINNT__ _X86_ i386 __i386
on UNIXes:
unix __unix__ __unix
回答3:
Based on nadeausoftware and Lambda Fairy\'s answer.
#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;
}
Tested with GCC and clang on:
- Debian 8
- Windows (MinGW)
- Windows (Cygwin)
回答4:
In most cases it is better to check whether a given functionality is present or not. For example: if the function pipe()
exists or not.
回答5:
#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
回答6:
MS compiler PreDefined Macros can be found here:
http://msdn.microsoft.com/en-us/library/b0084kay(VS.80).aspx
I think you are looking for:
_WIN32
_WIN64
gcc compiler PreDefined MAcros can be found here:
http://gcc.gnu.org/onlinedocs/cpp/Predefined-Macros.html
I think you are looking for:
__GNUC__
__GNUC_MINOR__
__GNUC_PATCHLEVEL__
Do a google for your appropriate compilers pre-defined.
回答7:
There is no standard macro that is set according to C standard. Some C compilers will set one on some platforms (e.g. Apple\'s patched GCC sets a macro to indicate that it is compiling on an Apple system and for the Darwin platform). Your platform and/or your C compiler might set something as well, but there is no general way.
Like hayalci said, it\'s best to have these macros set in your build process somehow. It is easy to define a macro with most compilers without modifying the code. You can simply pass -D MACRO
to GCC, i.e.
gcc -D Windows
gcc -D UNIX
And in your code:
#if defined(Windows)
// do some cool Windows stuff
#elif defined(UNIX)
// do some cool Unix stuff
#else
# error Unsupported operating system
#endif
回答8:
On MinGW, the _WIN32
define check isn\'t working. Here\'s a solution:
#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
For more information please look: https://sourceforge.net/p/predef/wiki/OperatingSystems/
回答9:
Use #define OSsymbol
and #ifdef OSsymbol
where OSsymbol is a #define
\'able symbol identifying your target OS.
Typically you would include a central header file defining the selected OS symbol and use OS-specific include and library directories to compile and build.
You did not specify your development environment, but I\'m pretty sure your compiler provides global defines for common platforms and OSes.
See also http://en.wikibooks.org/wiki/C_Programming/Preprocessor
回答10:
Just to sum it all up, here are a bunch of helpful links.
- GCC Common Predefined Macros
- SourceForge predefined Operating Systems
- MSDN Predefined Macros
- The Much-Linked NaudeaSoftware Page
- Wikipedia!!!
- SourceForge\'s \"Overview of pre-defined compiler macros for standards, compilers, operating systems, and hardware architectures.\"
- FreeBSD\'s \"Differentiating Operating Systems\"
- All kinds of predefined macros
libportable
回答11:
Sorry for the external reference, but I think it is suited to your question:
C/C++ tip: How to detect the operating system type using compiler predefined macros
回答12:
Some compilers will generate #defines that can help you with this. Read the compiler documentation to determine what they are. MSVC defines one that\'s __WIN32__
, GCC has some you can see with touch foo.h; gcc -dM foo.h
回答13:
You can use pre-processor directives as warning or error to check at compile time you don\'t need to run this program at all just simply compile it .
#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;
}
回答14:
I did not find Haiku definition here. To be complete, Haiku-os definition is simple __HAIKU__
回答15:
You can use Boost.Predef
which contains various predefined macros for the target platform including the OS. Yes boost is often thought as a C++ library, but this one is a preprocessor header that works with C as well
This library defines a set of compiler, architecture, operating system, library, and other version numbers from the information it can gather of C, C++, Objective C, and Objective C++ predefined macros or those defined in generally available headers. The idea for this library grew out of a proposal to extend the Boost Config library to provide more, and consistent, information than the feature definitions it supports. What follows is an edited version of that brief proposal.
For example
#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
回答16:
I wrote an small library to get the operating system you are on, it can be installed using clib (The C package manager), so it is really simple to use it as a dependency for your projects.
Install
$ clib install abranhe/os.c
Usage
#include <stdio.h>
#include \"os.h\"
int main()
{
printf(\"%s\\n\", operating_system());
// macOS
return 0;
}
It returns a string (char*
) with the name of the operating system you are using, for further information about this project check it out the documentation on Github.