Declaring the Unix flavour in C/C++
How do I declare in C/C++ that the code that is written is to be buil开发者_JAVA技巧t in either HP-UX or Solaris or AIX?
I found that, a good way to figure this king of question, is, at least with gcc, to have this makefile:
defs:
g++ -E -dM - < /dev/null
then, :
$ make defs
should output all the definitions you have available.
So:
$ make defs | grep -i AIX
$ make defs | grep -i HP
should give you the answer. Example for Linux:
$ make defs | grep -i LINUX
#define __linux 1
#define __linux__ 1
#define __gnu_linux__ 1
#define linux 1
Once you found the define you are looking for, you type at the beginning of your code:
#if !(defined(HP_DEFINE) || defined(AIX_DEFINE) || defined(SOLARIS_DEFINE))
# error This file cannot be compiled for your plateform
#endif
How about a macro passed to the compiler ?
i.e. gcc -Dmacro[=defn]
Then test for the macro in your code with a simple #ifdef
of #if
(if you've given it a value). There may already be a predefined macro for your target platform as well.
[EDIT: Put some of my comments here in my answer that explain how -D
works]
-Dmacro[=defn]
on the command line for the compiler is the same as having #define macro defn
in the code. You expand it out like this: -Dfoo=bar
is equivalent to #define foo bar
. Also, the definition is optional so -Dfoo
is equivalent to #define foo
.
Be careful about how you handle this. You should identify the features of the O/S that you want to use by feature, not by O/S, and write your code accordingly. Then, in one header, you can identify which of the features are available on the O/S that you are compiling on. This is the technique used by autoconf, and even if you do not use autoconf itself, the technique it espouses is better than the platform-based technique. Remember, the features found on one O/S often migrate and become available on others too, so if you work by features, you can adapt to the future more easily than if you work solely on the O/S.
You also have to write your code appropriately, and portably. Isolate the O/S dependencies in separate files whenever possible, and code to an abstract O/S interface that does what you need. Taken to an extreme, you end up with a Java JVM; you don't need to go that far, but you can obviate most of the problems.
Take a look at portable libraries like the Apache Portable Runtime (APR) library.
And write your code along the lines of:
#ifdef HAVE_PWRITE
...code using pread() and pwrite()...
#else
...code using plain old read() and write()...
#endif
This is a grossly over-simplified example - there could be a number of fallbacks before you use plain read() and write(). Nevertheless, this is the concept used in the most portable code - things like GCC and Apache and so on.
Perhaps a less convoluted solution that some of those suggested is to consult Pre-defined C/C++ Compiler Macros. This site provides an extensive list of compiler macros for a large number of compiler/OS/Architecture combinations.
精彩评论