Vijay
Vijay

Reputation: 67291

Declaring the Unix flavour in C/C++

How do I declare in C/C++ that the code that is written is to be built in either HP-UX or Solaris or AIX?

Upvotes: 3

Views: 330

Answers (4)

PierreBdR
PierreBdR

Reputation: 43294

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

Upvotes: 15

Clifford
Clifford

Reputation: 93534

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.

Upvotes: 0

Adisak
Adisak

Reputation: 6926

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.

Upvotes: 4

Jonathan Leffler
Jonathan Leffler

Reputation: 754490

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.

Upvotes: 3

Related Questions