开发者

Declaring the Unix flavour in C/C++

开发者 https://www.devze.com 2022-12-14 14:30 出处:网络
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,

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号