2012-07-05 3 views
18

Verwandte Fragen
How can I detect the operating system in C/C++?Wie kann ich feststellen, ob das Betriebssystem POSIX in C ist?

Wie kann ich herausfinden, was Betriebssystem ich unter in GCC leite oder in ANSI C?

Mir geht es gut Wenn ich wissen kann, ob ich auf POSIX laufe.


UPDATE:

Es hat keinen Unterschied für mich nicht, ob es bei der Kompilierung oder zur Laufzeit ist. Ich benutze dies in einer Debug-Routine, so dass die Leistung nicht so wichtig ist.

Ich bin auf der Suche nach dem Pfadtrennzeichen. Windows & Unix/Linux/BSD wäre in Ordnung.

Und ich versuche, den Basisnamen auf einem Pfad zu finden. Ich habe einige Lösungen gefunden, aber die Lösungen beinhalten viele Includes, die ich nicht möchte. Ich werde mod up this solution.


Ich bin auf Mac OS X 10.4.11 und nach this URL, ich ausgeführt und bekam die folgende Ausgabe:

mac $ touch myfile.c 
mac $ gcc -std=c99 -E -dM myfile.c 
#define __DBL_MIN_EXP__ (-1021) 
#define __FLT_MIN__ 1.17549435e-38F 
#define __CHAR_BIT__ 8 
#define __WCHAR_MAX__ 2147483647 
#define __DBL_DENORM_MIN__ 4.9406564584124654e-324 
#define __FLT_EVAL_METHOD__ 0 
#define __DBL_MIN_10_EXP__ (-307) 
#define __FINITE_MATH_ONLY__ 0 
#define __GNUC_PATCHLEVEL__ 1 
#define __SHRT_MAX__ 32767 
#define __LDBL_MAX__ 1.79769313486231580793728971405301e+308L 
#define __APPLE_CC__ 5367 
#define __UINTMAX_TYPE__ long long unsigned int 
#define __LDBL_MAX_EXP__ 1024 
#define __SCHAR_MAX__ 127 
#define __USER_LABEL_PREFIX__ _ 
#define __STDC_HOSTED__ 1 
#define __LDBL_HAS_INFINITY__ 1 
#define __DBL_DIG__ 15 
#define __FLT_EPSILON__ 1.19209290e-7F 
#define __LDBL_MIN__ 2.00416836000897277799610805135016e-292L 
#define __ppc__ 1 
#define __strong 
#define __APPLE__ 1 
#define __DECIMAL_DIG__ 33 
#define __LDBL_HAS_QUIET_NAN__ 1 
#define __DYNAMIC__ 1 
#define __GNUC__ 4 
#define __DBL_MAX__ 1.7976931348623157e+308 
#define __DBL_HAS_INFINITY__ 1 
#define __STRICT_ANSI__ 1 
#define __weak 
#define __DBL_MAX_EXP__ 1024 
#define __LONG_LONG_MAX__ 9223372036854775807LL 
#define __GXX_ABI_VERSION 1002 
#define __FLT_MIN_EXP__ (-125) 
#define __DBL_MIN__ 2.2250738585072014e-308 
#define __DBL_HAS_QUIET_NAN__ 1 
#define __REGISTER_PREFIX__ 
#define __NO_INLINE__ 1 
#define _ARCH_PPC 1 
#define __FLT_MANT_DIG__ 24 
#define __VERSION__ "4.0.1 (Apple Computer, Inc. build 5367)" 
#define __BIG_ENDIAN__ 1 
#define __SIZE_TYPE__ long unsigned int 
#define __FLT_RADIX__ 2 
#define __LDBL_EPSILON__ 4.94065645841246544176568792868221e-324L 
#define __NATURAL_ALIGNMENT__ 1 
#define __FLT_HAS_QUIET_NAN__ 1 
#define __FLT_MAX_10_EXP__ 38 
#define __LONG_MAX__ 2147483647L 
#define __FLT_HAS_INFINITY__ 1 
#define __STDC_VERSION__ 199901L 
#define _BIG_ENDIAN 1 
#define __LDBL_MANT_DIG__ 106 
#define __WCHAR_TYPE__ int 
#define __FLT_DIG__ 6 
#define __INT_MAX__ 2147483647 
#define __LONG_DOUBLE_128__ 1 
#define __FLT_MAX_EXP__ 128 
#define __DBL_MANT_DIG__ 53 
#define __WINT_TYPE__ int 
#define __LDBL_MIN_EXP__ (-968) 
#define __MACH__ 1 
#define __LDBL_MAX_10_EXP__ 308 
#define __DBL_EPSILON__ 2.2204460492503131e-16 
#define __INTMAX_MAX__ 9223372036854775807LL 
#define __FLT_DENORM_MIN__ 1.40129846e-45F 
#define __PIC__ 1 
#define __FLT_MAX__ 3.40282347e+38F 
#define __FLT_MIN_10_EXP__ (-37) 
#define __INTMAX_TYPE__ long long int 
#define __GNUC_MINOR__ 0 
#define __DBL_MAX_10_EXP__ 308 
#define __LDBL_DENORM_MIN__ 4.94065645841246544176568792868221e-324L 
#define __PTRDIFF_TYPE__ int 
#define __LDBL_MIN_10_EXP__ (-291) 
#define __LDBL_DIG__ 31 
#define __POWERPC__ 1 
mac $ 
+1

Mehr, die vorhandene ist etwa bei Compiler Zeit statt, die dieses über Erkennung zur Laufzeit zu sein scheint. Entschuldigung für die unangebrachte enge Abstimmung. Erneute offene Abstimmung – dmckee

+0

Erneut die Frage geöffnet :) –

+0

Möchten Sie dies zur Laufzeit oder zur Kompilierzeit feststellen? – netcoder

Antwort

22

Die Single UNIX Specification erfordert die Existenz von unistd.h, die sagen kann, Sie die POSIX-Version (über das _POSIX_VERSION Makro).

Aber wie können Sie unistd.h einschließen, wenn Sie noch nicht wissen, dass Sie tatsächlich auf einem UNIX kompilieren?

Das ist, wo this GCC document kommt praktisch. Demnach sollte das Testen auf das Vorhandensein oder das Auswerten von __unix__ Ihnen sagen, dass das System ein UNIX ist. Also:

#ifdef __unix__ 
/* Yes it is a UNIX because __unix__ is defined. */ 

#include <unistd.h> 

/* You can find out the version with _POSIX_VERSION. 
.. 
.. */ 

#endif 

__unix__ definiert sich nicht auf Mac OS X, so zu Konto für das, könnten Sie stattdessen tun:

#if defined (__unix__) || (defined (__APPLE__) && defined (__MACH__)) 

Um eine Liste der systemspezifischen vordefinierten Makros auf Ihrem System zu erhalten, können Sie ausführen kann:

cpp -dM /dev/null 

Zum Beispiel meines GNU/Linux-System auch definiert zusätzlich __linux__ und __gnu_linux__ abgesehen von __unix__ und eine Menge anderer Sachen.


Ein weiteres nützliches Dokument, das Sie auf this Wiki ist aussehen muss.

Es goes on to present a way of detecting the presence and version of POSIX in einer Weise ähnlich der oben beschriebenen.


EDIT: Da Sie wirklich alles, um dies zu tun, weil Sie die Verzeichnistrenner zu verwenden, schauen Sie sich this URL entscheiden wollen. Dort heißt es:

Hinweis Datei-I/O-Funktionen in der Windows-API-convert "/" auf "\" als Teil von den Namen auf einen NT-Artnamen Umwandlung, es sei denn, die mit „\ ? \ "Präfix wie in den folgenden Abschnitten beschrieben.

ich nicht Programm unter Windows, oder weiß viel etwas darüber, so kann ich nicht sagen, dass ich auf diese überhöht habe. Hier

+3

Nun, Sie wissen, dass UNIX (meistens) POSIX ist, aber es bedeutet nicht, dass Nicht-UNIX nicht POSIX ist. – netcoder

+7

'unistd.h' definiert die' _POSIX_ * 'Makros. UNIX ist POSIX, also gibt es sicher ein "unistd.h". Mein Punkt war, dass Sie ein POSIX-kompatibles System haben könnten, das nicht UNIX ist, wo "__unix__" nicht definiert wäre (Spekulationen wirklich). Kurz gesagt, POSIX ist kein UNIX. ;-) – netcoder

+0

@netcoder - Ich ging umgekehrt vor. Ich wollte sicher sein, dass "unistd.h" überhaupt da ist *, bevor ich es einfügen kann und die POSIX-Version sehe. Schließlich war der einzige "sichere" Weg, den ich sehen konnte, nach "__unix__" zu suchen. Aber Sie haben Recht (POSIX! = UNIX), ich würde nicht sagen, dass es kugelsicher ist. – ArjunShankar

0

ist das, was ich am Ende mit:

#include <stdio.h> 
/* 
NAME 
    basename -- return pointer to last component of a pathname 

Distribution: This function is in the public domain. 

Origin of function: 
http://www.koders.com/c/fidEB79B7607A210C3BB7B813E793465F9D469AE912.aspx 


SYNOPSIS 
    char *basename (const char *name) 

DESCRIPTION 
    Given a pointer to a string containing a typical pathname 
    (/usr/src/cmd/ls/ls.c for example), returns a pointer to the 
    last component of the pathname ("ls.c" in this case). 

Restrictions: 
    Presumes a UNIX or DOS/Windows style path with UNIX or DOS/Windows 
    style separators. 
*/ 

/* 
NAME: 
    basename: 

Function: 
    return pointer to last component of a pathname 

Distribution: 
    This function is in the public domain. 

Origin of function: 
    http://www.koders.com/c/fidEB79B7607A210C3BB7B813E793465F9D469AE912.aspx 


SYNOPSIS: 
    char *basename (const char *name) 

DESCRIPTION: 
    Given a pointer to a string containing a typical pathname 
    (/usr/src/cmd/ls/ls.c for example), returns a pointer to the 
    last component of the pathname ("ls.c" in this case). 

Restrictions: 
    Presumes a UNIX or DOS/Windows style path with UNIX or 
    DOS/Windows style separators. 
    Windows volumes are only a-zA-Z. 
    The original code suggests ISALPHA. 

*/ 

char * basename (const char *name) 
{ 
const char *base; 
// predefined OS symbols 
// http://sourceforge.net/apps/mediawiki/predef/index.php?title=Operating_Systems#UNIX_Environment 

#ifndef DIR_SEPARATOR 
# define DIR_SEPARATOR '/' 
#endif 

#ifndef DIR_SEPARATOR_2 
# define DIR_SEPARATOR_2 '\\' 
#endif 

// Check if we are running Unix like os 
// else assume Windows. Note if we guess wrong, it's not 
// so bad because Windows includes the Unix separator. 
#if defined (__unix__) || (defined (__APPLE__) && defined (__MACH__)) 
# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) 
#else 
# define IS_DIR_SEPARATOR(ch) \ 
(((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) 
/* Skip over the disk name in MSDOS pathnames. */ 
if (isalpha(name[0]) && name[1] == ':') 
    name += 2; 
#endif 


for (base = name; *name; name++) 
    { 
    if (IS_DIR_SEPARATOR (*name)) 
     { 
     base = name + 1; 
     } 
    } 
return (char *) base; 
} 




int main (int argc, const char * argv[]) { 
    /* Return the basename of a pathname. */ 


#define S1 "/usr/src/cmd/ls/ls.c" 
#define S2 "/usr/src/cmd/ls/abc" 
#define S3 "a:/usr/src/cmd/ls/def" 
#define S4 "ghi" 
#define S5 "jkl.txt" 
#define S6 "d:\\usr\\src\\cmd\\mno.txt" 
#define S7 "d:pqm.txt" 

printf(S1 " \t is %s\n",basename(S1)); 
printf(S2 " \t is %s\n",basename(S2)); 
printf(S3 " \t is %s\n",basename(S3)); 
printf(S4 " \t is %s\n",basename(S4)); 
printf(S5 " \t is %s\n",basename(S5)); 
printf(S6 " \t is %s\n",basename(S6)); 
printf(S7 " \t is %s\n",basename(S7)); 
    return 0; 

}

2

Es ist möglich, Ihr Problem zu lösen autoconf tool mit der Anwesenheit von unistd.h zu entdecken und dann möchte hinzufügen, eine #define HAVE_UNISTD_H 1 Linie in einem dynamisch erzeugten config.h wenn unistd.h gefunden wurde, aber ich finde, dass autoconf ist ein wenig schwer zu bedienen, und ist sehr veraltet. Wenn Sie zufällig cmake verwenden, können Sie es auf die gleiche Weise lösen. Sie könnten ein config.h.in enthält so etwas wie dies erstellen:

#ifndef CONFIG_H 
#define CONFIG_H 

#cmakedefine HAVE_UNISTD_H 1 

#endif 

Und CMakeLists.txt das Projekt würde wie folgt aussehen:

project(MyApp) 

include(CheckIncludeFiles) 
check_include_file("unistd.h" HAVE_UNISTD_H) 

configure_file(config.h.in config.h @ONLY) 

add_executable(${PROJECT_NAME} main.c) 

und dann von der Kommandozeile zu generieren:

cmake . -G"Unix Makefiles" 

oder Xcode-Projekt generieren (nur OSX):

cmake . -G"Xcode" 

oder ein Visual Studio 2013-Lösung Projekt (nur Windows) generieren:

cmake . -G"Visual Studio 12 2013 Win64" 

Cmake Generatoren = epic

Wenn Ihr Betriebssystem POSIX ist, dann config.h sollte wie folgt aussehen erzeugt gewinnen :

#ifndef CONFIG_H 
#define CONFIG_H 

#define HAVE_UNISTD_H 1 

#endif 

Ansonsten wird es so aussehen:

#ifndef CONFIG_H 
#define CONFIG_H 

/* #undef HAVE_UNISTD_H */ 

#endif 

Und dann können Sie zu Ihrem vertrauenswürdigen erzeugt config.h:

#include "config.h" 

#if HAVE_UNISTD_H 
# include <unistd.h> 
#endif 

int main (int argc, const char * argv[]) 
{ 
#if defined(_POSIX_VERSION) 
    /* POSIX code here */ 
#else 
    /* non-POSIX code here */ 
#endif 
    return 0; 
} 
Verwandte Themen