AIPS++ NOTE 166: Evaluation of Imake for use in AIPS++ ====================================================== J. E. Horstkotte 17 June 1994 At Paul Shannon's request, I have read part (the first five chapters) of "Software Portability with imake" by Paul DuBois in order to evaluate it for the AIPS++ project. In summary, my conclusion is that we should not use imake since most or all of the features which the imake program "adds" to make are already available in gmake. However, when (if) we do a major redesign of our makefiles, we should pay a great deal of attention to the makefile design methodology discussed in this book. The X/imake approach to portability and platform and site dependencies is very sensible, and I believe could be used to advantage by AIPS++. Imake is basically a preprocessor which uses a set of input files to generate correct makefiles for a particular platform, site, etc. These input files are processed by the c preprocessor cpp to generate the makefiles. Great use is made of include files, conditionals, macros, and preprocessor variables to provide the desired flexibility. Imake comes with the X distribution, and is what X uses to build its software. It comes with an orgizational structure for separating out system and site dependencies. It also comes with a large number of predefined macros, e.g. for target definition. In section "Why Not Just Use make?" of the Introduction on pp. 6-7, there are discussed several problems with make which imake addresses. I will discuss each of these in turn below. In addition, there is the implicit assumption by the authors of imake that many different make programs will be used. Therefore, they must write their makefiles to work with the least common denominator make. AIPS++ does not have this problem, since we specify that only one make program be used: gmake. This simplifies our problems in two important ways. The first is that we can write for a single version of make, i.e. gmake. The second is that gmake has many powerful features beyond the least common denominator make, and we can use these features in our makefiles. Deficiencies in the "least common denominator make" which imake solves, and the gmake answer: 1. There are no conditionals. These are used to conditionally define make variables, targets, etc. gmake does have conditionals. 2. There is no flow control. These are loops and iterators. gmake does have loops and iterators for use in building and transforming make variables. 3. It's difficult to make global changes. imake uses include files to solve this. gmake has the capability to include files. 4. Header file dependencies for C source files are inherently nonportable. imake computes dependencies at makefile build time, and makes them part of the built makefile. There are many ways/schemes to compute dependencies. Since gmake has the ability to include files, one can compute the dependencies, put them into a file, and include this file in the makefile. If there is a rule for how to build this include file containing the dependencies, gmake automatically ensures that the dependencies are up to date. In short, it seems that everything that imake can do, gmake can do. Not only do I feel that one can do with gmake about everything one can do with imake; I also feel that there are several negatives to using imake. 1. It is a new language, which requires new expertise and experience, and which would therefore make the AIPS++ build system even more difficult to understand than it already is. 2. We would have to write cpp macro functions for all of the make targets which we need. Thus, we would not need to know any less about make, but we would need to know about imake in addition. 3. When developing makefiles, the cycle of writing the imake files, building the makefiles, and running the makefiles is clumsier than just writing the makefiles directly and running them, and more prone to error. Further, debugging the imake files would require understanding what the generated makefiles were doing, and then understanding how they were built from the imake files, which I think would be considerably more complex than just debugging the makefiles directly. 4. The make rules which imake writes are very specific, and do not take advantage of much of the power of make (and gmake). In gmake, one can (and I believe one should) write the general, powerful, and concise rules when one can. I believe that this makes for a more readable and maintainable makefile. There are a couple of advantages to imake, as it comes with the X distribution: 1. It comes with all of the configuration files to build X. Thus, much of what would go into our (i)makefiles has already been written. We would just(!) have to extend/adapt it for AIPS++ (and gmake). The question is, of course, how much work we would need to do to make it work for AIPS++. I suspect that it would be alot. 2. It comes with platform configuration files for many useful architectures. 3. It comes structured in a very nice way for separating platform, site, and target (as well as other) dependencies. On balance, I think we should stay with gmake. I believe that it is a superior solution to imake. I do think that we could probably learn alot from looking at their platform configuration files. I would like to reemphasize that the structure which this imake book describes and espouses, which is used by the builders of X, is an excellent one, from which we can get alot of good ideas. They separate out platform, site, and target (and more) descriptions into separate files. They also make good use of make variables to parameterize quantities which could vary. We do alot of this in the current AIPS++ makefiles, of course. However, they do a number of things differently, and I believe that it gives them more flexibility and power. Jim Horstkotte