Date: Tue, 15 Feb 94 12:31:57 JST From: Stephen Turnbull To: ghgreene AT nyx10 DOT cs DOT du DOT edu Cc: djgpp AT sun DOT soe DOT clarkson DOT edu Subject: simple make problem: some simple recommendations In general, the long command line lengths that arise in making large programs is a problem under DOS. Makes don't provide good ways to deal with this (but see comments about DMake, below) in a way that is portable across operating systems. Unfortunately, the linker response file ("gcc -o prog @prog.rsp") method is really non-portable; GCC doesn't know about it, GO32 does. A fairly general way to deal with it is the following. (1) Define your dependencies as macros. Eg, SRCS1 = src1.c src2.c src3.c SRCS2 = src4.c src5.c src6.c OBJS1 = src1.o src2.o src3.o OBJS1 = src4.o src5.o src6.o OBJS = $(OBJS1) $(OBJS2) You will typically need multiple macros because of the line length limitation on the echo commands (see below). (2) Define compilation flags and libraries, etc, as macros: LIBS = -lm CFLAGS = -g -O2 Be careful about the differences in syntax between files and libraries (this always sneaks up on me). To use libm.a, you need to include the library switc "-l" h as well as the name "m". (3) Use the macros in the rules. Probably the SRCS macro isn't very useful, as there will be a default rule to compile sources into objects. (On the other hand, in large makes it is not that uncommon to run into situations where the compilation flags will be different for different modules, in which case grouping sources by module might make a fair amount of sense.) In any case, it provides a list of the source files so that readers can tell what you're compiling. But the linker rule might look like this: # For Unix, comment out the DGJPP sections and uncomment the Unix section # DJGPP link prog: $(OBJS) # don't put "gcc -o prog" in the DOS-style response file echo $(CFLAGS) > prog.rsp # be careful to truncate here! echo $(OBJS1) >> prog.rsp # be careful to append here! echo $(OBJS2) >> prog.rsp echo $(LIBS) >> prog.rsp gcc -o prog @prog.rsp # DJGPP-specific processing of the linker output prog.exe: prog strip prog coff2exe prog del prog # Unix link #prog: $(OBJS) # echo gcc -o prog > link.sh # be careful to truncate here! # echo $(CFLAGS) > link.sh # be careful to append here! # echo $(OBJS1) >> link.sh # echo $(OBJS2) >> link.sh # echo $(LIBS) >> link.sh # sh ./link.sh This is a fairly portable but rather ugly makefile. Writing a really portable makefile is really hard. Look at the multiple makefiles for Ghostscript, for an example of how bad things can get. In fact, Ghostscript creates a half-dozen special purpose programs, including a replacement for "echo", merely to allow compile-time configuration and creation of the linker response or script file to be done in a portable fashion. However, the techniques presented here can help make a long makefile more readable, and present things in a way that is compatible with DOS but doesn't completely confuse Unix programmers. There seems to be fairly good reason to believe that DMake makefiles can be quite portable, but despite the claims of DMake advocates I have never figured out how to get DMake to process GNU Make makefiles "out of the box". This is probably my deficiency in not properly setting up DMake on my system, not DMake's. But it's usually easier to hand-edit the DOS requirements for the makefile, since there are typically a number of GO32 dependencies that need to be fixed anyway. In any case, using DMake breaks portability to systems using GNU Make. An alternative is to use Imake, which comes with the X Windows systems. But this is really hairy. Imake doesn't come with helpful documentation; the comments say things like "don't edit below this line or your hard disk will grow a beard" and "you really don't want to create Imakefiles from scratch; find one that looks like it does about what you want and tweak it until it does what you want." Furthermore, figuring out how to preconfigure Imake for your system, especially if it's DOS/GO32/GCC, can be a real pain. On the other hand, once you get that stuff right, Imakefiles are very portable to any system using GNU or Unix make.