Learn about issues and tips for porting C and C++ applications to the Solaris OS. Contents
Introduction
This article discusses porting C and C++ applications to the Solaris OS. While it generally addresses porting from any OS/hardware platform to the Solaris OS (on either SPARC or x86), the most commonly expected cases are ports from Linux/x86 to Solaris/x86 and from Solaris/SPARC to Solaris/x86. Issues
Porting an application deals with differences caused by a change in these factors:
Operating System and Build Environment Issues
When porting from Linux or other Unix platforms, the interfaces will be nearly the same, although there are still some minor differences to accommodate. Build Environment
Before actually porting any source code, the first step is to locate the correct version of all of the necessary third-party utilities and libraries needed to build the application. Common examples are:
Many of the open-source utilities used on other platforms are already integrated in Solaris in
File Locations
The build environment needs to be modified for the different location of include files, libraries, and user-level commands between the platforms. For Solaris, $PATH should likely include:
Runtime libraries are found in the corresponding For historical reasons, the Solaris OS also provides include files and runtime libraries compatible with SunOS 4.X, in Other small interface differences will be obvious during compiling and linking, which makes them comparatively easy to find (and fix). A few examples are:
Runtime Differences
Other differences, however, might not be obvious until execution time. For example, by default the Solaris OS does not restart interrupted system calls. To get this behavior, instead of registering a signal handler with
Another difference, from Linux for example, is that the various implementations of Any code using While not strictly a difference between platforms, it's not uncommon for a platform port to uncover latent bugs in the application -- for example a bad pointer
or buffer overrun corrupting the heap. These problems might require manual investigation using a debugger, however the Solaris OS also provides Compiler and Build Environment Issues
Choosing a Compiler
Before considering the details of compiler differences, you must first determine which compilers to use. For C, you can mix object code from compilers from different vendors. However C++ compilers do not implement identical ABIs, so the entire application should be built with the same brand of C++ compiler. For example, if your application depends on a library built with GNU C++, you should build your application with a GNU C++ compiler as well. For C++, changing to a new compiler can sometimes be as difficult as porting to a new OS. Thus, if you are porting from Linux/GNU, you should carefully consider if you should use the GNU compiler on the Solaris OS as well. Similarly, the Sun Studio compilers are supported on Linux, so it would also be reasonable to use Sun Studio tools on both platforms. If you choose to port from GNU to Sun Studio (for multithreaded debugging, performance analysis, and Sun support), a reasonable strategy would be to port in two steps, first using GNU compilers and then migrating to Sun Studio compilers, rather than tackling both changes at once. Compiler Options
If you are migrating to the Sun Studio compilers, the first visible difference is that they accept different command-line options. This is a minor technical hurdle, but it might require some parameterization of the existing makefiles. Refer to the Compiler Option appendix in the C User's Guide and in the C++ User's Guide for an explanation of the compiler switches in the Sun Studio compilers. After the port is functional, reference the paper Selecting The Best Compiler Options to find the right options for your production build. Conditional Compilation
If the application has been previously ported to some alternate operating system, hardware platform, or compiler, then it probably already contains #ifdefs to isolate the port-specific code sequences. This makes porting to the Solaris OS easier for a couple of reasons. First, code that runs on multiple platforms has already been generalized away from platform-specific dependencies. Second, the specific areas that have been previously #ifdef'd have already been identified as the areas most in need of inspection for the Solaris port. For the common case where an application has been released on Solaris/SPARC and Linux/x86, porting to Solaris/x86 may mostly be an exercise in selecting the correct set of #ifdefs from the existing sequences. One issue, however, is that existing code might have been written assuming that both sun and solaris imply SPARC and that linux implies x86. Therefore an existing conditional code sequence might look like this:
Obviously, however, this would be incorrect for Solaris/x86. Instead, there should be distinct discriminants for both hardware architecture and operating system. The most robust solution is for your build environment to define these symbols, because they can be made to work with any compiler on any platform. As a shortcut in the common cases, you could take advantage of symbols defined by both the GNU and Sun Studio compilers. Both sets of compilers provide a common definition of the symbol sun when on Solaris (as compared to linux for Linux). Both define __sparc for the SPARC architecture. And both sets of compilers define the symbols __i386 and __x86_64__ for the 32-bit and 64-bit x86 platforms, respectively. Using these symbols, the corrected example would be:
Language Issues
Current C++ compilers recognize slightly different definitions for the C++ language. They all strive to conform to the ISO C++ standard, but most compilers implement some extensions and the standard allows some features to be implementation defined. When these particular features are used in the source (either purposefully or inadvertently), they must be dealt with during porting. Later releases of Sun Studio compilers incorporate many of the GNU extensions, so using a newer version of Sun Studio will reduce the number of porting issues. However, some issues must be found and fixed manually. Most of these language differences cause compiler diagnostics where the error/warning message explains the problem. The code can then be rewritten to match the well-defined areas of the ISO standard. Sometimes, however, the problem is sufficiently subtle that it requires research to understand what is wrong or how to fix it. For those so inclined, a copy of the C++ standard is the definitive source for investigating the language rules. However, an easier and often effective technique is to use an Internet search engine to find discussions about the error message. Finally, if you're not sure if the compiler is correctly accepting or rejecting a particular language construct, you can ask questions at the Sun Developer Network Tools Forum. Library Issues
When porting C++ using Sun Studio tools, you must decide whether to use the default C++ Standard Library or the newer stlport4 library. The newer library provides better standards conformance and often better performance, but might require source changes (thus adding to your porting effort). For a discussion of the nuances of using and packaging the STLport library, see Using and Redistributing Sun Studio Libraries in an Application. Hardware Architecture
Instruction Set Architecture
The most obvious hardware issue is the different instruction set architecture, which requires the conversion of any hand-generated assembly code. While there's no shortcut for removing all of it, there are several important cases where it might make sense to replace, rather than port, the assembly code:
Aside from the work needed to port assembly code to a new ISA, a change in toolset can also cause porting issues. Both Sun Studio and GNU compilers support the single-string GNU provides extensions to the Another ISA issue comes from the functional differences in the graphics and vector capabilities of the underlying architecture (for example, SSE on x86 platforms or VIS on SPARC platforms). Generally, these differences should be hidden within libraries (for example, Sun Performance Library). Finally, when porting from SPARC to x86 platforms, numerical results might differ due to the use of x86 80-bit floating-point calculations. To minimize these differences (and generally speed up computations), use Byte Order
Byte order or endian-ness refers to the ordering of individual bytes within multibyte data. This can be a porting issue when data is reinterpreted as a different type within a single process (for example, if an array of char is interpreted as type long) or between multiple processes when the memory image of a multibyte datatype is written directly to a file or socket. The two byte orderings are big-endian (for example SPARC and PowerPC platforms, where the most significant byte of an integer is stored in the lowest address), and little-endian (for example, x86/x64 platforms, where the least significant byte of an integer is stored in the lowest addressed location). This issue is usually solved by changing the application to always use a consistent byte ordering for shared multibyte data. Alignment
Another processor-related issue is data alignment, where multibyte data needs to be stored on some minimally aligned address. As a general rule, SPARC platforms require data alignment to equal data size: two-byte types must be on a two-byte boundary, and four-byte types must be on a four-byte boundary. On other processors like the x86/x64, the hardware handles misaligned data, but there might be a performance penalty. The compilers automatically arrange for data to be appropriately aligned, by adding padding within structs and before static data locations, and by the initial location of the stack and heap. However, alignment problems can be introduced via casting, for example, by taking the address of an arbitrary element of a char array and interpreting it as the address of an element of type double. The highest performance and most general solution is to change the logic of the application to maintain correct alignment. However, on SPARC platforms
it might be reasonable (at least during the initial stages of the port) to have the Sun Studio compilers convert multibyte loads and stores into a sequence of smaller accesses via the For More Information
For more information on related topics, see: | |||||||||||||||||
|