home *** CD-ROM | disk | FTP | other *** search
/ ftp.muug.mb.ca / 2014.06.ftp.muug.mb.ca.tar / ftp.muug.mb.ca / pub / muuglines / source / softport / softpor1.txt next >
Text File  |  1993-05-08  |  6KB  |  124 lines

  1. Writing Software for Portability, Part 1
  2.  
  3. By Gilbert Detillieux, Info West Inc.
  4.  
  5. As the computer industry continues to evolve at an ever
  6. increasing pace, old systems and their software are becoming
  7. obsolete more quickly.  The move to open systems technology
  8. and decreasing hardware costs make it feasible to throw out
  9. old hardware and entirely replace it every few years.  But,
  10. what about our investment in software?  The cost to produce
  11. and maintain it is increasing, and the complexity of the
  12. software is also increasing.  To avoid having our software
  13. become obsolete too quickly, we have to design it so it will
  14. survive the transition to new systems.  We must make it
  15. portable.
  16.  
  17. What does software portability mean?  First, software must
  18. be machine independent, so it can easily move to different
  19. hardware architectures and systems of different scales, from
  20. micros to mainframes.  It also should be operating system
  21. independent, as much as possible, since this also will
  22. change with time and with hardware changes. Software also
  23. should be designed to be independent of the environment in
  24. which it runs -- user interfaces and interfaces to other
  25. programs it interacts with can change.  It should also be
  26. independent of language and country specific features, if it
  27. will be used internationally. Finally, it should have
  28. version independence -- it should survive changes in
  29. hardware, operating system, and programming language version
  30. changes, as well as changes in its own code.
  31.  
  32. The selection of the right programming language is
  33. important.  A high level language is essential to assure
  34. machine independence, but it's important that this language
  35. follows industry standards, such as those set by ANSI and
  36. the ISO.  Also, pick a language that will fit into corporate
  37. standards and coding practise, and that will be available on
  38. all your target systems.  Avoid non-portable features, such
  39. as a particular compiler's language extensions, or ill-defined
  40. or implementation dependent features in a language.
  41. The last thing you want is to rely on a side-effect of an
  42. operator or other non-standard feature that will break when
  43. compiled on another system.  Also avoid standards or
  44. language features that are too new, since these aren't yet
  45. widely supported or may change in future standards.  A good
  46. choice for UNIX systems is ANSI C, but there might be other
  47. choices that are reasonable for your situation.
  48.  
  49. Regardless of language, structure and modularity are
  50. important.  Use a top-down design consisting of small
  51. independent code modules.  If your language supports them,
  52. use header files for public declarations of module
  53. interfaces.  Use these headers in modules that will need
  54. these interfaces, as well as in the module that defines them
  55. -- this ensures consistency in the declarations.  Header
  56. files should not result in storage allocation or code
  57. generation -- i.e. they should only declare variable and
  58. functions, not define them.  If the system has standard
  59. headers for declaring library routines and system calls, use
  60. them -don't make assumptions about these by declaring them
  61. yourself.
  62.  
  63. With a well structured program, only a few low-level modules
  64. will be machine dependent or system dependent -- the higher
  65. level code should all be portable.  These low-level modules,
  66. on the other hand, should be general enough to be reusable
  67. in any application.  There should be a clear line between
  68. the high-level, application specific but portable code, and
  69. the low-level, application independent but machine specific
  70. code. System calls, and other non-portable constructs,
  71. should only occur in the low-level modules.  You might have
  72. to create stubs to handle missing features on a particular
  73. system -- these should either fake the missing feature or
  74. return an error to the higher level modules to say this
  75. feature isn't supported.
  76.  
  77. You also might need optional modules, that will be linked in
  78. only if certain system-specific features will be required.
  79. This might be the case for interfaces to other programs,
  80. such as mailers or spoolers, for example.  You can design
  81. plug-in replacements that will be selected based on the
  82. system configuration (such as a mailer interface to either
  83. SMTP or UUCP, or a spooler interface to either LP or LPR).
  84.  
  85. If your language supports conditional compilation
  86. constructs, you can use these to further isolate machine
  87. dependencies within modules.  That way, one source module
  88. can support several systems, by simply selecting the right
  89. parts to compile.  (If your language doesn't support
  90. conditional compilation, but you're developing on UNIX,
  91. consider using the C preprocessor or M4 on your source files
  92. to get that capability.) As much as possible, use pre-defined
  93. constants and macros as switches to control
  94. compilation of system specific features.  (The C
  95. preprocessor usually defines a few symbols for the target
  96. operating system and architecture, such as "unix" and
  97. "sparc".)  If required, you can define your own constants
  98. and macros, either as compilation switches, or to define
  99. system specific quantities.  Make all such definitions easy
  100. to find and change -- don't bury them all over the place, but
  101. rather put them in a configuration header file, so they are
  102. localized and editing for a new configuration is kept to a
  103. minimum.  (This not only saves time, but reduces the chances
  104. of introducing errors in the code.)
  105.  
  106. Finally, use the "make" command and a Makefile, if your
  107. systems support it.  This makes it easy to control the
  108. compilation, and eases configuration and installation.
  109. Configuration options, constants, and macros can all be
  110. defined in the Makefile -- this isolates them from the code,
  111. and allows flexibility in customizing the code without
  112. making any changes to the modules themselves.  If you want
  113. to get fancy, you could even have a program or script that
  114. builds a Makefile tailored to a particular configuration,
  115. based on the system and user selected option. (Most X11
  116. Window software now includes an Imakefile, a system
  117. independent Makefile, which can be run through a program
  118. that will produce a custom Makefile for your site.)
  119.  
  120. So far, we've only looked at program structure and
  121. modularity.  Even more important to assure portability is
  122. the way we use data structures and data types, in memory and
  123. in data files.  We'll look at that next time.
  124.