|< Day Day Up >|
As previously discussed, porting is an activity of moving a custom application, written in one or more programming languages, to a new operating system (OS). This activity relates primarily to creating a new executable that is compatible with the new OS. This is accomplished by modifying the application programming interfaces (APIs) used by the software so that they conform to or match the APIs offered by the new OS while maintaining similar functionality.
A detailed understanding of the application logic is not necessary for this task. Instead, familiarity with the development tools and the linkers and library technology that exist for the target environment is required because the porting effort is primarily one of modifying, compiling, and linking the application to the new OS.
The first step in porting an application is to identify which APIs are incompatible with the new OS and need to be rebuilt. Once you flag an API as being incompatible, you must develop a solution for a compatibility library that you can use to replicate the functionality that existed on the old platform. You can then modify the source code of the application to use the new API, as defined in the compatibility library, wherever the older incompatible version occurs.
In the following sections, we describe how to create a build environment on the target system. In addition, we explore some of the issues associated with creating the new application executable and discuss nondestructive methods of transforming the code.
Creating a Target Build Environment
The development environment is composed of the development tools, the source code for the application, and any third-party products that are required to create the application. It also includes the hardware to support the developers who will use the tools to create the application executable and the supporting application infrastructure.
When migrating custom-written applications, you must also migrate the development environment to the new target environment. To migrate the build environment, perform the following tasks :
Prepare the Hardware Environments
The development environment is usually created on nonproduction hardware. Although the development hardware can be purchased with the production hardware, it will almost certainly be required before the production hardware. Arrangements must be made to ensure that the hardware used in the development environment is delivered in a timely manner. However, keep in mind that large production environments require significant installation and verification efforts. Because of this, they must be acquired long before they are actually scheduled for use. The vendor's sales representatives can assist you in determining the lead time required for the acquiring and installing both the development and production hardware environments.
Although the porting process can involve significant effort that uses numerous resources, the development environment should be sized to support steady-state development and maintenance rather than the loads created by the one-time-only migration effort. It might be possible to lease equipment to support the migration activity, but care must be taken to ensure that the following items are sufficient for your project:
Identify the Software to Use in the New Environment
The target build software environment generally consists of the following items, which you should identify before beginning the porting exercise:
Acquire a Recent Reference Build Log
The best way to ensure that you fully understand the build environment is to acquire a build log that was created when the application source that you are going to port was last compiled. There are two main reasons for acquiring a build log of the source that you are transforming:
Plan to Acquire and Install Tools and Utilities
For the purposes of creating the build environment, the build log is useful in that it specifies all the tools and utilities that are required to create the application executable. You will have to acquire new versions of these products that will run under the new target OS from the various software vendors . Lead times for acquiring products can vary, so some effort must be put into ensuring that the required hardware and software products are available before the porting effort is begun. Training might also be required for any new tools that are going to be used and should be arranged and delivered so that training does not impact the migration schedule.
When installing the new software, examine the make files and the build logs that were used or created on the old platform. Installing the new products in the same location under the new environment might reduce or minimize changes that have to be made to hard-coded paths in scripts or make files.
Access to documentation that describes the tools and APIs of the old environment is essential because the behavior of the old tools must be well understood . Although it is not a necessity, it can be useful to have access to the old environment if you need to verify how things were done on the old system.
Once the development environment is installed, create and compile several test examples to ensure that executables perform as required.
It is now time to install the source code control system and populate it with the source that is to be transformed. Mark or label the source in the repository to ensure that you can quickly go backwards if you need to compare a modified version of the source to the original code. In addition, ensure that you have tools like Perl, the sed commands, and shells to automate source code transformation.
Building a New Application for the Target Platform
Once you've verified that the development environment is functioning correctly, you can start to build the application. Ideally, the process used to build an application should be well documented. However, frequently, this is not the case. If build documentation does exist, it might not be current or reflect the latest changes that have been implemented to the code or to the build process. The advantage of having a reference build of the application is the understanding that you will be porting the application as it is configured in that reference snapshot of the code.
As mentioned previously, much of the information about how an application should be built can be obtained from the make files and the reference build log that were created when the application was built on the old system.
Building the application results in the creation of an application executable. The functionality provided by the application can depend on a number of different elements of the build process. The output of the build process usually depends on one or more of the following items:
The following paragraphs explain possible dependencies that exist for the preceding items:
Create a Compatibility Library
You should use a compatibility library to replicate the functionality of the old environment. Doing so will minimize the amount of change that will have to be made to the source code base. A compatibility library might be available from the vendor of the new system, or it can be created by the migration team that is transforming the code.
When migrating to the Solaris OS, consider using the tools and migration kits found at http://www.sun.com/migration. The following example shows how to create a function to minimize the change to an application to an application that was written for an HP-UX environment that is being ported to the Solaris environment.
Table 7-2. Compatibility Library Sample
APIs can vary among operating systems in a number of different ways:
Again, when attempting to port or transform code, attempt to minimize the changes that have to be made to the application logic, and use compatible functions whenever possible to minimize implementation errors.
Sun has created a set of compatibility libraries to assist developers port from some common operating systems. An example is the Solaris OE Implementation for HP-UX API. It implements a set of commonly used HP-UX functions for Solaris/SPARC ¢ or Solaris/x86. It is available at http://www.sun.com/migration/hp_ux/tools/hpuxapi.html. To use these libraries, simply download the file and unzip it in your directory. The following content will be created under the directory:
For a complete list of included functions, visit http://www.sun.com/migration/hp_ux/tools/emulation.html.
Modify the Make Environment
Complex applications can contain millions of lines of code. Well-written applications are usually implemented as a number of modules that are broken down along functional lines. Each module is usually contained in its own subdirectory. The code in each subdirectory might be dependent on another subdirectory within the application, as well as on libraries or header files provided by the system.
Building the application should be a monolithic activity that is performed at a high level within the source tree. Rather than starting at the bottom of the tree (the leaf nodes) and building each component from the bottom up, the structure of the build environment should be such that the application can be built from the root node of the source code tree.
Although a little more work will have to go into coordinating the make files at a lower level with those higher up in the tree, the effort will be worthwhile because the location of include files, compiler options, and so forth can be assigned at one higher level and inherited through the use of include directives by those at a lower level in the source hierarchy. This minimizes the opportunity for errors to creep into the build process, because all definitions are created at a high level.
Understand the Application Configuration
Applications frequently require configuration information. They might read this data from a configuration file, or they might obtain it dynamically from the environment by using a getenv() call. In addition, configuration files might contain data that is environmentally dependent, meaning that it will have to change when you change platforms or operating systems. Be sure to review the data within the configuration file with experts on the current environment who are knowledgeable about the application on the new environment. For example, Oracle configuration options differ depending on whether you implement your solution on the Solaris OS or HP/UX. Attempting to determine the correct configuration data for an application requires a detailed understanding of the application logic, which the porting team might not have. Remember, relying on individuals who are knowledgeable in the application and its configuration ensures the most productive use of resources.
Deciding Whether to Support Backward Compatibility
When modifying the code base for an application during a migration, you must decide whether the new code base will be able to function in the old environment. This is known as backward compatibility. After the migration, the same source code could be used in the old build environment to produce an application executable targeted for the old platform, or the same source base could be used in the new build environment to support the new platform.
In the source code base, backward compatibility is accomplished by nondestructive source code modification, usually implemented through the use of conditional compilation, as illustrated in the following code fragment. _sun is predefined by the Solaris compiler.
Table 7-3. Backward Compatibility Example
Backward compatibility within a source code base can reduce the amount of work that has to be done by the development staff. If a single source code base is created that can support both the old and the new environments, changes resulting from new requirements or changing business logic only have to be implemented once in the source code.
While code that is heavily modified to include conditional compilation directives can be hard to read and maintain, the benefits of using conditional compilation directives far outweigh the cost. In fact, migrating to the Solaris OS does not usually require significant code modification.
|< Day Day Up >|