Ready! Set! Build!
And, the Race Is On
The development race to the market place that is. As we know all too well, timeliness to the retail arena is critical to the success of any software product. One piece of the foundation to quickly obtaining a quality product is having efficient and effective software development builds.
In the last issue of The Developer Connection News, we described some basic techniques such as library control, problem tracking, common tools, and public header files. In this article, we continue to explore the critical parts of a quality build system, including communication, system configuration, local area networks (LANs), and error detection.
Your Pit Crew
You wouldn't start an Indy race without talking to your pit crew first, would you?
Communication, or the lack of, often results in delayed development schedules. To get your build out of the blocks, we strongly advise holding a short meeting just before you initiate a build. It is essential that all key players attend this meeting to discuss and determine the contents, as well as the purpose of the build (testing, Alpha, or Beta).
Tailor the formats of these communications to meet your particular needs. For example, minor development changes might only require brief interaction between developers (a casual chat in the hallway). In comparison, major function enhancements should be communicated throughout the entire development organization (a formal pre-build meeting). Some of the topics you should discuss include clearly defined output requirements, such as desired deliverable media, number of copies required for a given media type, and expected cycle time for the build. This communication between developers often provides early-warning signs of potential build problems.
Configuring Your Machine for the Long Haul
Just as a racer plans on changing the car's tires during the race, it's probable that a developer might change or upgrade their operating system at some point during the development cycle. Correct upfront build machine configuration facilitates modifications to the development environment.
It's best to keep the system and build data separate. One example is to isolate the boot drive to a single hard file. If a single hard file is not available, establish a single partition for the boot drive. This provides the ability to upgrade to a new version of an operating system at any time, for any reason. For example, you might choose to change to a new version of the operating system to gain added function or possibly just to stabilize the existing operating system. In the event that the operating system becomes corrupted, or if it becomes necessary to upgrade the operating system, it can be done quickly without interruption to other machine data. Also, keep in mind that some development tools are operating system- and version-specific.
Get Your Code on Track
Using a LAN, you can get your source code on track to becoming an executable in a highly interactive and productive environment. This beats the ol' Sneaker Net method of moving source code from developers desktop to the build machine. Owning and maintaining our own LAN provides great flexibility and reliability in a development build environment.
Using a LAN also enhances the build process by creating interactive capabilities for library control, problem tracking, source code maintenance and remote debugging. Additionally, by being responsible for maintenance of the LAN, build system modifications can be made when necessary. For instance, new build machines or servers can be added (or deleted) from the build environment at a moment's notice. This can be a nice feature, especially considering the ever changing needs of dynamic development environments.
Some LANs that you might want to explore are IBM's OS/2 LAN Server 3.0, Novell's NetWare 4.01 Server and NetWare Client 2.12 for OS/2, or Banyan Vines 5.125.5 (Server and Client).
Are Ya Good To Go?
Without a prerace inspection of your build machine, you might be destined for the dunce hat. Simple items like loose cables, insufficient disk space, and dead source can really "hang up" your build. One fool-proof way to eliminate build errors from the start is to apply the product source code to a build machine that does not contain any previous versions of source code.
After the environment and source code have been cleanly established, this is a green flag to flip the build switch to ON. Do this by invoking the master makefile with a MAKE utility. As a result, the product will compile in a predefined logical order (previously mentioned in Volume 3 of The Developer Connection News).
In the racing world, pit stops are a necessary evil. They are crucial to the success of the race. However, a bad pit stop can cost you the race. In the development world, you must be able to capture and evaluate build output information. An overlooked error or warning can cost you the build, or worst yet, the product's success. Therefore, we recommend taking the time to meticulously review the output for warnings, errors, and abnormal terminations (such as STOPS). There are several tools available that quickly search for character strings within text files. Some tools that we use frequently for this task are:
- GREP.EXE, which is on The Developer Connection for OS/2 CD-ROM within the UTIL2: AIX Like Utilities for OS/2 Productivity Tool category.
- SEEK SCAN, which is located in the OS/2 2.x Productivity folder.
After the error information is extracted from the output files, it provides a starting point for problem discovery. The component makefile usually provides a quick answer to accurate problem determination. This makefile indicates special environment settings, header files, tools, path-dependent components, and compile- and link-option information. Any one of these variables can have an adverse effect on the component, and introduce build-time errors into an executable.
Crash and Burn
Now that you have hit the wall in Turn 3, it's time to figure out what went wrong with the build. For the most part, errors can be broken down into two categories: compile and link.
Compile errors within a self-contained component, in general, are easily detected and resolved. Especially if they are syntax or source-code related. However, compile errors due to external dependencies can be more complicated and may require complete component pre-builds. This analogy also applies to link errors.
Link errors, however, are more apt to be caused by external influences such as library files. Some examples of common link errors are unresolved externals, symbol multiply defined, or library not found.
Comin' Down the Home Stretch
As the old saying goes "An ounce of prevention is worth a pound of cure." Strict adherence to the defined development process not only saves time in the long run, but additionally can dynamically reduce the amount of frustration that many developers feel as they rush to the white flag. A development process, or cycle, should be well thought out, refined, and customized to meet the needs of the development community. One good way to flush out potential public build problems is to implement component or system pre-builds for interdependent source code. Some build procedures that have worked well for us follow.
Delta all the changed files into the library, and then extract those files to verify that all changes successfully made it into that library version of the file. We use a shadow routine that automatically extracts changed files from the library to a public server on the LAN. This is done as a convenience for developers. It enables them to compile and link only the changed files. By using a shadow server, the developer has the option to test build only his changes, or all of the changes related to their source code. Thus, giving them a true picture of what the real build would be like.
After successful compilation and linkage of a component or subsystem some minimal amount of testing is recommended. The change in a file is only as good as the output it produces - hence the saying "Garbage in, garbage out." It is a good idea to verify the function of the fix, before you enter it into the public build. This reduces repetitive fixes in the public build, as well as system regression problems.
Not only are the above procedures key to implementing a build, they are also extremely helpful in determining all types of build errors. These steps might seem cumbersome at the onset, but believe us, they will save you hours of whirlwind debugging.
The Checkered Flag!
Now that you have the pre-build process and the build system to get you on your way to the Winner's Circle, one of the remaining processes is to make the sum of the parts equal to the whole. In the next issue of The Developer Connection News, we will discuss the ins and outs of post compiles, virus detection, integration, and diskette creation.
Reprint Courtesy of International Business Machines Corporation, © International Business Machines Corporation