Mail Archives: djgpp/1994/02/15/00:29:27
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.
- Raw text -