As already noted, SRT attempts to take care of most of the portability issues for you. However, you should keep in mind a couple of principles to avoid hassles. These are portable shell programming, using the right utility programs, supporting the three different build methods, defining the right -I options for preprocessors, being careful with the order in which you define your custom rules (see Section 15.4, ``Defining Custom Rules''), and being aware of how the optional tools complicate things (see Appendix G, ``Details on Tools'').
Your makefiles must be written to use Bourne shell commands and not much else. You are not allowed to use any other shell variant, or to use TCL, Perl, REXX, or other similar tools. This applies not only to the commands you are executing in the makefile rules, but also to any scripts you are calling from them. For example, if you write scripts to implement your testsuites, they must be written for Bourne shell, not for some other scripting language--or as full-blown programs in C. This restriction can only be lifted if your software project as a whole makes a decision to allow otherwise.
The non-shell utilities you can use in the makefiles are listed in the GNU Coding Standards. The list of utilities the release tools themselves require are listed in Table 19-1, ``Required System Tools''--but note that this includes programs used only in special, highly controlled conditions, or only when the user knows that a particular tool will be required for the task. You should not expect to have in your makefiles access to all of the tools mentioned in that table.
Dealing with the different build orders boils down to remembering to use $(srcdir) or $(top_srcdir) where necessary, and remembering not to use them in a number of occasions. You can get pretty far by remembering a simple rule: write the makefile as if the source directory was completely read-only and not the current directory.
The makefile should never assume that the user is building the package in its source directory.[1] The occasions where you should remember to use $(srcdir) or $(top_srcdir) include preprocessor options (more details shortly), invocations of $(wildcard), and when rules refer to files in the source directory (see for instance Example 15-2). You do not need to use the variables in the TARGET variables or in the SRC property variables; the release tools automatically assume it in those contexts. You should not use the variables when you are referring to anything generated by configure or the makefiles.
As for writing into the source directory, the makefile should almost never expect to be able to add, delete or modify files in the source directory.[2] This means that all the intermediate files, such as object files or generated header files, should be put into the current directory or its subdirectories.
If your package has header files you include in your own source files, you must also define -I options for the preprocessors such that your header files are found appropriately. Assume for instance a makefile in the package root directory and source files in the src subdirectory. Now, if the source files include private header files from the src subdirectory by including "Header.h", you should add -I$(srcdir)/src to the target's preprocessor options. On the other hand, if src also contains generated header files, you will need two preprocessor options: -I./src and -I$(srcdir)/src. The first points to the generated area, the second to the directory in the source tree. These will end up identical when the package is built in the source directory, but different otherwise. For examples, see Example 15-2 and Figure 8-1, ``Directory structure in the SRT build method''.
The final issue you need to remember is that the tools described in Appendix G, ``Details on Tools'' can greatly change the build process. If you write custom rules that generate source files or do other weird things, make sure your rules still work with the tools.
| [1] | Except for the rules that are meant to be used solely by the package authors. For such rules it is safe to assume that the developers know what restrictions apply. |
| [2] | ``Almost never'' because under a certain circumstances one would want to write in there. These are always situations where the package author is in control. An example would be updating configure. |