All current portability helper tools were designed and written with this assumption in mind: the software must either use the platform specific features directly or suffer from serious performance loss. People were thinking that building layers around the platform differences will impose prohibitively high costs. The idea to avoid these costs is that the preprocessor is used to tune a piece of the source code specifically for the particular platform for which the software is been compiled.
However after a while some people got tired from that preprocessor instructions scattered around the code. They found them so annoying that they decided to concentrate them into one place and isolate them from the rest of the code thus creating an indirect layer. They soon realized that the performance loss was not prohibitively high; it was so low than even on very old machines the difference between the layered version and the version using the platform directly was unmeasurable except when subjecting the program to awfully large inputs.
There is another way how a program can get polluted with preprocessor directives enough to be rendered unreadable. Such a program starts its existence as a simple utility for one specific platform which was created by the autor to "scratch his itch". Then other author using another platform picks that program and ports it to his platform. An obvious way to do this is to keep the old source somewhere by side, then change the code to work on the second platform and then merge the new code into the old code so that a preprocessor symbol is used to determine which version to compile. The last merging step was done so often that GNU project added a feature which does this automatically: the --ifdef command line switch for the diff
command. After our programs gets ported to few dozens of platforms using this technique, it is so polluted with various preprocessor directives that a normal user, not familiar with preprocessor directives and the know-how allowing him to cope with them, is unable to determine, how the program is constructed and how it works. Even worse, the load placed on the maintainer of the program soon becomes so huge that the program is abandoned or the number of "low priority bugs" is constantly increasing.
I consider all these trends in the software industry to be very bad. They are locking the majority of users out of the freedom to study and change the software. The net result is that users don't value this freedom high enough to actively protect it. Therefore I decided to toss away all current portability solutions and design my own from scratch.
So OSHS does not support imakefiles, nor configure scripts directly. An interface is placed between the OSHS software and the operating system itself instead. This interface is called the OSHS kernel interface and is present (or, more precisely, appears to be present) on all supported platforms. This interface is the only thing the "normal" OSHS software is allowed to use (even the type of the CPU or the name of the underlying operating system (if any) is not available to the software unless the software is a special system tool which is not considered to be a "normal application", such as a compiler). The interface serves as an indirection level between the OSHS software and the host platform.
All the platform differences and diversities are buried deeply in the bowels of the OSHS to host communicating library called SYSLIB. This library bents all properties of each of the supported platforms in such a way that it appears as if it was supporting the OSHS kernel interface. The OSHS kernel interface appears to be supported in exactly the same way, no matter on what CPU, OS or architecture the software is working. SYSLIB achieves this goal with a plethora of advanced tricks. Giving just one example: The SYSLIB presents the application with binary files using the OSHS binary file extensions (.rmc
for compiled relocatable modules, .bpf
for programs and .rtl
for libraries) no matter which host platform it sits on. The actual binaries are hidden, only their content appears as a part of their respective OSHS binary file. The SYSLIB automatically converts the OSHS binary files to the platform specific ones as it communicates with the platform's compiler, linker and loader. This way the OSHS build system does not need to deal with different binary file specifications used by various platforms. This trick is called binary file masquerading.
The OSHS kernel interface is designed to be as small as possible but also to be flexible. It is based on ideas presented by the HURD design. The interface presents the system resources as a collection of servers which whom the program can communicate using a simple datagram protocol. This allows it to be scalable in the terms of what is directly emulated by SYSLIB and what must be done by the OSHS software itself. The program does not need to know whether on the other side of the link is sitting a real server or a "stupid library call" which handles the request itself. Therefore on one platform the calls described by the OSHS kernel interface can be real OSHS kernel calls and the real work is done by other programs while on another platform the calls are normal procedures that masquerade as an OSHS resource server. Once the results are the same, the way used to reach them is not important from the view of the application.
One implication of this appoarch is evident: if a program uses nothing but the OSHS kernel interface, it will work on any platform supported by SYSLIB. If we have a collection of programs and libraries designed to use this interface and nothing else, to port this collection it is necessary to port the SYSLIB only and then simply recompile the collection.
The second implication is that we get the cross-platform buildability at almost no cost: since the OSHS interface is the same on the host platform as on the target platform, we don't have to probe for features first (or to guess them if the probing is impossible) so we can just go on with the build process. Effectively this enables us to be able to crossbuild all software on all pairs of the supported platforms: a thing that is impossible to reach with appoarches like the one in autoconf
.