BSM Development has detailed knowledge of the most commonly used Operating Systems including Linux, Unix, Windows, OS/390 and VMS (e.g. we have written device drivers, daemons and/or worked on internals on all of these systems), plus the hardware platforms that they run on. This allows us to perform ports of existing software, written for one of these systems, to any or all of the other systems. Furthermore, we are able help in the design and building from scratch of portable software that can be ported, in short order, to other platforms (e.g. in the past, one of the complex systems which we originally built to run on Windows NT and Novell Netware was ported to Sun OS by one person in just three weeks).
If you would like us involved in your porting project, please briefly describe it and send the description along with your contact information to BSM Development. We can help you identify the areas that will need work and/or perform the port for you. For new projects, we can indicate what steps you should follow to ensure portable code.
Successful ports do not happen by themselves but, rather, are the end result of careful and methodical preparation and follow-through. Well thought out, thorough testing procedures are also necessary because code that was previously working on one platform can be rendered inoperational by such seemingly innocuous details as reversed bit order, word size and even boundary alignment. BSM Development has the expertise to produce working ports using the above mentioned techniques plus others of a much more subtle nature, devloped over years of porting experience.
There are two basic methods that can be used to yield a properly working, portable system: starting from scratch, design a system that is meant to be portable by using generic data types and only commonly available services; or port an existing piece of software by removing or replacing all non-portable code with portable code of equivalent functionality. Incidentally, while the first method produces a clearly superior product, in terms of portability, enforcement of the rules that need to be followed is no joy. Having a knowledgable authority, such as BSM Development, who can formulate rules and then ensure adherance to them, as well as explain why they are necessitated, is key.
In either case, it is important to understand what functionality is available from each implementation platform and how any services that are used can be translated to the other implemenation platforms. This is one area where extensive experience is desirable and even required. Prior knowledge of how oft-used functions differ ever so slightly in their usage from platform to platform and what pitfalls to avoid can save a tremendous amount of time over learning on the job. Even an otherwise competent programmer but who has not done a port before can get into serious trouble with the seemingly trivial differences in service implementations from platform to platform. Having ported three major systems as well as numerous smaller programs across platforms such as Unix, Windows NT, NetWare and Linux, we know what to look for and how to make ports work.
To port existing code, one can use automated tools, such as lint, to look for platform incompatibilities. However, there is still no substitute for reading through all of the code line by line, looking for functions, etc. that aren't portable. Some of this can be done automatically by a program but much of it requires human intervention, something that we at BSM Development are well versed at. To complete the port, one essentially does what one should have done in the first place, which is to make the code portable using a number of well-known techniques.
Over the years, BSM Development has developed a set of techniques that it applies to build portable programs. The first step is to create a small number of carefully-crafted header files laying out a set of generic data types that are portable to all platforms. We have examples of such header files that we can provide to kick start your porting process.
The second step is to partition the code into two components: the service interface layer; and the algorithmic layer. The algorithmic layer is that which implements all of the program's real functionality. The service interface layer is a simple layer that we build on top of each platform which essentially becomes a common virtual machine whereupon the algorithmic layer is built. The other side of the service interface layer either passes service requests through to the underlying target OS (sometimes after massaging them slightly) or simulates those functions which are important but not supplied directly by the target OS. Often, the services provided by this layer are the lowest common denominator between all of the platforms upon which the ported software is intended to run.
In our experience, some of the services you might consider building into the service interface layer are: shared memory; Remote Procedure Call (RPC); event scheduling; handle management; a signalling mechanism such as semaphores; access to system information (e.g. user name, machine name, etc.); message delivery or Inter Process Communication (IPC); and access to a database. Once again, we can provide you with examples of which services to implement and how to do so.
Another route to producing portable systems is to build them on top of one of the portable development environments such as Java, Perl or PHP. Here too, there are pitfalls, however. For example, not all Java development environments are created equal nor do they all have the same features. Once again, the extensive porting experience of BSM Development can be utilized to identify which features are universal and can be used and which should be avoided like the plague.