head 3.1; access; symbols; locks; strict; comment @.\" @; 3.1 date 95.06.30.16.18.34; author grog; state Exp; branches; next 3.0; 3.0 date 95.06.26.08.24.15; author grog; state Exp; branches; next 2.6; 2.6 date 95.06.25.11.27.36; author grog; state Exp; branches; next 2.5; 2.5 date 95.06.20.12.22.10; author grog; state Exp; branches; next 2.4; 2.4 date 95.06.09.04.54.42; author grog; state Exp; branches; next 2.3; 2.3 date 95.05.16.08.32.40; author grog; state Exp; branches; next 2.2; 2.2 date 95.02.24.10.14.27; author grog; state Exp; branches; next 2.1; 2.1 date 95.02.17.09.35.35; author grog; state Exp; branches; next 1.8; 1.8 date 95.02.15.14.47.17; author grog; state Exp; branches; next 1.7; 1.7 date 95.02.15.12.05.18; author grog; state Exp; branches; next 1.6; 1.6 date 95.02.11.13.03.32; author grog; state Exp; branches; next 1.5; 1.5 date 95.02.04.09.11.40; author grog; state Exp; branches; next 1.4; 1.4 date 95.01.26.12.24.31; author grog; state Exp; branches; next 1.3; 1.3 date 95.01.25.16.42.26; author grog; state Exp; branches; next 1.2; 1.2 date 95.01.24.16.03.00; author grog; state Exp; branches; next 1.1; 1.1 date 95.01.23.09.27.18; author grog; state Exp; branches; next ; desc @Describe the pitfalls that can occur when building a package @ 3.1 log @Minor mods @ text @.\" For emacs, this file is in -*- nroff-fill -*- mode .\" $Id: building.ms,v 3.0 1995年06月26日 08:24:15 grog Exp grog $ .\" $Log: building.ms,v $ .\" Revision 3.0 1995年06月26日 08:24:15 grog .\" Final draft .\" .\" Revision 2.5 1995年06月20日 12:22:10 grog .\" Final draft, first cut. .\" .\" Revision 2.4 1995年06月09日 04:54:42 grog .\" Remove date from page headers .\" Minor mods .\" .\" Revision 2.3 1995年05月16日 08:32:40 grog .\" Major mods after Andy's final draft review .\" .\" Revision 2.2 1995年02月24日 10:14:27 grog .\" Minor mods .\" .\" Revision 2.1 1995年02月17日 09:35:35 grog .\" Minor mods, remove question flags .\" .\" Revision 1.8 1995年02月15日 14:47:17 grog .\" Minor mods .\" .\" Revision 1.6 1995年02月11日 13:03:32 grog .\" Checkin before Andy's suggested mods. .\" .\" Revision 1.5 1995年02月04日 09:11:40 grog .\" Minor mods .\" .\" Revision 1.4 1995年01月26日 12:24:31 grog .\" Minor mods .\" .\" Revision 1.3 1995年01月25日 16:42:26 grog .\" Minor mods .\" .\" Revision 1.2 1995年01月24日 16:03:00 grog .\" Minor mods .\" .\" Revision 1.1 1995年01月23日 09:27:18 grog .\" Initial revision .\" .so global.ms .Se \*[nchbuild] "Building the package" .St "Building the package" Now we have configured our package and we're ready to build. This is the Big Moment: at the end of the build process we should have a complete, functioning software product in our source tree. In this chapter, we'll look at the surprises that \fImake\fR can have in store for you. You can find the corresponding theoretical material in \*[chmake]. .Ah "Preparation" .XX "Preparation for building" .XX "Building, preparation for" If you're unlucky, a port can go seriously wrong. The first time that error messages appear thick and fast and scroll off the screen before you can read them, you could get the impression that the packages were built this way deliberately to annoy you. .LP A little bit of preparation can go a long way towards keeping you in control of what's going on. Here are some suggestions: .Bh "Make sure you have enough space" One of the most frequent reasons of failure of a build is that the file system fills up. If possible, ensure that you have enough space before you start. The trouble is, how much is enough? Hardly any package will tell you how much space you need, and if it does it will probably be wrong, since the size depends greatly on the platform. If you are short on space, consider compiling without debugging symbols (which take up a lot of space). If you do run out of space in the middle of a build, you might be able to save the day by \fIstripping\fR the objects with \fIstrip\fR, in other words removing the symbols from the file. .Bh "Use a windowing system" The sheer size of a complicated port can be a problem. Like program development, porting tends to be an iterative activity. You edit a file, compile, link, test, go back to edit the file, and so on. It's not uncommon to find yourself having to compare and modify up to 20 different files in 5 different directories, not to mention running \fImake\fR and the debugger. In adddition, a single line of output from \fImake\fR can easily be 5000 or 10000 characters long, many times the screen capacity of a conventional terminal. .LP All of these facts speak in favour of a windowing system such as X11, preferably with a high-resolution monitor. You can keep your editor (or editors, if they don't easily handle multiple files) open all the time, and run the compiler and debugger in other windows. If multiple directories are involved, it's easier to maintain multiple \fIxterm\fRs, one per directory, than to continually change directories. A correctly set up \fIxterm\fR will allow you to scroll back as far as you want--I find that 250 lines is adequate. .Bh "Keep a log file" .XX "Log file, keeping" .Pn make-log .XX Theseus .XX labyrinth .XX "Graves, Robert" Sooner or later, you're going to run into a bug that you can't fix immediately: you will have to experiment a bit before you can fix the problem. Like finding your way through a labyrinth, the first time through you will probably not take the most direct route, and it's nice to be able to find your way back again. In the original labyrinth, Theseus used a ball of string to find his way both in and out. The log file, a text file describing what you've done, is the computer equivalent of the ball of string, so you should remember to roll it up again. If you're running an editor like \fIemacs\fR, which can handle multiple files at a time, you can keep the log in the editor buffer and remove the notes again when you back out the changes. .LP In addition to helping you find your way out of the labyrinth, the log will also be of use later when you come to install an updated version of the software. To be of use like this, it helps to keep additional information. For example, here are some extracts from a log file for the \fIgcc\fR: .Ps Platform: SCO UNIX System V.3.2.2.0 Revision: 2.6.0 Date ported: 25 August 1994 Ported by: Greg Lehey, LEMIS Compiler used: rcc, gcc-2.6.0 Library: SCO 0. configure i386-unknown-sco --prefix=/opt. It sets local_prefix to /usr/local anyway, and won't listen to --local_prefix. For some reason, config decides that it should be cross-compiling. 1. function.c fails to compile with the message function.c: 59: no space. Compile this function with ISC gcc-2.5.8. 2. libgcc.a was not built because config decided to cross-compile. Re-run config with configure i386-*-sco --prefix=/opt, and do an explicit make libgcc.a. 3. crtbegin.o and crtend.o were not built. Fix configure: --- configure~ Tue Jul 12 01:25:53 1994 +++ configure Sat Aug 27 13:09:27 1994 @@@@ -742,6 +742,7 @@@@ else tm_file=i386/sco.h tmake_file=i386/t-sco + extra_parts="crtbegin.o crtend.o" fi truncate_target=yes ;; .Pe Keeping notes about problems you have with older versions helps a lot: this example represents the results of a considerable time spent debugging the \fImake\fR procedure. If you didn't have the log, you'd risk tripping over this problem every time. .Bh "Save make output" .XX "make output, saving" Typically, to build a package, after you have configured it, you simply type .Ps $ \f(CBmake\f(CW .Pe Then the fireworks start. You can sit and watch, but it gets rather boring to watch a package compile for hours on end, so you usually leave it alone once you have a reasonable expectation that it will not die as soon as you turn your back. The problem is, of course, that you may come back and find a lot of gobbldegook on the screen, such as: .Ps make[5]: execve: ../../config/makedepend/makedepend: No such file or directory make[5]: *** [depend] Error 127 make[5]: Leaving directory `/cdcopy/SOURCE/X11/X11R6/xc/programs/xsetroot' depending in programs/xstdcmap... make[5]: Entering directory `/cdcopy/SOURCE/X11/X11R6/xc/programs/xstdcmap' checking ../../config/makedepend/makedepend over in ../../config/makedepend first... make[6]: Entering directory `/cdcopy/SOURCE/X11/X11R6/xc/config/makedepend' gcc -DNO_ASM -fstrength-reduce -fpcc-struct-return -fwritable-strings -O \\ -I../../config/imake -I../.. OSDefines -DSYSV -DSYSV386 -c include.c gcc: OSDefines: No such file or directory In file included from include.c:30: def.h:133: conflicting types for `getline' /opt/include/stdio.h:505: previous declaration of `getline' Broken pipe .Pe This is from a real life attempt to compile X11R6, normally a fairly docile port. The target \fImakedepend\fR failed to compile, but why? The reason has long since scrolled off the screen.\** .FS Well, there \fIis\fR a clue, but it's very difficult to see unless you have been hacking X11 configurations longer than is good for your health. \f(CWOSDefines\fR is a symbol used in X11 configuration. It should have been replaced by a series of compiler flags used to define the operating system to the package. In this case, the X11 configuration was messed up, and nothing defined \f(CWOSDefines\fR, so it found its way to the surface. .FE You can have your cake and eat it too if you use \fItee\fR to save your output: .Ps $ \f(CBmake 2>&1 | tee -a Make.log\f(CW .Pe This performs the following actions: .Ls B .Li It copies error output (file descriptor 2) to standard output (file descriptor 1) with the expression \s10\f(CW2>&1\fR\s0. .Li It pipes the combined standard output to the program \fItee\fR, which echos it to its standard output and also copies it to the file \fIMake.log\fR. .Li In this case, I specified the \s10\f(CW-a\fR\s0 option, which tells \fItee\fR to append to any existing \fIMake.log\fR. If I don't supply this flag, it will erase any previous contents. Depending on what you're doing, you may or may not want to use this flag. .Le If you're not sure what your \fImake\fR is going to do, and especially if the \fIMakefile\fR is complicated, consider using the \s10\f(CW-n\fR\s0 option. This option tells \fImake\fR to perform a "dry run": it prints out the commands that it would execute, but doesn't actually execute them. .LP These comparatively simple conventions can save a lot of pain. I use a primitive script called \fIMake\fR which contains just the single line: .Ps make 2>&1 $* | tee -a Make.log .Pe It's a good idea to always use the same name for the log files so that you can find them easily. .Ah "Standard targets" .XX "make, standard targets" .XX "make, target, standard" Building packages consists of more than just compiling and linking, and by convention many \fIMakefile\fRs contain a number of targets with specific meanings. In the following sections we'll look at some of the most common ones. .Bh "make depend" .XX "make depend" .XX "make, target, depend" .Pn makedepend \fImake depend\fR creates a list of dependencies for your source tree, and usually appends it to the \fIMakefile\fR. Usually it will perform this task with \fImakedepend\fR, but sometimes you will see a \f(CWdepend\fR target that uses \fIgcc\fR with the \fI-M\fR flag or \fIcpp\fR. \f(CWdepend\fR should be the first target to run, since it influences which other commands need to be executed. Unfortunately, most \fIMakefile\fRs don't have a \s10\f(CWdepend\fR\s0 target. It's not difficult to write one, and it pays off in the reduction of strange, unaccountable bugs after a rebuild of the package. Here's a starting point: .Ps depend: makedepend *.[ch] .Pe This will work most of the time, but to do it correctly you need to analyze the structure of the package: it might contain files from other languages, or some files might be created by shell scripts or special configuration programs. Hopefully, if the package is this complicated, it will also have a \s10\f(CWdepend\fR\s0 target. .LP Even if you have a \s10\f(CWdepend\fR\s0 target, it does not always work as well as you would hope. If you make some really far-reaching changes, and things don't work the way you expect, it's worth starting from scratch with a \fImake clean\fR to be sure that the make still works. .Bh "make all" .XX "make, target, all" .XX "make all" \fImake all\fR is the normal way to perform the build. Frequently, it is the default target (the first target in the \fIMakefile\fR), and you just need to enter \fImake\fR. This target typically rebuilds the package but does not install it. .Bh "make install" .XX "make, target, install" .XX "make install" .Pn install-target \fImake install\fR installs the compiled package into the local system environment. The usage varies considerably; we'll look at this target in more detail in \*[chinstall], page \*[make-install]. .Bh "make clean" .XX "make clean" .XX "make, target, clean" .Pn make-clean \fImake clean\fR normally removes everything that \fImake all\fR has made--the objects, executables and possibly auxiliary files. You use it after deciding to change a compiler, for example, or to save space after you have finished an installation. Be careful with \fImake clean\fR: there is no complete agreement about exactly what it removes, and frequently you will find that it doesn't remove everything it should, or it is too eager and removes lots of things it shouldn't. \fImake clean\fR should remove everything that \fImake all\fR can make again--the intermediate and installable files, but not the configuration information that you may have taken days to get right. .Bh "make stamp-halfway" .XX "make stamp-halfway" .XX "make, target, stamp-halfway" Occasionally you see a target like \fImake stamp-halfway\fR. The commands perform a lot of other things, and at the end just create an empty file called \fIstamp-halfway\fR. This is a short cut to save lots of complicated dependency checking: the presence of this file is intended to indicate that the first half of the build is complete, and that a restart of \fImake\fR can proceed directly to the second half. Good examples of this technique can be found in the \fIMakefile\fR for the GNU C compiler, and in the X11 source tree, which uses the name \fIDONE\fR for the stamp file. .Ah "Problems running make" .XX "make, problems running" .Pn problems-running-make Ideally, running \fImake\fR should be simple: .Ps $ \f(CBmake all\fR \fI\&lots of good messages from \fImake .Pe Things don't always go this smoothly. You may encounter a number of problems: .Ls B .Li You may not be able to find a \fIMakefile\fR, or the targets don't work the way you expect. .Li \fImake\fR may not be able to make any sense of the \fIMakefile\fR. .Li The \fIMakefile\fR may refer to non-existent files or directories. .Li \fImake\fR seems to run, but it doesn't rebuild things it should, or it rebuilds things it shouldn't. .Li You can't find anything that's wrong, but \fImake\fR still produces obscure error messages. .Le In the following sections we'll look at each of these problems. Here's an overview of the types of error message we'll consider: .ne 10 .Ts "Problems running \fImake\fR" .TS H linesize(2), tab(#) ; lf(I) | lf(R)r . \fRProblem#page _ .TH N Argument list too long#\*[Arg-list-too-long] "$! nulled, predecessor circle"#\*[Circular-dependency-dropped] "Circular dependency dropped"#\*[Circular-dependency-dropped] "Commands commence before first target"#\*[Commands-commence-before-first-target] Comments in command lists#\*[Comments-in-command-lists] "Graph cycles through \fItarget\fR#\*[Circular-dependency-dropped] Incorrect continuation lines#\*[Incorrect-continuation-lines] Incorrect dependencies#\*[Incorrect-dependencies] make forgets the current directory#\*[make-forgets-the-current-directory] "Missing separator - stop"#\*[Missing-separator-stop] Missing targets#\*[Missing-targets] No dependency on Makefile#\*[No-dependency-on-Makefile] No Makefile#\*[No-Makefile] Nonsensical targets#\*[Nonsensical-targets] Problems with make clean#\*[Problems-with-make-clean] Problems with subordinate makes#\*[Problems-with-subordinate-makes] Prompts in Makefiles#\*[Prompts-in-Makefiles] Subordinate makes#\*[Subordinate-makes] Syntax errors from the shell#\*[Syntax-errors-from-the-shell] Trailing blanks in variables#\*[Trailing-blanks-in-variables] Unable to stop make#\*[Unable-to-stop-make] Wrong flavour of make#\*[Wrong-flavour-of-make] Wrong Makefile#\*[Wrong-Makefile] .TE .Te .Ah "Missing Makefile or targets" Sometimes \fImake\fR won't even let you in the door--it prints a message like: .Ps $ \f(CBmake all\f(CW Don't know how to make all. Stop. .Pe .Pn No-Makefile .XX "make, problems, no makefile" The first thing to check here is whether there is a \fIMakefile\fR. If you don't find \fIMakefile\fR or \fImakefile\fR, check for one under a different name. If this is the case, the author should have documented where the \fIMakefile\fR comes from--check the \fIREADME\fR files and other documentation that came with the package. You may find that the package uses separate \fIMakefile\fRs for different architectures. For example, \fIMakefile\fR may be correct only if you are compiling in a BSD environment. If you want to compile for a System V machine, you may need to specify a different \fIMakefile\fR: .Ps $ \f(CBmake -f Makefile.sysv\fR .Pe .IP This is a pain because it's so easy to make a mistake. In extreme cases the compiler will successfully create objects, but they will fail to link. .LP Other possibilities include: .Ls B .Li The \fIMakefile\fR is created by the configuration process, and you haven't configured yet. This would be the case if you find an \fIImakefile\fR (from which you create a \fIMakefile\fR with \fIxmkmf\fR--see \*[chconfig], page \*[xmkmf]), or \fIMakefile.in\fR (GNU \fIconfigure\fR--see page \*[GNU-configure]). .Li The directory you are looking at doesn't need a \fIMakefile\fR. The \fIMakefile\fR in the parent directory, also part of the source tree, could contain rules like: .Ps foo/foo: foo/*.c ${CC} foo/*.c -o foo/foo .Pe In other words, the executable is made automatically when you execute \fImake foo/foo\fR in the parent directory. As a rule, you start building in the root directory of a package, and perform explicit builds in subdirectories only if something is obviously wrong. .Li The author of the package doesn't believe in \fIMakefile\fRs, and has provided a shell script instead. You often see this with programs that originated on platforms that don't have a \fImake\fR program. .Li There is really nothing to build the package: the author is used to doing the compilation manually. In this case, your best bet is to write a \fIMakefile\fR from scratch. The skeleton in .Ref e \& n 1 will get you a surprisingly long way. The empty targets are to remind you what you need to fill in: .Xs SRCS = \fIlist of C source files\f(CW OBJS = ${SRCS:.c=.o} \fIcorresponding object files\f(CW CC=gcc \fIfile name of compiler\f(CW CFLAGS=-g -O3 \fIflags for compiler\f(CW LDFLAGS=-g \fIflags for linker\f(CW BINDIR=/opt/bin LIBDIR=/opt/lib MANDIR=/opt/man MAN1DIR=man1 INFODIR=/opt/info PROGRAM= \fIname of finished program\f(CW all: $(PROGRAM) ${CC} ${LDFLAGS} -o ${PROGRAM} ${OBJS} man: doc: install: all depend: makedepend ${SRCS} clean: rm -f \e#* *~ core $(PROGRAM) *.o .Xe .Le .Pn Wrong-Makefile .XX "make, problems, wrong Makefile" .XX "GNUmakefile file" .XX "makefile file" .XX "make, GNUmakefile file" .XX "make, makefile file" .Bh "Missing targets" .Pn Missing-targets .XX "make, problems, missing targets" .Pn no-standard-target Another obvious reason for the error message might be that the target \s10\f(CWall\fR\s0 doesn't exist: some \fIMakefiles\fR have a different target name for each kind of system to which the \fIMakefile\fR has been adapted. The \fIREADME\fR file should tell you if this is the case. One of the more unusual examples is \fIgnuplot\fR. You need to enter .Ps $ \f(CBmake All\f(CW $ \f(CBmake x11 TARGET=Install\f(CW .Pe The better ones at least warn you--see \*[chconfig], page \*[multiple-targets], for an example. I personally don't like these solutions: it's so much easier to add the following line at the top of the \fIMakefile\fR: .Ps BUILD-TARGET = build-bsd .Pe The first target would then be: .Ps all: ${BUILD-TARGET} .Pe If you then want to build the package for another architecture, you need only change the single line defining \s10\f(CWBUILD-TARGET\fR\s0. .Ah "make doesn't understand the Makefile" .Pn Wrong-flavour-of-make .XX "make, problems, wrong flavour" Sometimes \fImake\fR produces messages that make no sense at all: the compiler tries to compile the same file multiple times, each time giving it a different object name, or it claims not to be able to find files that exist. One possible explanation is that various flavours of \fImake\fR have somewhat different understandings of default rules. In particular, as we will see in \*[chmake], there are a number of incompatibilities between BSD \fImake\fR and GNU \fImake\fR. .LP Alternatively, \fImake\fR may not even be tryining to interpret the \fIMakefile\fR. Somebody could have hidden a file called \fImakefile\fR in the source tree. Most people today use the name \fIMakefile\fR for \fImake\fR's description file, probably because it's easier to see in an \fIls\fR listing, but \fImake\fR always looks for a file called \fImakefile\fR (with lower case \fIm\fR) first. If you are using GNU \fImake\fR, it first looks for a file called \fIGNUmakefile\fR before checking for \fImakefile\fR and \fIMakefile\fR. .Ah "make refers to non-existent files" Building a package refers to a large number of files, and one of the most frequent sources of confusion is a file that can't be found. There are various flavours of this, and occasionally the opposite happens, and you have trouble with a file that \fImake\fR finds, but \fIyou\fR can't find. .LP To analyse this kind of problem, it's helpful to know how \fImake\fR is referring to a file. Here are some possibilities: .Ls B .Li \fImake\fR may be looking for a dependent file, but it can't find it, and it can't find a rule to build it. In this case you get a message like: .Ps $ \f(CBmake\f(CW make: *** No rule to make target `config.h'. Stop. .Pe .Li \fImake\fR may not be able to locate a program specified in a command. You get a message like: .Ps $ \f(CBmake foo.o\f(CW /bin/cc -c foo.o -o foo.c make: execve: /bin/cc: No such file or directory make: *** [foo.o] Error 127 .Pe .Li The compilers and other programs started by \fImake\fR also access files specified in the source. If they don't find them, you'll see a message like .Ps $ \f(CBmake foo.o\f(CW gcc -c foo.c -o foo.o foo.c:1: bar.h: No such file or directory make: *** [foo.o] Error 1 .Pe .Le No matter where the file is missing, the most frequent reasons why it is not found are: .Ls B .Li The package has been configured incorrectly. This is particularly likely if you find that the package is missing a file like \fIconfig.h\fR. .Li The search paths are incorrect. This could be because you configured incorrectly, but it also could be that the configuration programs don't understand your environment. For example, it's quite common to find \fIMakefiles\fR with contents like: .Ps AR = /bin/ar AS = /bin/as CC = /bin/cc LD = /bin/cc .Pe Some older versions of \fImake\fR need this, since they don't look at the \s10\f(CWPATH\fR\s0 environment variable. Most modern versions of \fImake\fR do look at \s10\f(CWPATH\fR\s0, so the easiest way to fix such a \fIMakefile\fR is to remove the directory component of the definitions. .Bh "Problems with subordinate makes" .Pn Problems-with-subordinate-makes .XX "make, problems, subordinate makes" Occasionally while building, the compiler complains about a file that doesn't seem to be there. This can be because the make is running in a subdirectory: large projects are frequently split up into multiple subdirectories, and all the top level \fIMakefile\fR does is to run a number of subordinate \fImake\fRs. If it is friendly, it also echos some indication of where it is at the moment, and if it dies you can find the file. Newer versions of GNU \fImake\fR print messages on entering and leaving a directory, for example: .Pn make-newdir .Ps make[1]: Entering directory `/cdcopy/SOURCE/Core/glibc-1.08.8/assert' make[1]: Nothing to be done for `subdir_lib'. make[1]: Leaving directory `/cdcopy/SOURCE/Core/glibc-1.08.8/assert' .Pe If neither of these methods work, you have the option of searching for the file: .Ps $ \f(CBfind . -name foo.c -print .Pe or modifying the \fIMakefile\fR to tell you what's going on. .Ah "make doesn't rebuild correctly" One of the most insidious problems rebuilding programs occurs when \fImake\fR doesn't rebuild programs correctly: there's no easy way to know that a module has been omitted, and the results can be far-reaching and time-consuming. Let's look at some possible causes of this kind of problem. .Bh "Incorrect dependencies" .Pn Incorrect-dependencies .XX "make, problems, incorrect dependencies" One weakness of \fImake\fR is that you have to tell it the interdependencies between the source files. Unfortunately, the dependency specifications are \fIvery\fR frequently incorrect. Even if they were correct in the source tree as delivered, changing configuration flags frequently causes other header files to be included, and as a result the dependencies change. Make it a matter of course to run a \fImake depend\fR after reconfiguring, if this target is supplied--see page \*[makedepend] for details on how to make one. .Bh "No dependency on Makefile" .Pn No-dependency-on-Makefile .XX "make, problems, no dependency on Makefile" What happens if you change the \fIMakefile\fR? If you decide to change a rule, for example, this could require recompilation of a program. To put it in \fImake\fR terms: all generated files depend on the \fIMakefile\fR. The \fIMakefile\fR itself is not typically included in the dependency list. It really should be, but that would mean rebuilding everything every time you change the \fIMakefile\fR, and in most cases it's not needed. On the other hand, if you do change your \fIMakefile\fR in the course of a port, it's a good idea to save your files, do a \fImake clean\fR and start all over again. If everything is OK, it will build correctly without intervention. .Ah "Other errors from make" The categories we have seen above account for a large proportion of the error messages you will see from \fImake\fR, but there are many others as well. In this section, we'll look at other frequent problems. .Bh "Trailing blanks in variables" .Pn Trailing-blanks-in-variables .XX "make, problems, trailing blanks in variables" You define a \fImake\fR variable with the syntax: .Ps NAME = Definition # optional comment .Pe The exact \fIDefinition\fR starts at the first non-space character after the \s10\f(CW=\fR\s0 and continues to the end of the line or the start of the comment, if there is one. You can occasionally run into problems with things like: .Ps MAKE = /opt/bin/make # in case something else is in the path .Pe When starting subsidiary \fImake\fRs, \fImake\fR uses the value of the variable \s10\f(CWMAKE\fR\s0 as the name of the program to start. In this case it is "\fI/opt/bin/make\ \ \ \ \fR"--it has trailing blanks, and the \fIexec\fR call fails. If you're lucky, you get: .Ps $ \f(CBmake\f(CW make: don't know how to make make . stop. .Pe This message does give you a clue: there shouldn't be any white space between the name of the target and the following period. On the other hand, GNU \fImake\fR is "friendly" and tidies up trailing blanks, so it says: .Ps $ \f(CBmake\f(CW /opt/bin/make subdir \fInote the space before the target name "subdir"\f(CW make: execve: /opt/bin/make: No such file or directory make: *** [suball] Error 127 .Pe The only clue you have here is the length of the space on the first line. .LP It's relatively easy to avoid this sort of problem: avoid comments at the end of definition lines. .Bh "Comments in command lists" .Pn Comments-in-command-lists .XX "make, problems, comments in command lists" Some versions of \fImake\fR, notably XENIX, can't handle rules of the form .Ps doc.dvi: doc.tex tex doc.tex # do it again to get the references right tex doc.tex # same thing again .Pe The first comment causes \fImake\fR to think that the rule is completed, and it stops. When you fix this problem by removing the comment, you run into a second one: it doesn't understand the second comment either. This time it produces an error message. Again, you need to remove the comment. .Bh "make forgets the current directory" .Pn make-forgets-the-current-directory .XX "make, problems, forgets current directory" Occasionally, it looks as if \fImake\fR has forgotten what you tell it. Consider the following rule: .Ps docs: cd doc ${ROFF} ${RFLAGS} doc.ms> doc.ps .Pe When you run it, you get: .Ps $ \f(CBmake docs\f(CW cd doc groff -ms doc.ms>doc.ps gtroff: fatal error: can't open `doc.ms': No such file or directory make: *** [docs] Error 1 .Pe So you look for \fIdoc.ms\fR in \fIdoc\fR, and it's there. What's going on? Each command is run by a new shell. The first one executes the \s10\f(CWcd doc\fR\s0 and then exits. The second one tries to execute the \s10\f(CWgroff\fR\s0 command. Since the \s10\f(CWcd\fR\s0 command doesn't affect the parent environment, it has no further effect, and you're still in the original directory. To do this correctly, you need to write the rule as: .Ps docs: cd doc; \e ${ROFF} ${RFLAGS} doc.ms> doc.ps .Pe This causes \fImake\fR to consider both lines as a single line, which is then passed to a single shell. The semicolon after the \s10\f(CWcd\fR\s0 is necessary, since the shell sees the command as a single line. .Bh "Missing separator - stop" .Pn Missing-separator-stop .XX "make, error messages, missing separator - stop" .XX "make, error messages, shell command needs a leading tab" This strange message is usually made more complicated because it refers to a line that looks perfectly normal. In all probability it is trying to tell you that you have put leading spaces instead of a tab on a command line. BSD \fImake\fR expects tabs, too, but it recovers from the problem, and the message it prints if they are missing is much more intelligible: .Ps "Makefile", line 21: warning: Shell command needs a leading tab .Pe .Bh "Commands commence before first target" .Pn Commands-commence-before-first-target .XX "make, error messages, commands commence before first target" .XX "make, error messages, unassociated shell command" This message, from System V \fImake\fR, is trying to tell you that you have used a tab character instead of spaces at the beginning of the definition of a variable. GNU \fImake\fR does not have a problem with this--it doesn't even mention the fact--so you might see this in a \fIMakefile\fR written for GNU \fImake\fR when you try to run it with System V \fImake\fR. BSD \fImake\fR cannot handle tabs at the beginning of definitions either, and produces the message: .Ps "Makefile", line 3: Unassociated shell command "CC=gcc" Fatal errors encountered -- cannot continue .Pe .Bh "Syntax errors from the shell" .Pn Syntax-errors-from-the-shell .XX "make, error messages, syntax errors from the shell" Many \fIMakefile\fRs contain relatively complicated shell script fragments. As we have seen, these are constrained to be on one line, and most shells have rather strange relationship between new line characters and semicolons. Here's a typical example: .Ps if test -d $(texpooldir); then exit 0; else mkdir -p $(texpooldir); fi .Pe This example is all on one line, but you can break it \fIanywhere\fR if you end each partial line with a backslash (\e). The important thing here is the placement of the semicolons: a rule of thumb is to put a semicolon where you would otherwise put a newline, but \fInot\fR after \s10\f(CWthen\fR\s0 or \s10\f(CWelse\fR\s0. For more details, check your shell documentation. .Bh "Circular dependency dropped" .Pn Circular-dependency-dropped .XX "make, error messages, circular dependency dropped" .XX "make, error messages, $! nulled, predecessor circle" .XX "make, error messages, graph cycles" This message comes from GNU \fImake\fR. In System V \fImake\fR, it is even more obscure: .Ps $! nulled, predecessor circle .Pe BSD \fImake\fR isn't much more help: .Ps Graph cycles through \f(CIdocs .Pe In each case, the message is trying to tell you that your dependencies are looping. This particular example was caused by the dependencies: .Ps docs: man-pages man-pages: docs .Pe In order to resolve the dependency \s10\f(CWdocs\fR\s0, \fImake\fR first needs to resolve \fIman-pages\fR. But in order to resolve \fIman-pages\fR, it first needs to resolve \fIdocs\fR--a real Catch 22 situation. Real-life loops are, of course, usually more complex. .Bh "Nonsensical targets" .Pn Nonsensical-targets .XX "make, problems, nonsensical targets" Sometimes the first target in the \fIMakefile\fR does nothing useful: you need to explicitly enter \s10\f(CWmake all\fR\s0 in order to make the package. There is no good reason for this, and every reason to fix it--send the mods back to the original author if possible (and be polite). .Bh "Unable to stop make" .Pn Unable-to-stop-make .XX "make, problems, unable to stop" Some \fIMakefile\fRs start a number of second and third level \fIMakefile\fRs with the \s10\f(CW-k\fR\s0 option, which tells \fImake\fR to continue if the subsidiary \fIMakefile\fR dies. This is quite convenient if you want to leave it running overnight and collect all the information about numerous failures the next morning. It also makes it almost impossible to stop the make if you want to: hitting the \fIQUIT\fR key (CTRL-C or DEL on most systems) kills the currently running \fImake\fR, but the top-level \fImake\fR just starts the next subsidiary \fImake\fR. The only thing to do here is to identify the top-level \fImake\fR and stop it first, not an easy thing to do if you have only a single screen. .Bh "Problems with make clean" .Pn Problems-with-make-clean .XX "make, target, clean" .XX "make clean" \fImake clean\fR is supposed to put you back to square one with a build. It should remove all the files you created since you first typed \f(CWmake\fR. Frequently, it doesn't achieve this result very accurately: .Ls B .Li It goes back further than that, and removes files that the \fIMakefile\fR doesn't know how to make.\** .FS If this does happen to you, don't despair just yet. Check first whether this is just simple-mindedness on the part of the \fIMakefile\fR--maybe there is a relatively simple way to recreate the files. If not, and you forgot to make a backup of your source tree before you started, \fIthen\fR you can despair. .FE .Li Other \fIMakefile\fRs remove configuration information when you do a \fImake clean\fR. This isn't quite as catastrophic, but you still will not appreciate it if this happens to you after you have spent 20 minutes answering configuration questions and fixing incorrect assumptions on the part of the configuration script. Either way: before running a \fImake clean\fR for the first time, make sure that you have a backup. .Li \fImake clean\fR can also start off by doing just the opposite: in early versions of the GNU C library, for example, it first compiled some things in order to determine what to clean up. This may work most of the time, but is still a Bad Idea: \fImake clean\fR is frequently used to clean up after some catastrophic mess, or when restarting the port on a different platform, and it should not be able to rely on being able to compile anything. .Li .XX "make, target, realclean" .XX "make, target, squeakyclean" Yet another problem with \fImake clean\fR is that some \fIMakefile\fRs have varying degrees of cleanliness, from \fIclean\fR via \fIrealclean\fR all the way to \fIsqueakyclean\fR. There may be a need for this, but it's confusing for casual users. .Le .Bh "Subordinate makes" .Pn Subordinate-makes .XX "make, problems, subordinate makes" .XX "make, target, install" .XX "make install" Some subordinate makes use a different target name for the subsidiary makes: you might write \fImake all\fR, but \fImake\fR might start the subsidiary \fImake\fRs with \fImake subdirs\fR. Although this cannot always be avoided, it makes it difficult to debug the \fIMakefile\fR. When modifying \fIMakefile\fRs, you may frequently come across a situation where you need to modify the behaviour of only one subsidiary \fImake\fR. For example, in many versions of System V, the \fIman\fR pages need to be formatted before installation. It's easy to tell if this applies to your system: if you install BSD-style unformatted man pages, the \fIman\fR program will just display a lot of hard-to-read nroff source. Frequently, fixing the \fIMakefile\fR is more work than you expect. A typical \fIMakefile\fR may contain a target \fIinstall\fR that looks like: .Ps install: for dir in ${SUBDIRS}; do \e echo making $@@ in $$dir; \e cd $$dir; ${MAKE} ${MDEFINES} $@@; \e cd ..; \e done .Pe \s10\f(CWmake $@@\fR\s0 expands to \s10\f(CWmake install\fR\s0. One of these subdirectories is the subdirectory \fIdoc\fR, which contains the documentation and requires special treatment for the \fIcatman\fR pages: they need to be formatted before installation, whereas the \fIman\fR pages are not formatted until the first time they are referenced--see \*[chdoc], page \*[man-pages] for further information. The simplest solution is a different target that singles out the \fIdoc\fR and makes a different target, say \fIinstall-catman\fR. This is untidy and requires some modifications to the variable \s10\f(CWSUBDIRS\fR\s0 to exclude \fIdoc\fR. A simpler way is to create a new target, \fIinstall-catman\fR, and modify \fIall\fR \fIMakefile\fRs to recognize it: .Ps install-catman install-manman: for dir in ${SUBDIRS}; do \e echo making $@@ in $$dir; \e cd $$dir; ${MAKE} ${MDEFINES} $@@; \e cd ..; \e done .Pe In the \fIMakefile\fRs in the subdirectories, you might then find targets like .Ps install-catman: ${MANPAGES} for i in $<; do ${NROFF} -man $$i> ${CATMAN}/$i; done install-manman: ${MANPAGES} for i in $<; do cp $$i> ${MANMAN}/$i; done .Pe The rule in the top-level \fIMakefile\fR is the same for both targets: you just need to know the name to invoke it with. In this example we have also renamed the original \s10\f(CWinstall\fR\s0 target so that it doesn't get invoked accidentally. By removing the \s10\f(CWinstall\fR\s0 target altogether, you need to make a conscious decision about what kind of man pages that your system wants. .LP We're not done yet: we now have exactly the situation we were complaining about on page \*[no-standard-target]: it is still a nuisance to have to remember \fImake install-catman\fR or \fImake install-manman\fR. We can get round this problem, too, with .Ps INSTALL_TYPE=install-catman install: ${INSTALL_TYPE} .Pe After this, you can just enter \fImake install\fR, and the target \fIinstall\fR performs the type of installation specified in the variable \s10\f(CWINSTALL_TYPE\fR\s0. This variable needs to be modified from time to time, but it makes it easier to avoid mistakes while porting. .Bh "Incorrect continuation lines" .Pn Incorrect-continuation-lines .XX "make, problems, incorrect continuation lines" \fIMakefile\fRs frequently contain numerous continuation lines ending with \s10\f(CW\e\fR\s0. This works only if it is the very last character on the line. A blank or a tab following the backslash is invisible to you, but it really confuses \fImake\fR. .LP .XX "make, problems, continued comments" Alternatively, you might continue something you don't want to. Consider the following \fIMakefile\fR fragment, taken from an early version of the \fIMakefile\fR for this book: .Ps PART1 = part1.ms config.ms imake.ms make.ms tools.ms compiler.ms obj.ms \e documentation.ms testing.ms install.ms epilogue.ms .Pe At some point I decided to change the sequence of chapters, and removed the file \fItools.ms\fR. I was not completely sure I wanted to do this, so rather than just changing the \fIMakefile\fR, I commented out the first line and repeated it in the new form: .Ps # PART1 = part1.ms config.ms imake.ms make.ms tools.ms compiler.ms obj.ms \e PART1 = part1.ms config.ms imake.ms make.ms compiler.ms obj.ms \e documentation.ms testing.ms install.ms epilogue.ms .Pe This works just fine--at first. In fact, it turns out that \fImake\fR treats all three lines as a comment, since the comment finished with a \s10\f(CW\e\fR\s0 character. As a result, the variable \s10\f(CWPART1\fR\s0 remained undefined. If you comment out a line that ends in \s10\f(CW\e\fR\s0, you should also remove the \s10\f(CW\e\fR\s0. .Bh "Prompts in Makefiles" .Pn Prompts-in-Makefiles .XX "make, problems, prompts in Makefile" If you do the Right Thing and copy your \fImake\fR output to a log file, you may find that \fImake\fR just hangs. The following kind of \fIMakefile\fR can cause this problem: .Ps all: checkclean prog checkclean: @@echo -n "Make clean first? " @@read reply; if [ "$$reply" = 'y' ]; then make clean; fi .Pe If you run \fImake\fR interactively, you will see: .Ps $ \f(CBmake\f(CW Make clean first? .Pe .XX "Linux" If you copy the output to a file, of course, you don't see the prompt, and it looks as if \fImake\fR is hanging. This doesn't mean it's a bad idea to save your \fImake\fR output: it's generally a bad idea to put prompts into \fIMakefiles\fR. There are some exceptions, of course. The Linux configuration program is a \fIMakefile\fR, and to interactively configure the system you enter \fImake config\fR. .Bh "Arg list too long" .Pn Arg-list-too-long .XX "make, problems, arg list too long" .Pn raise-arglist-size Sometimes \fImake\fR fails with this message, especially if you are running a System V system. Many versions of System V limit the argument list to 5120 bytes--we'll look at this in more detail in \*[chkdepend], page \*[arglist-size]. Modern versions of System V allow you to rebuild the kernel with a larger parameter list: modify the tuneable parameter \s10\f(CWARG_MAX\fR\s0 .XX "ARG_MAX" to a value in the order of 20000. If you can't do this, there are a couple of workarounds: .Ls B .Li The total storage requirement is the sum of the length of the argument strings and the environment strings. It's very possible that you have environment variables that aren't needed in this particular situation (in fact, if you're like me, you probably have environment variables that you will never need again). If you remove some of these from your shell startup file, you may get down below the limit. .Li You might be able to simplify expressions. For example, if your \fIMakefile\fR contains a line like .Ps clean: rm -rf *.o *.a *.depend *~ core ${INTERMEDIATES} .Pe .IP you can split it into .Ps clean: rm -rf *.o rm -rf *.a *.depend *~ core ${INTERMEDIATES} .Pe .IP In most large trees, the \fI*.o\fR filenames constitute the majority of the arguments, so you don't need more than two lines. .Li Even after the previous example, you might find that the length of the \fI*.o\fR parameters is too long. In this case, you could try naming the objects explicitly: .Ps clean: rm -rf [a-f]*.o rm -rf [g-p]*.o rm -rf [r-z]*.o rm -rf *.a *.depend *~ core ${INTERMEDIATES} .Pe .Li Alternatively, you could specify the names explicitly in the \fIMakefile\fR: .Ps OBJ1S = absalom.o arthur.o ... fernand.o OBJ2S = gerard.o guillaume.o ... pierre.o OBJ3S = rene.o roland.o ... zygyszmund.o OBJS = ${OBJ1S} ${OBJ2S} ${OBJ3S} clean: rm -rf ${OBJ1S} rm -rf ${OBJ2S} rm -rf ${OBJ3S} .Pe .Li .XX "xargs, program" .XX "program, xargs" Yet another method involves the use of the \fIxargs\fR program. This has the advantage of not breaking after new files have been added to the lists: .Ps clean: find . -name "*.o" -print | xargs rm -f .Pe .IP This chops up the parameter list into chunks that won't overflow the system limits. .Le .Ch "Creating executable files" The \fIxargs\fR method is not much help if you want to build an executable file. If the command that fails looks like .Ps ${PROG}: ${CC} ${ALLOBJS} -o ${PROG} .Pe there are some other possibilities. You might be able to shorten the pathnames. If you are building in a directory \fI/next-release/SOURCE/sysv/SCO/gcc-2.6.0\fR, and every file name in \s10\f(CWALLOBJS\fR\s0 is absolute, it's much easier to exceed the limit than if the directory name was, say, \fI/S\fR. You \fIcould\fR use a symbolic link to solve this problem, but most systems that don't support \s10\f(CWARG_MAX\fR\s0 also don't have symbolic links.\** .FS If you are on a network with other machines with more modern file systems, you could work around this problem by placing the files on the other system and accessing them via NFS. .FE .LP If this doesn't work, you could place the files in a library, possibly using \fIxargs\fR: .Ps ${PROG}: rm libkludge.a echo ${ALLOBJS} | xargs ar cruv libkludge.a ${CC} libkludge.a -o ${PROG} .Pe .XX "crt0.o, file" .XX "file, crt0.o" This looks strange, since there's no object file, but it works: by the time it finds the name \fIlibkludge.a\fR, the linker has already loaded the object file \fIcrt0.o\fR (see \*[chobj], page \*[crt0.o]), and is looking for a symbol \s10\f(CWmain\fR\s0. It doesn't care whether it finds it in an object file or a library file. .Ah "Modifying Makefiles" .Pn Modifying-Makefiles .XX "make, modifying Makefiles" Frequently enough, you find that the \fIMakefile\fR is inadequate. Targets are missing, or some error occurs that is almost untraceable: you need to fix the \fIMakefile\fR. Before you do this, you should check whether you are changing the correct \fIMakefile\fR. Some packages build a new \fIMakefile\fR every time you run \fImake\fR. In particular, you frequently see \fIMakefile\fRs that start with text like .Ps # Makefile generated by imake - do not edit! .Pe You can follow this advice or not: it depends on you and what you are doing: If you are just trying to figure out what the \fIMakefile\fR is trying (and presumably failing) to do, it's nice to know that you can subsequently delete your modified \fIMakefile\fR and have it automatically remade. .LP .XX "make, Makefile.in" .XX "Makefile.in" Once you have found out why the \fIMakefile\fR is doing what it is, you need to fix the source of the \fIMakefile\fR. This is not usually too difficult: the input files to the \fIMakefile\fR generation phase typically don't look too different from the finished \fIMakefile\fR. For example, \fIMakefile.in\fR in the GNU packages is a skeleton that is processed by \fIm4\fR, and except for the \fIm4\fR parameters \fIMakefile.in\fR looks very similar to the finished \fIMakefile\fR. Finding the way back to the \fIImakefile\fR from the \fIMakefile\fR requires a little more understanding of the \fIimake\fR process, but with a little practice it's not that difficult. @ 3.0 log @Final draft @ text @d2 1 a2 1 .\" $Id: building.ms,v 2.5 1995年06月20日 12:22:10 grog Exp grog $ d4 3 d909 1 d912 4 a915 1 your \fImake\fR output: it's a bad idea to put prompts into \fIMakefiles\fR. @ 2.6 log @Final draft, second cut @ text @a322 1 .\" Incorrect paths#\*[Incorrect-paths] a337 1 .\" Wrong shell#\*[Wrong-shell] d396 2 a397 2 OBJS = ${SRCS:.c=.o} \fIcorresponding object files\fCW CC=gcc \fIname of compiler\f(CW @ 2.5 log @Final draft, first cut. @ text @d2 1 a2 1 .\" $Id: building.ms,v 2.4 1995年06月09日 04:54:42 grog Exp grog $ d4 3 d46 2 a47 4 software product in our source tree. .LP Unfortunately, things don't always run smoothly. In this chapter, we'll look at the surprises that \fImake\fR can have in store for you. You can find the d50 2 d73 3 a75 3 different directories, not to mention running \fImake\fR and the debugger, and a single line of output from \fImake\fR can easily be 5000 or 10000 characters long, many times the screen capacity of a conventional terminal. d85 1 d143 1 d150 3 a152 3 have a reasonable expectation that it will not die immediately. The problem is, of course, that you may come back and find a lot of gobbldegook on the screen, such as: d170 2 a171 2 port. Evidently, the program \fImakedepend\fR did not get made, but why? The reason has long since scrolled off the screen.\** d175 4 a178 4 \s10\f(CWOSDefines\fR\s0 is a symbol used in X11 configuration. It should have been replaced by a series of compiler flags used to define the operating system to the package. In this case, the X11 configuration was messed up, and nothing defined \s10\f(CWOSDefines\fR\s0, so it found its way to the surface. d209 1 a209 1 easily get back to them. d305 1 a305 1 We'll look at each of these problems in the following sections. Here's an d343 1 a343 1 Sometimes \fImake\fR won't even let you in the door--you get a message like: d381 1 a381 1 In other words, the executable automatically gets made when you execute \fImake d390 7 a396 5 There is really nothing to build the package: the author is used to doing the compilation manually. In this case, your best bet is to write a \fIMakefile\fR from scratch. The following skeleton will get you a surprisingly long way: .Ps d423 1 a423 1 .Pe d620 1 a620 1 Some versions of \fImake\fR, notably Xenix, can't handle rules of the form d660 1 a660 1 This causes \fImake\fR to consider both lines as a single line, which then gets d671 1 a671 1 it prints if it doesn't get them is much more intelligible: d1002 1 a1002 1 could get around this problem by placing the files on the other system and d1044 2 a1045 2 the GNU packages is a skeleton that gets processed by \fIm4\fR, and except for the \fIm4\fR parameters \fIMakefile.in\fR looks very similar to the finished @ 2.4 log @Remove date from page headers Minor mods @ text @d2 1 a2 1 .\" $Id: building.ms,v 2.3 1995年05月16日 08:32:40 grog Exp grog $ d4 4 d793 6 a798 2 System V, the \fIman\fR pages need to be preformatted. A typical \fIMakefile\fR may contain a target \fIinstall\fR that looks like: @ 2.3 log @Major mods after Andy's final draft review @ text @d2 1 a2 1 .\" $Id: building.ms,v 2.2 1995年02月24日 10:14:27 grog Exp grog $ d4 3 d36 1 a36 1 .St "Building the package ($Date: 1995年02月24日 10:14:27 $)" d59 2 a60 2 the middle of a build, you might be able to save the day by stripping the objects with \fIstrip\fR. a76 1 .Le d87 5 a91 4 and out. The log file is the computer equivalent of the ball of string, so you should remember to roll it up again. If you're running an editor like \fIemacs\fR, which can handle multiple files at a time, you can keep the log in the editor buffer and remove the notes again when you back out the changes. d194 1 a194 1 These compararatively simple conventions can save a lot of pain. I use a d224 6 d293 2 a294 2 Everything may seem to be OK, but \fImake\fR still produces obscure error messages. d348 1 a348 1 for a System V machine, you may need to enter: d383 31 a413 1 \fIMakefile\fR from scratch. a419 1 .Le d465 1 a465 1 frequent sources of confusion is when a file can't be found. There are various d541 1 a541 1 One of the most insidious problems rebuilding programs comes when \fImake\fR d598 1 a598 1 /opt/bin/make subdir \fInote the space before "subdir"\f(CW d617 3 a619 2 stops. When you fix this problem, you run into a second one: it doesn't understand the second comment either. This time it produces an error message. d659 1 a659 1 \fImake\fR expects tabs too, but it recovers from the problem, and the message d709 1 a709 1 looping. This particular example was caused by the dependencies d804 4 a807 4 further information. The simplest solution is a different target that singles out the \fIdoc\fR and makes a different target, say \fIinstall-catman\fR. This is untidy and requires some modifications to the variable \s10\f(CWSUBDIRS\fR\s0 to exclude \fIdoc\fR. A simpler way is to create a new target, a808 1 .\" XXX Aaaargh. Page 72 of Andy's review - do it. d817 14 a830 5 In this example we have also renamed the other install target: the original \fImake install\fR would succeed even for systems that require formatted man pages, but the result would not be very useful. By removing the \s10\f(CWinstall\fR\s0 target altogether, you need to make a conscious decision about what kind of man pages you want. d841 1 a841 1 Like this, you can just enter \fImake install\fR, and the target \fIinstall\fR d1030 4 a1033 4 the \fIm4\fR parameters they look very similar to the finished \fIMakefile\fR. Finding the way back to the \fIImakefile\fR from the \fIMakefile\fR requires a little more understanding of the \fIimake\fR process, but with a little practice it's not that difficult. @ 2.2 log @Minor mods @ text @d2 1 a2 1 .\" $Id: building.ms,v 2.1 1995年02月17日 09:35:35 grog Exp grog $ d4 3 d33 1 a33 1 .St "Building the package ($Date: 1995年02月17日 09:35:35 $)" d39 2 a40 2 the surprises that \fImake\fR and the C compiler can have in store for you. You can find the corresponding theoretical material in \*[chmake]. d42 4 a45 4 If you're unlucky, a port can go seriously wrong. The first time error messages appear thick and fast and scroll off the screen before you can read them, you could get the impression that the packages were built this way deliberately to annoy you. d57 1 a57 1 objects. d59 6 a64 11 The sheer size of a complicated port can be a problem: .Ls B .Li Like program development, porting tends to be an iterative activity: edit a file, compile, link, test, go back to edit the file, and so on. .Li It's not uncommon to find yourself having to compare and modify up to 20 different files in 5 different directories, not to mention running \fImake\fR and the debugger. .Li A single line of output from \fImake\fR can easily be 5000 or 10000 characters d66 1 a66 1 .Le d68 6 a73 11 with a high-resolution monitor: .Ls B .Li You can keep your editor (or editors, if they don't easily handle multiple files) open all the time, and run the compiler and debugger in other windows. .Li If multiple directories are involved, it's easier to maintain multiple \fIxterm\fRs, one per directory, than to continually change directories. .Li A correctly set up \fIxterm\fR will allow you to scroll back as far as you want--I find that 250 lines is adequate. d80 1 a80 1 Sooner or later, you're going to run into a bug which you can't fix immediately: d85 4 a88 4 and out (see [Graves 55]). The log file is the computer equivalent of the ball of string. If you're running an editor like \fIemacs\fR, which can handle multiple files at a time, you can keep the log in the editor buffer and remove the notes again when you back out the changes. d108 1 a108 1 space. Compile with ISC gcc-2.5.8. d129 2 a130 2 \fImake\fR procedure. If you didn't have the log, you'd trip over this problem every time. d137 4 a140 4 sit and watch a package compile for hours on end, so you usually leave it alone once you have a reasonable expectation that it will not die immediately. The problem is, of course, that you may come back and find a lot of gobbldegook on the screen, such as: d161 6 a166 1 Well, there \fIis\fR a clue--do you see it? d186 5 d207 5 a211 1 \fImake depend\fR runs \fImakedepend\fR against your source tree. It should be d216 5 d228 3 a230 3 \fImake all\fR is the normal way to perform the build step. Frequently, it is the default target (the first target in the \fIMakefile\fR), and you just need to enter \fImake\fR. This target typically rebuilds the package but does not d260 3 a262 2 to the second half. A good example of this technique can be found in the \fIMakefile\fR for the GNU C compiler. d268 2 a269 2 $ \f(BImake\fR \fI\&lots of good messages from \fImake\f(CW d271 1 a271 2 Things don't always go this smoothly. You may encounter a number of problems running \fImake\fR: d294 1 a294 1 Problem#page d298 1 d302 1 d305 1 a305 1 Incorrect paths#\*[Incorrect-paths] d321 1 a321 1 Wrong shell#\*[Wrong-shell] d327 1 a327 1 $ \f(CBmake\f(CW d344 2 a345 2 This is a pain because it's so easy to make a mistake. In extreme cases you will even create formally correct objects that fail to link. d363 8 a370 8 In other words, it automatically gets made when you execute \fImake foo/foo\fR in the parent directory. As a rule, you start building in the root directory of a package, and perform explicit builds in subdirectories only if something is obviously wrong. .Li The author doesn't believe in \fIMakefile\fRs, and has provided a shell script instead. You often see this with programs which originated on platforms that don't have a \fImake\fR program. a380 7 .Li Somebody has hidden a file called \fImakefile\fR in the source tree. Most people today use the name \fIMakefile\fR for \fImake\fR's description file, probably because it's easier to see in an \fIls\fR listing, but \fImake\fR always looks for a file called \fImakefile\fR (with lower case \fIm\fR) first. If you are using GNU \fImake\fR, it first looks for a file called \fIGNUmakefile\fR before checking for \fImakefile\fR and \fIMakefile\fR. d388 3 a390 3 name for each kind of system to which the \fIMakefile\fR has been adapted. One of the more unusual ones is the \fIMakefile\fR for \fIgnuplot\fR. You need to enter d395 3 a397 13 The better ones at least warn you--you may find something like: .Ps build-bsd: ${DEPEND-BSD} \fI\&...commands\f(CW build-sysv: ${DEPEND-SYSV} \fI\&...commands\f(CW all: @@echo "Don't use all, use build-bsd or build-sysv" .Pe I personally don't like either of these solutions: it's so much easier to add the following line at the top of the \fIMakefile\fR: d417 8 d429 1 a429 1 with a file which \fImake\fR finds, but \fIyou\fR can't find. d477 4 a480 3 Most versions of \fImake\fR understand \s10\f(CWPATH\fR\s0, so the easiest way to fix such a \fIMakefile\fR is to remove the directory component of the definitions. d484 7 a490 12 Occasionally while building the compiler complains about a file that doesn't seem to be there. This can be due to the fact that the make is running in a subdirectory: large projects are frequently split up into multiple subdirectories, and all the top level \fIMakefile\fR does is to run a number of subordinate \fImake\fRs. If it is friendly, it also echos some indication of where it is at the moment, and if it dies you can find the file. If not, you have the option of searching for the file: .Ps $ \f(CBfind . -name foo.c -print .Pe or modifying the \fIMakefile\fR to tell you what's going on. Newer versions of GNU \fImake\fR print messages on entering and leaving a directory, for example: d497 5 d503 1 a503 1 One of the most insidious problems rebuilding programs is when \fImake\fR d510 1 a510 1 A weakness of \fImake\fR is that it requires to be told the interdependencies d515 2 a516 5 course to run a \fImake depend\fR after reconfiguring, assuming that this target is supplied. Otherwise you can get part of the way with .Ps $ \f(CBmakedepend *.c\f(CW .Pe d531 2 a532 2 messages you will see from \fImake\fR, but there are a large number of others as well. In this section, we'll look at other frequent problems. d538 1 a538 1 NAME = Definition # optional comment d540 1 a540 1 The exact \fIDefinition\fR starts at the first non-white space after the d565 3 d599 6 a604 6 The problem here is that each command is run by a new shell. The first one executes the \s10\f(CWcd doc\fR\s0 and then exits. The second one tries to execute the \s10\f(CWgroff\fR\s0 command. Since the \s10\f(CWcd\fR\s0 command doesn't affect the parent environment, it has no further effect, and you're still in the original directory. To do this correctly, you need to write the rule as: d617 5 a621 5 This strange message is usually complicated by the fact that it refers to a line that looks perfectly normal. In all probability it is trying to tell you that you have put leading spaces instead of a tab on a command line. BSD \fImake\fR expects tabs too, but it recovers from the problem, and the message it prints if it doesn't get them is much more intelligible: d634 2 a635 1 cannot handle this either, and produces the message: d676 4 a679 1 Real-life loops are, of course, usually more complex. d691 9 a699 8 and continue if the subsidiary \fIMakefile\fR dies. This is quite convenient if you want to leave it running overnight and collect all the information about numerous failures the next morning. It also makes it almost impossible to stop the make if you want to: hitting the \fIQUIT\fR key (CTRL-C on most systems) kills the currently running \fImake\fR, but the top-level \fImake\fR just starts the next subsidiary \fImake\fR. The only thing to do here is to identify the top-level \fImake\fR and stop it first, not an easy thing to do if you have only a single screen. d704 2 a705 1 \fImake clean\fR is supposed to put you back to square one with a build. d710 7 a716 3 doesn't know how to make. Sometimes this is just simple-mindedness on the part of the \fIMakefile\fR, but sometimes they remove things that you really can't get back again. d747 5 a751 5 is not usually a good idea. When modifying \fIMakefile\fRs, you may frequently come across a situation where you need to modify the behaviour of only one subsidiary \fImake\fR. For example, in many versions of System V, the \fIman\fR pages need to be preformatted. A typical \fIMakefile\fR may contain a target \fIinstall\fR that looks like: d762 9 a770 6 and requires special treatment for the \fIcatman\fR pages. One solution is a different target that singles out the \fIdoc\fR and makes a different target, say \fIinstall-catman\fR. This is untidy and requires some modifications to the variable \s10\f(CWSUBDIRS\fR\s0 to exclude \fIdoc\fR. A simpler way is to create a new target, \fIinstall-catman\fR, and modify \fIall\fR \fIMakefile\fRs to recognize it: d816 1 a816 1 just changing the \fIMakefile\fR, I commented out the first line and repeat it d826 1 a826 1 remained undefined. If you comment out a line which ends in \s10\f(CW\e\fR\s0, d852 1 d856 3 a858 4 \*[arglist-size], .Pn raise-arglist-size Modern versions of System V allow you to rebuild the kernel with a larger parameter list: modify the tuneable parameter \s10\f(CWARG_MAX\fR\s0 d868 2 a869 1 again). If you remove some of these, you may get down below the limit. d915 1 a915 1 advantage that it does not break after new files have been added to the lists: d925 2 a926 2 The \fIxargs\fR method is not much help if you want to build an executable file, for example. If the command that fails looks like d931 2 a932 4 there are a number of other possibilities: .Ls B .Li You might be able to shorten the pathnames. If you are building in a directory d943 3 a945 44 .IP .Li Alternatively, you could do something like: .Ps ${PROG}: ${CC} ${ALLOBJS} -o ${PROG} mywd=`pwd`; \e echo ${ALLOBJS} | sed 's:$$mywd::g' | xargs ${CC} -o ${PROG} .Pe .IP The \fIsed\fR command strips all occurrences of the directory name from the object file names, and passes them to \fIxargs\fR, which appends them to the command line. To get this to work, we had to change the sequence of arguments and move the object file names to the end of the line. .IP .XX "echo, program" .XX "program, echo" But wait a minute. I'm using \fIecho\fR with exactly the big command list that the compiler couldn't use. How come \fIecho\fR can handle it? There's no guarantee that it can: it depends on whether \fIecho\fR is run as a program or part of the shell. Most shells have a built-in \fIecho\fR function, so they don't need to pass \fIexec\fR and supply 200 parameters. If your shell doesn't have a built-in \fIecho\fR, there are two things to do: get a newer shell--it's probably missing a lot of other functionality as well--or use the \s10\f(CWfor\fR\s0 construct, which is built in to all shells. Here's the Bourne shell version: .Ps ${PROG}: ${CC} ${ALLOBJS} -o ${PROG} mywd=`pwd`; \e for i in ${ALLOBJS}; do echo $i; done \e | sed 's:$$mywd::g' \e | xargs ${CC} -o ${PROG} .Pe With \fIcsh\fR, you would write: .Ps ${CC} ${ALLOBJS} -o ${PROG} mywd=`pwd`; \e foreach i ( ${ALLOBJS} ); echo $i; end \e | sed 's:$$mywd::g' \e | xargs ${CC} -o ${PROG} .Pe .Li You could place the files in a library, possibly using \fIxargs\fR: a958 1 .Le a971 2 .Ls B .Li d975 1 a975 1 .Li d982 1 a982 1 the GNU packages is a skeleton which gets processed by \fIm4\fR, and except for a986 1 .Le @ 2.1 log @Minor mods, remove question flags @ text @d2 1 a2 1 .\" $Id: building.ms,v 1.8 1995年02月15日 14:47:17 grog Exp grog $ d4 3 d30 1 a30 1 .St "Building the package ($Date: 1995年02月15日 14:47:17 $)" d188 7 a194 3 These compararatively simple conventions can save a lot of pain. It's a good idea to always use the same name for the log files so that you can easily get back to them. @ 1.8 log @Minor mods @ text @d2 1 a2 1 .\" $Id: building.ms,v 1.6 1995年02月11日 13:03:32 grog Exp grog $ d4 3 d27 1 a27 1 .St "Building the package ($Date: 1995年02月11日 13:03:32 $)" a412 1 .\" XXX example? @ 1.7 log @Minor mods @ text @d41 2 a42 2 One of the most frequent reasons of failure of a build is that the disk fills up. If possible, ensure that you have enough space before you start. The d46 2 a47 2 debugging symbols (which take up a lot of space). If you do run out of space in the middle of a build, you might be able to save the day by stripping the @ 1.6 log @Checkin before Andy's suggested mods. @ text @d2 1 a2 1 .\" $Id: building.ms,v 1.5 1995年02月04日 09:11:40 grog Exp grog $ d4 3 d24 1 a24 1 .St "Building the package ($Date: 1995年02月04日 09:11:40 $)" d40 9 d77 1 a156 1 $ a246 1 $ a281 1 Incorrect source tree structure#\*[Incorrect-source-tree-structure] a304 1 $ a305 5 There can be a number of reasons for this message: there might not be a \fIMakefile\fR, there might be too many \fIMakefiles\fR, or the target \s10\f(CWall\fR\s0 might be missing. We'll investigate each of these possibilities below. .Bh "No Makefile" d308 8 a315 11 In some cases, it looks like there's no \fIMakefile\fR at all. If this is the case, the author should have documented where the \fIMakefile\fR comes from--check the \fIREADME\fR files and other documentation that came with the package. Typical problems finding a \fIMakefile\fR include: .Ls B .Li \fIDifferent names\fR. The \fIMakefile\fR is there, but the author has thought out some non-standard name for it. Some packages use separate \fIMakefile\fRs for different architectures. For example, \fIMakefile\fR may be correct only if you are compiling in a BSD environment. If you want to compile for a System V machine, you may need to enter: d322 3 d326 9 a334 22 The package may be supplied with an \fIImakefile\fR. This is the standard X11 method. As described in \*[chconfig], on page \*[xmkmf], you use \fIxmkmf\fR to create the \fIMakefile\fR from the \fIImakefile\fR. .Li Many packages, notably those from the Free Software Foundation, supply a shell script to generate the \fIMakefile\fR. We looked at this approach in \*[chconfig]. .Li .Pn emacs-make Some packages, such as \fIemacs\fR and \fIbash\fR, only use the \fIMakefile\fR to make the "real" \fIMakefile\fR and then execute it. In older versions of \fIemacs\fR, the \fIMakefile\fR used the input file \fIymakefile\fR to build the real \fIMakefile\fR, which was called \fIxmakefile\fR. It then used \fIxmakefile\fR to build emacs. This was transparent to the user. .XX "ymakefile" .XX "make, ymakefile" .XX "xmakefile" .XX "make, xmakefile" .Li Another possibility is that no \fIMakefile\fR is needed for the directory you are looking at. The \fIMakefile\fR in the parent directory, also part of the source tree, could contain rules like: a338 1 .IP d344 3 a346 3 Maybe the author doesn't believe in \fIMakefile\fRs, and has provided a shell script instead. You often see this with programs which originated on platforms that don't have a \fImake\fR program. d348 1 a348 1 Maybe there is really nothing to build the package: the author is used to doing a350 2 .Le .Bh "Wrong Makefile" d357 8 a364 11 Most people today use the name \fIMakefile\fR for \fImake\fR's description file, probably because it's easier to see in an \fIls\fR listing. This is \fInot\fR the standard name, however: \fImake\fR always looks for a file called \fImakefile\fR (with lower case \fIm\fR) first. If somebody has hidden a file called \fImakefile\fR in your source tree, \fImake\fR tries to execute it, and does not look at your \fIMakefile\fR. If you are using GNU \fImake\fR, it first looks for a file called \fIGNUmakefile\fR before checking for \fImakefile\fR and \fIMakefile\fR. .LP As we discussed above, there may be other \fIMakefile\fRs in the tree, and neither \fIMakefile\fR nor \fImakefile\fR may be the one you need. d370 4 a373 4 \s10\f(CWall\fR\s0 doesn't exist--that's easy enough to figure out. Some \fIMakefiles\fR have a different target name for each kind of system to which the \fIMakefile\fR has been adapted. One of the more unusual ones is the \fIMakefile\fR for \fIgnuplot\fR. You need to enter d399 1 a399 4 change the single line defining \s10\f(CWBUILD-TARGET\fR\s0. You could argue that this makes the \fIMakefile\fR less portable, but in fact \fIMakefiles\fR frequently need a certain amount of attention at the beginning of a port--we looked at this in detail in \*[chconfig]. d412 7 a418 1 Building a package refers to a large number of files: d421 2 a422 3 \fImake\fR examines the specified source files directly to determine their relative age. If it can't find one, and it can't find a rule to build one, it will fail with a message like: d428 9 d445 4 d450 2 a451 8 \fImake\fR may not be able to locate a program specified in a rule. You get a message like: .Ps $ \f(CBmake foo.o\f(CW /bin/cc -c foo.o -o foo.c make: execve: /bin/cc: No such file or directory make: *** [foo.o] Error 127 .Pe d453 4 a456 38 Occasionally, the opposite happens: \fImake\fR finds (and objects to) a file which doesn't seem to be there. .Le Of course, it's possible that the source files really don't exist, but it's more common to find that they're not where \fImake\fR is looking for them: the source tree is structured differently from the way \fImake\fR expects. The third problem is often a matter of incorrect source paths, and the fourth frequently happens when subordinate \fImake\fRs run in subdirectories. Let's look at these problems in more detail: .Bh "Incorrect source tree structure" .Pn Incorrect-source-tree-structure .XX "make, problems, incorrect source tree structure" In a large package with multiple source directories, there are are at least two ways to include files from other directories. For example, if you have a directory \fIsrc\fR with sources and a directory \fIconfig\fR with configuration information, you might see code like this in \fIsrc/foo.c\fR: .Ps #include "../config/sys.h" #include "../config/machine.h" .Pe or you might see: .Ps #include "sys.h" #include "machine.h" .Pe The first form has the advantage that it does not require multiple \f(CW-I\fR directives in order to compile the program. On the other hand, if somebody restructures the tree, which happens often enough to be irritating, this form requires all the source files to be modified. In the second case, you just need to change the \s10\f(CW-I\fR\s0 flags. .Bh "Incorrect paths" .Pn Incorrect-paths .XX "make, problems, incorrect paths" .XX "PATH, environment variable" Some older versions of \fImake\fR do not export the current \fIPATH\fR environment to the subordinate shell. As a result, many \fIMakefiles\fR go to great pains to specify the location of tools that \fImake\fR may use. You often see things like: d463 2 a464 3 This can be a problem if these tools are in different locations on your system. Most versions of \fImake\fR do understand \s10\f(CWPATH\fR\s0, so the easiest way to fix such a \fIMakefile\fR is to remove the directory component of the a465 17 .Bh "Wrong shell" .Pn Wrong-shell .XX "make, problems, wrong shell" Sometimes you might see something like .Ps make -f foomakefile foo.o gcc -c foo.o -o foo.c make: execve: /usr/bin/sh: No such file or directory make: *** [foo.o] Error 127 .Pe It's trying to run the compiler--why does it complain about the name of the shell? Don't forget that \fImake\fR doesn't execute commands directly, it always gets a shell to start the programs for it. By default \fImake\fR executes commands using the Bourne shell. If you want a different shell, many versions of \fImake\fR use the value of the variable \s10\f(CWSHELL\fR\s0 to indicate the shell you prefer to use. Nearly all \fIMakefile\fRs use Bourne shell syntax. I have never seen one with \fIcsh\fR syntax. d469 3 a471 3 Occasionally you get an error in a compile and the file it's complaining about doesn't seem to be there. This can be due to the fact that the make is running in a subdirectory: large projects are frequently split up into multiple d685 1 a685 1 Frequently, it doesn't achieve this result very well: d751 5 a755 6 The \fImake\fR variable \s10\f(CW$@@\fR\s0 refers to the target and is replaced with the name with which the target is invoked. In this example we have also renamed the other install target: the original \fImake install\fR would succeed even for systems that require formatted man pages, but the result would not be very useful. By removing the \s10\f(CWinstall\fR\s0 target altogether, you need to make a conscious decision about what kind of man pages you want. d780 2 a781 1 following \fIMakefile\fR fragment, taken from the \fIMakefile\fR for this book: d980 3 a982 3 the correct \fIMakefile\fR. As we saw on page \*[emacs-make], some packages build a new \fIMakefile\fR every time you run \fImake\fR. In particular, you frequently see \fIMakefile\fRs that start with text like @ 1.5 log @Minor mods @ text @d2 1 a2 1 .\" $Id: building.ms,v 1.4 1995年01月26日 12:24:31 grog Exp grog $ d4 3 d21 1 a21 1 .St "Building the package ($Date: 1995年01月26日 12:24:31 $)" d323 1 a323 1 method. As described in \*[chmake], on page \*[xmkmf], you use \fIxmkmf\fR to @ 1.4 log @Minor mods @ text @d2 1 a2 1 .\" $Id: building.ms,v 1.3 1995年01月25日 16:42:26 grog Exp grog $ d4 3 d18 1 a18 1 .St "Building the package ($Date: 1995年01月25日 16:42:26 $)" d592 2 a593 2 "\fI/opt/bin/make \fR"--it has a trailing blank, and the \fIexec\fR call fails. If you're lucky, you get: d838 1 a838 1 PART3 = part3.ms config.ms imake.ms make.ms tools.ms compiler.ms obj.ms \e d846 2 a847 2 # PART3 = part3.ms config.ms imake.ms make.ms tools.ms compiler.ms obj.ms \e PART3 = part3.ms config.ms imake.ms make.ms compiler.ms obj.ms \e d852 1 a852 1 \s10\f(CW\e\fR\s0 character. As a result, the variable \s10\f(CWPART3\fR\s0 d949 2 a950 1 .Li a956 1 .IP d958 1 a958 1 .Ls B "" "\-" d1024 1 a1024 1 finds the first file name, the linker has already loaded the object file a1058 23 .Le .Ah "Summary" \fIAndy--I've let this here for your consideration, but I'd rather remove it. It's almost word for word what I wrote at the beginning of the chapter. I think summaries look good in chapters where I've described a few topics in detail, such as in the hardware dependencies chapter, but in this chapter I've discussed a lot of topics superficially, and there's not much I can say in summary. I think we could leave the summaries in those chapters where they are useful, and remove them in others--possibly we could change the heading from "summary" to something else. What do you think? XXX\fR Probably not even the X Consortium, which makes extensive use of all the arcane features of \fImake\fR, would claim that it is anywhere near ideal. But we're stuck with it, at least for the foreseeable future. In this chapter, we looked at how to make the best of it, in particular: .Ls B .Li We saw a brief overview of the main features of \fImake\fR. .Li We looked at additional features and incompatibilities of GNU and BSD \fImake\fR. .Li We looked at some of the more common problems running \fImake\fR, and how to deal with them. @ 1.3 log @Minor mods @ text @d2 1 a2 1 .\" $Id: building.ms,v 1.2 1995年01月24日 16:03:00 grog Exp grog $ d4 3 d15 1 a15 1 .St "Building the package ($Date: 1995年01月24日 16:03:00 $)" d167 55 @ 1.2 log @Minor mods @ text @d2 1 a2 1 .\" $Id: building.ms,v 1.1 1995年01月23日 09:27:18 grog Exp grog $ d4 3 d12 1 a12 1 .St "Building the package ($Date: 1995年01月23日 09:27:18 $)" d20 48 d69 95 d200 3 a202 3 Arg list too long#\*[Arg-list-too-long] Circular dependency dropped#\*[Circular-dependency-dropped] Commands commence before first target#\*[Commands-commence-before-first-target] d209 1 a209 1 Missing separator - stop#\*[Missing-separator-stop] @ 1.1 log @Initial revision @ text @d2 4 a5 2 .\" $Id: make.ms,v 2.0 1994年12月22日 14:27:50 grog Exp grog $ .\" $Log: make.ms,v $ d9 9 a17 1 .St "Building the package ($Date: 1994年12月22日 14:27:50 $)" d21 70 a90 12 Many programmers look upon a \fIMakefile\fR as a necessary evil and don't do more than the absolute minimum to get it to run. The result can be that the \fIMakefile\fR won't do what you want it to do. On the other hand, some \fIMakefile\fRs can be so convoluted that they are almost inpenetrable--the \fIMakefile\fRs for earlier versions of the GNU C library are a good example. Either way, they can cause you problems. .LP Problems running \fImake\fR seem all the more complicated because of the recursive nature of \fImake\fR: if a problem occurs, it is frequently difficult to figure out what it has to do with what you are trying to do, and how \fImake\fR got there in the first place. In this section, we'll look at some of the more common problems, how they occur, and how you can solve them. d92 1 d113 2 a114 2 method. As described in \*[chimake], you use \fIxmkmf\fR to create the \fIMakefile\fR from the \fIImakefile\fR. d142 1 a142 1 obviously wrong, as it may well be even in otherwise well-conceived packages. d150 1 a150 2 \fIMakefile\fR from scratch. As we saw earlier in the chapter, this is not difficult. d152 18 a169 9 .Bh "Wrong flavour of make" .XX "make, problems, wrong flavour" Sometimes \fImake\fR produces messages that make no sense at all: the compiler tries to compile the same file multiple times, each time giving it a different object name, or it claims not to be able to find files that exist. One possible explanation is that various flavours of \fImake\fR have somewhat different understandings of default rules. In particular, BSD make and GNU make do not understand each other very well. .\" XXX example? d171 1 d174 5 a178 2 After you have established that you have a \fIMakefile\fR, you may find you can't do much with it: you get a message like a179 8 $ \f(CBmake all\f(CW make: don't know how to make all. Stop .Pe Well, maybe it doesn't have a target called \s10\f(CWall\fR\s0--that's easy enough to figure out. Some \fIMakefiles\fR have a different target name for each kind of system to which the \fIMakefile\fR has been adapted. One of the more unusual ones is the \fIMakefile\fR for \fIgnuplot\fR. You need to enter .Ps d206 111 a316 21 frequently need a certain amount of attention at the beginning of a port--see \*[chconfig] for more information. .Bh "Wrong Makefile" .XX "make, problems, wrong Makefile" .XX "GNUmakefile file" .XX "makefile file" .XX "make, GNUmakefile file" .XX "make, makefile file" Most people today use the name \fIMakefile\fR for \fImake\fR's description file, probably because it's easier to see in an \fIls\fR listing. This is \fInot\fR the standard name, however: \fImake\fR always looks for a file called \fImakefile\fR (with lower case \fIm\fR) first. If somebody has hidden a file called \fImakefile\fR in your source tree, \fImake\fR tries to execute it, and does not look at your \fIMakefile\fR. If you are using GNU \fImake\fR, it first looks for a file called \fIGNUmakefile\fR before checking for \fImakefile\fR and \fIMakefile\fR. .LP As we discussed above, there may be other \fIMakefile\fRs in the tree, and neither \fIMakefile\fR nor \fImakefile\fR may be the one you need. .Bh "Problems with recursive makes" .XX "make, problems, recursive makes" d335 5 d341 1 d354 1 d365 4 d370 1 d402 1 d412 2 a413 75 stops. When you fix it, you discover that it doesn't understand the second comment either. This time it produces an error message. .Bh "Incorrect source tree structure" .XX "make, problems, incorrect source tree structure" In a large package with multiple source directories, there are are at least two ways to include files from other directories. For example, if you have a directory \fIsrc\fR with sources and a directory \fIconfig\fR with configuration information, you might see some code like this in \fIsrc/foo.c\fR: .Ps #include "../config/sys.h" #include "../config/machine.h" .Pe or you might see: .Ps #include "sys.h" #include "machine.h" .Pe The first form has the advantage that it does not require multiple \f(CW-I\fR directives in order to compile the program. On the other hand, if somebody restructures the tree, which happens often enough to be irritating, this form requires all the source files to be modified. In the second case, you just need to change the \s10\f(CW-I\fR\s0 flags. .\" If you have a set of .\" files that don't correspond to the tree structure, and you don't have time to .\" modify all the source files, you can often save the situation by creating a .\" symbolic link to the directory from where the source files expect to find them. .\" This must be a symbolic link, since you can't create normal links to .\" directories. If, for example, your source tree has had \fIconfig\fR replaced .\" with two new directories, \fIs\fR for system headers and \fIm\fR for machine .\" headers, so that these two files are now called \fIs/sys.h\fR and .\" \fIm/machine.h\fR, you can create appropriate linkages with .\" .Ps .\" $ \f(CBcd s\f(CW .\" $ \f(CBln -s . config\f(CW .\" $ \f(CBcd ../m\f(CW .\" $ \f(CBln -s . config\f(CW .\" $ \f(CBcd ..\f(CW .\" $ \f(CBcc -Is -Im foo.c\f(CW .\" .Pe .\" The compiler looks for the header files in the following sequence: .\" \fIconfig/sys.h\fR (not found), \fIs/config/sys.h\fR (found: \fIs/config\fR .\" points to \fIs\fR, so the file found is really \fIs/sys.h\fR), .\" \fIconfig/machine.h\fR (not found), \fIs/config/machine.h\fR (not found), .\" \fIm/config/machine.h\fR (found: \fIm/config\fR points to \fIm\fR, so the .\" compiler finds the file \fIm/machine.h\fR. .Bh "Modifying Makefiles" .XX "make, modifying Makefiles" Frequently enough, you find that the \fIMakefile\fR is inadequate. Targets are missing, or some error occurs that is almost untraceable: you need to fix the \fIMakefile\fR. Before you do this, you should check whether you are changing the correct \fIMakefile\fR. As we saw on page \*[emacs-make], some packages build a new \fIMakefile\fR every time you run \fImake\fR. In particular, you frequently see \fIMakefile\fRs that start with text like .Ps # Makefile generated by imake - do not edit! .Pe You can follow this advice or not: it depends on you and what you are doing: .Ls B .Li If you are just trying to figure out what the \fIMakefile\fR is trying (and presumably failing) to do, it's nice to know that you can subsequently delete your modified \fIMakefile\fR and have it automatically remade. .Li .XX "make, Makefile.in" .XX "Makefile.in" Once you have found out why the \fIMakefile\fR is doing what it is, you need to fix the source of the \fIMakefile\fR. This is not usually too difficult: the input files to the \fIMakefile\fR generation phase typically don't look too different from the finished \fIMakefile\fR. For example, \fIMakefile.in\fR in the GNU packages is a skeleton which gets processed by \fIm4\fR, and except for the \fIm4\fR parameters they look very similar to the finished \fIMakefile\fR. Finding the way back to the \fIImakefile\fR from the \fIMakefile\fR requires a little more understanding of the \fIimake\fR process, but with a little practice (and after reading \*[chimake]) it's not that difficult. .Le d415 1 a445 7 .Bh "Wrong shell" .XX "make, problems, wrong shell" By default \fImake\fR executes commands using the Bourne shell. If you want a different shell, many versions of \fImake\fR use the value of the variable \s10\f(CWSHELL\fR\s0 to indicate the shell you prefer to use. Nearly all \fIMakefile\fRs use Bourne shell syntax. I have never seen one with \fIcsh\fR syntax. d447 1 d459 1 d473 1 d488 1 d493 1 a493 4 obscure: \s10\f(CW$! nulled, predecessor circle\fR\s0, and BSD \fImake\fR isn't much more help: \s10\f(CWGraph cycles through \f(CIdocs\fR\s0. In each case, what the message is trying to tell you is that your dependencies are looping. This particular example was caused by the dependencies d495 9 d510 1 d517 1 a527 17 .Bh "Incorrect paths" .XX "make, problems, incorrect paths" .XX "PATH, environment variable" Some versions of \fImake\fR, such as SunOS, do not evalues the current \fIPATH\fR environment variable in order to find tools. As a result, many \fIMakefiles\fR go to great pains to specify the location of tools that \fImake\fR may use. You often see things like: .Ps AR = /bin/ar AS = /bin/as CC = /bin/cc LD = /bin/cc .Pe This can be a problem if these tools are in different locations on your system. Most versions of \fImake\fR do understand \s10\f(CWPATH\fR\s0, so the easiest way to fix such a \fIMakefile\fR is to remove the directory component of the definitions. d529 1 d552 2 a553 2 catastrophic mess, and it should not be able to rely on being able to compile anything. d562 3 a564 2 .Bh "Recursive makes" .XX "make, problems, recursive makes" d567 1 a567 1 Some recursive makes use a different target name for the subsidiary makes: you d620 1 d649 1 d670 1 d673 3 a675 2 System V system. As we saw in \*[chkdepend], page \*[arglist-size], many versions of System V limit the argument list to 5120 bytes. d708 2 a709 2 parameters is too long. In this case, you could try explicit naming of the objects: d783 7 a789 7 guarantee that it will run on your system: it depends on whether \fIecho\fR is run as a program or part of the shell. Most shells have a built-in \fIecho\fR function, so they don't need to pass \fIexec\fR and supply 200 parameters. If your shell doesn't have a built-in \fIecho\fR, there are two things to do: get a newer shell--it's probably missing a lot of other functionality as well--or use the \s10\f(CWfor\fR\s0 construct, which is built in to all shells (though the C shell syntax differs): d798 8 d811 1 a811 1 echo ${ALLOBJS} |xargs ar cruv libkludge.a d817 35 a851 3 finds the first file name, the linker has already loaded \fIcrt0.o\fR (see \*[chobj], page \*[crt0.o]), and is looking for a symbol \s10\f(CWmain\fR\s0. It doesn't care whether it finds it in an object file or a library file. a875 939 .Ah "Compiler warnings" .XX "C, compiler warnings" It's easy to make mistakes when writing programs, but it used to be even easier: nowadays, even the worst compilers attempt to catch dubious constructs and warn you about them. In this section, we'll look at what they can and can't do. .LP Before compilers worried about coding quality, the program \fIlint\fR performed this task. \fIlint\fR is still around, but hardly anybody uses it any more, since it is available only on System V systems, and it requires significant setup to work correctly. This is a pity, because \fIlint\fR can catch a number of dubious situations that evade most compilers. .XX "lint, program" .LP Modern compilers can recognize two kinds of potential problems: .Ls B .Li Problems related to dubious program text, like .Ps if (a = 1) return; .Pe .IP The first line of this example is almost superfluous: if I allocate the value \s10\f(CW1\fR\s0 to \s10\f(CWa\fR\s0, I don't need an \s10\f(CWif\fR\s0 to tell me what the result will be. In all probability, this is caused by a typo, and the text should have been .Ps if (a == 1) return; .Pe .Li Problems related to program flow. These are detected by the flow analysis phase of the optimizer. For example: .Ps int a; b = a; .Pe .IP The second line uses the value of \s10\f(CWa\fR\s0 before it has been assigned a value. The optimizer notices this omission and may print a warning. .Le In the following sections, we'll examine typical warning messages, how they are detected and how reliable they are. We'll use the GNU C compiler warning messages a basis, since the GNU C compiler has a particularly large choice of warning messages, and since it is also widely used. Other compilers will warn about the same kind of problems, but the messages may be different. .Bh "Expressions with no effect" .XX "C, warning, expressions with no effect" The possibility of confusion between the operators \s10\f(CW=\fR\s0 and \s10\f(CW==\fR\s0 can also lead to mistakes like: .Ps if (x> 3) a == 4; .Pe This is syntactically perfectly valid C code, but it doesn't do much: under certain circumstances, the value of \s10\f(CWa\fR\s0 is compared with 4. And nothing else. .LP In all probability, this is a typo, and the programmer had intended to write \s10\f(CWa = 4\fR\s0. The \s10\f(CW-W\fR\s0 flag causes a warning to be issued for this kind of construct. .Bh "Implicit declarations" .XX "C, warning, implicit declarations" In ANSI C, it is good practice to declare all functions and parameters before use. If you specify the \s10\f(CW-Wimplicit\fR\s0 flag to \fIgcc\fR, it issues a warning if a function or parameter name is used before being declared. .XX "C, gcc, -Wimplicit flag" .Bh "Incomplete function prototypes" .XX "C, warning, incomplete function prototypes" Some flavours of C allow "incomplete" function declarations, where the return type or the types of some parameters default to \s10\f(CWint\fR\s0. If you specify the \s10\f(CW-Wstrict-prototypes\fR\s0 flag to \fIgcc\fR, it warns you if you declare or define a function without supplying the full information about parameters and return type. .XX "C, gcc, -Wstrict-prototypes flag" .Bh "Missing function prototypes in headers" .XX "C, warning, missing function prototypes" You can be even more pedantic about function prototypes and require that there should always be a function declaration in a header file before you encounter the function definition. You can get \fIgcc\fR to do this, too, by specifying the \s10\f(CW-Wmissing-prototypes\fR\s0 flag. .XX "C, gcc, -Wmissing-prototypes flag" .Bh "Implicit return type" .XX "C, warning, implicit return type" K&R C allowed programs like .Ps main () { printf ("Hello, World!\en"); } .Pe ANSI C has two problems with this program: .Ls B .Li The function name \s10\f(CWmain\fR\s0 does not specify a return type. It defaults to \s10\f(CWint\fR\s0. .Li Since \s10\f(CWmain\fR\s0 is implicitly an \s10\f(CWint\fR\s0 function, it should return a value. This one does not. .Le Both of these situations can be caught by specifying the \s10\f(CW-Wreturn-type\fR\s0 flag to \fIgcc\fR. This causes the following messages: .XX "C, gcc, -Wreturn-type flag" .Ps $ \f(CBgcc -c hello.c -Wreturn-type\f(CW hello.c:2: warning: return-type defaults to `int' hello.c: In function `main': hello.c:4: warning: control reaches end of non-void function .Pe .Bh "Inconsistent function returns" .XX "C, warning, inconsistent function returns" The following function does not always return a defined value: .Ps foo (int x) { if (x> 3) return x - 1; } .Pe If \s10\f(CWx\fR\s0 is greater than 3, this function returns \s10\f(CWx - 1\fR\s0. Otherwise it returns with some uninitialized value, since there is no explicit \s10\f(CWreturn\fR\s0 statement for this case. This problem is particularly insidious, since the return value will be the same for every invocation on a particular architecture (probably the value of \s10\f(CWx\fR\s0), but this is a by-product of the way the compiler works, and may be completely different on some other architecture. .Bh "Uninitialized variables" .XX "C, warning, uninitialized variables" Consider the following code: .Ps void foo (int x) { int a; if (x> 5) a = x - 3; bar (a); .Pe Depending on the value of \s10\f(CWx\fR\s0, \s10\f(CWa\fR\s0 may or may not be initialized when you call \s10\f(CWbar\fR\s0. If you select the \f(CW-Wuninitialized\fR\s0 compiler flag, it warns you when this situation occurs. Current versions of \fIgcc\fR place some limitations on this test--other compilers, including newer versions of \fIgcc\fR, may not: .XX "C, gcc, -Wuninitialized flag" .Ls B .Li It works only when the optimizer is in use, since it relies on data flow information computed by the optimizer. .Li It occurs only for variables that could be stored in registers. This excludes \s10\fIvolatile\fR\s0 variables, variables whose address is used explicitly, and variables with sizes other than 1, 2, 4 or 8 bytes. .XX "C, volatile type qualifier" .Li It also excludes structures, unions and arrays. .Le .Bh "Signed comparisons of unsigned values" .XX "C, warning, signed comparisons" Occasionally you see code of the form .Ps int foo (unsigned x) { if (x>= 0) \fI\&... etc\fR .Pe Since \s10\f(CWx\fR\s0 is unsigned, its value is \fIalways\fR>= 0, so the \s10\f(CWif\fR\s0 is superfluous. This kind of problem is surprisingly common: system header files may differ in opinion as to whether a value is signed or unsigned. The flag \s10\f(CW-W\fR\s0 causes the compiler to issue warnings for this situation. .Bh "Dubious arithmetic comparisons" .XX "C, warning, dubious comparisons" The statment .Ps if (a <= b <= c) .Pe is perfectly syntactically valid C. First, it compares the values of \s10\f(CWa\fR\s0 and \s10\f(CWb\fR\s0. The result of this comparison (0, if \s10\f(CWa\fR\s0 is greater than \s10\f(CWb\fR\s0, 1 otherwise) is compared with \s10\f(CWc\fR\s0. This may be what is intended, of course, but then it would be better to write it as .Ps if ((a <= b) <= c) .Pe which means the same thing. The original notation looks so much like mathematical notation that the author probably intended to write: .Ps if ((a <= b) && (b <= c)) .Pe The \s10\f(CW-W\fR\s0 flag causes a warning to be issued when this kind of construct is encountered. .Bh "Character subscripts to arrays" .XX "C, warning, character subscripts" Frequently, the subscript to an array is a character. Consider the following code: .Ps char iso_translate [256] = /* translate table for ISO 8859-1 to LaserJet */ { \fI\& codes for the first 160 characters\f(CW 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, \fI\&... etc\f(CW }; #define xlate(x) iso_translate [x]; char *s; /* pointer in buf */ for (*s = buf; *s; s++) *s = xlate (*s); .Pe The intention of \s10\f(CWxlate\fR\s0 is to translate text to a form used by older model HP LaserJet printers. This code does not work like this: the character \s10\f(CW*s\fR\s0 is a signed value by default, and so the characters \s10\f(CW0x80\fR\s0 to \s10\f(CW0xff\fR\s0 are expanded to a negative array offset, and the program attempts (maybe successfully) to access a byte outside the table \s10\f(CWiso_translate\fR\s0. \fIgcc\fR warns about this if you set the flag \f(CW-Wchar-subscripts\fR\s0. .XX "C, gcc, -Wchar-subscripts flag" .Bh "Unused variables" .XX "C, warning, unused variables" As we discussed at the beginning of the section, the compiler can detect and report variables that are defined but not used. Non-static global variables are excluded from this test, since they are known externally and could be used by other modules. Specify the \s10\f(CW-Wunused\fR\s0 flag to get these warnings. .XX "C, gcc, -Wunused flag" .LP Occasionally, this can be a nuisance. For example, if you are using RCS, you might have the following code: .Ps static char rcs_id [] = "$\&Id: foo.c,v 1.6 1994/08/07 11:49:03 grog Exp grog $"; .Pe The compiler complains about every one of these, since nothing in the program refers to it. You can prevent this warning with the following macro (suggested by the \fIgcc\fR documentation): .Ps #define USE(var) static void * use_##var = (&use_##var, (void *) &var) USE (string); .Pe This creates a pointer to the string, which takes up space, but gets rid of the warning message. It's your decision whether this is a cleaner state of affairs. .Bh "Incorrect formats for printf and scanf" .XX "C, warning, incorrect formats" The function \s10\f(CWscanf\fR\s0 is usually defined as .Ps int scanf (const char *format, ...); .Pe The ellipses (\s10\f(CW...\fR\s0) state that a variable number of parameters may follow: in fact, it is the format string that determines how many parameters to use. Consider what happens if I write .Ps scanf ("%d %d %d %d", &i); .Pe The call syntax is correct, but when I call \s10\f(CWscanf\fR\s0 it will probably overwrite its return information and generate a segmentation fault when it tries to return. \fIgcc\fR can recognize this situation, if the \s10\f(CW-Wformat\fR\s0 flag is specified, by comparing the format string to the parameters. This requires format string to be a string literal. For example, it won't work with .XX "C, gcc, -Wformat flag" .Ps char *format = "%d %d %d %d"; scanf (format, &i); .Pe .Bh "Dequalifying types" .XX "C, warning, dequalifying types" The following code fragment can cause problems: .Ps char *spray; void foo (const char *holy) { spray = holy; .Pe The assignment of \s10\f(CWholy\fR\s0 to \s10\f(CWspray\fR\s0 loses the qualifier \s10\f(CWconst\fR\s0, and the compiler complains about the fact. On the other hand, this is valid: .Ps spray = (char *) holy; .Pe This doesn't make it a better idea: \s10\f(CWholy\fR\s0 is supposed to be unchangeable, and here you are removing this qualifier. If you specify the \s10\f(CW-Wcast-qual\fR\s0 flag to \fIgcc\fR, it complains anyway if you use a cast to remove a type qualifier such as \s10\fIconst\fR\s0. .XX "C, gcc, -Wcast-qual flag" .XX "C, const type qualifier" .Bh "Increasing alignment requirements" .XX "C, warning, increasing alignment requirements" We saw in \*[chhard], page \*[wordalign], that many processors require that specific data types be aligned on specific boundaries, and that the results can be spectacular if they are not. We can easily outsmart the C compiler with code like: .Ps void foo (char *x) { int *ip = (int *) x; .Pe In this case, there is a good chance that the \s10\f(CWint *\fR\s0 pointer \s10\f(CWip\fR\s0 requires a specific alignment and is not allowed to point at any address in memory the way the \s10\f(CWchar\fR\s0 pointer \s10\f(CWx\fR\s0 is allowed to do. If you specify the \s10\f(CW-Wcast-align\fR\s0 flag to \fIgcc\fR, it warns you of such assignments. .XX "C, gcc, -Wcast-align flag" .Bh "Implicit conversions between enums" .XX "C, warning, implicit conversions" .XX "C, enum type" .XX "C, gcc, -Wenum-clash flag" On page \*[enums] we saw a case where a variable of one \s10\fIenum\fR\s0 type was assigned to a variable of a different \s10\f(CWenum\fR\s0 type. If you specify the \s10\f(CW-Wenum-clash\fR\s0 flag to \fIgcc\fR, \fIand\fR you're compiling C++, it warns about this. .Bh "Incomplete switch statements" .XX "C, warning, incomplete switch statements" .XX "C, switch statement" .XX "C, case label" .XX "C, gcc, -Wswitch flag" A frequent cause of error in a \s10\fIswitch\fR\s0 statement is that the index variable (the variable that decides which case is chosen) may assume a value for which no \s10\fIcase\fR\s0 has been specified. If the index variable is an \s10\f(CWint\fR\s0 of some kind, there is not much you can do except include a \s10\f(CWdefault\fR\s0 clause. If the index variable is an \s10\f(CWenum\fR\s0, the compiler can check that \s10\f(CWcase\fR\s0 clauses exist for all the possible values of the variable, and warns if they do not. It also warns if \s10\f(CWcase\fR\s0 clauses exist for values which are not defined for the type of the index variable. Specify the \s10\f(CW-Wswitch\fR\s0 flag for these warnings. .Bh "long indices for switch" .XX "C, warning, long indices for switch" In some dialects of pre-ANSI C, you could write things like .Ps foo (x) long x; { switch (x) { \fI\&... etc\fR .Pe .XX "C, gcc, -traditional flag" This is no longer allowed in ANSI C: indices for \s10\f(CWswitch\fR\s0 must evaluate to an \s10\f(CWint\fR\s0, even if \s10\f(CWint\fR\s0 and \s10\f(CWlong\fR\s0 have the same length. \fIgcc\fR issues a warning about \s10\f(CWlong\fR\s0 indices in \s10\f(CWswitch\fR\s0 unless you specify the \s10\f(CW-traditional\fR\s0 flag. .Bh "Writeable strings" .XX "C, warning, writeable strings" .XX "C, gcc, -Wwrite-strings flag" As we saw on page \*[writeable-strings], it is possible to write code that writes into string constants. This may not work at run time, depending on the way the compiler generates the code, but compilers don't normally generate any message if you try. If you start \fIgcc\fR with the \s10\f(CW-Wwrite-strings\fR\s0 flag, it gives string constants the type \s10\f(CWconst char []\fR\s0. This causes a warning if you assign string constants to \s10\f(CWchar *\fR\s0 pointers. This works properly only if you are religious about using \s10\f(CWconst\fR\s0 in declarations and prototypes--otherwise you get lots of irrelevant messages. .Bh "Changing non-volatile automatic variables" .XX "C, warning, changing non-volatile automatic variables" .XX "C, volatile type qualifier" .XX "setjmp, function" We discussed \fIvolatile\fR variables on page \*[volatile]. Under certain circumstances, a signal handler might modify a local automatic variable if the function has called \s10\f(CWsetjmp\fR\s0. \fIgcc\fR flags this situation as a warning if you specify the \s10\f(CW-W\fR\s0 flag. This is a complicated problem: .Ls B .Li It can occur only during an optimizing compilation, since the keyword \s10\fIvolatile\fR\s0 only has meaning in these circumstances. In addition, the situation is recognized only by the optimizer. .Li .XX "longjmp, function" The optimizer cannot recognize when a \s10\f(CWlongjmp\fR\s0 could be performed. This depends on semantics outside the scope of the optimizer. As a result, it could issue this warning when there is, in fact, no danger. .Le .Bh "Invalid keyword sequences in declarations" .XX "C, warning, invalid keyword sequences" Currently, it is permissible to write declarations like .Ps int static bad_usage; .Pe .XX "C, static storage class" Here the storage class specifier \s10\fIstatic\fR\s0 comes after the type specifier \s10\f(CWint\fR\s0. The ANSI Standard still permits this, but declares the usage to be obsolescent. \fIgcc\fR issues a warning when it encounters this and the flag \s10\f(CW-W\fR\s0 has been set. .Bh "Incorrectly initialized aggregates" .XX "C, warning, incorrectly initialized aggregates" Consider the following code segment .Ps struct foo {int bar, baz; }; struct frotzel {struct foo fritz; int franz; int erwin; }; struct frotzel motzel = {1, 2, 3}; .Pe The first element of \s10\f(CWfrotzel\fR\s0 is of type \s10\f(CWfoo\fR\s0, but the initializer assigns the value \s10\f(CW\&1\fR\s0 to it. If the \s10\f(CW-W\fR\s0 flag is specified, \fIgcc\fR flags this as a warning. I consider this to be an error. .Bh "Trigraphs" .XX "C, warning, trigraphs" .XX "C, gcc, -Wtrigraphs flag" Trigraphs (see page \*[trigraphs]) are no error, at least according to the ANSI Standard. The Free Software Foundation makes no bones about their opinion of them, and so \fIgcc\fR supplies the flag \s10\f(CW-Wtrigraphs\fR\s0, which prints a warning if any trigraphs occur in the source code. Since this works only if the flag \s10\f(CW-trigraphs\fR\s0 is used to enable them, it is not clear that this is of any real use. .Bh "Nested comments" .XX "C, warning, nested comments" .Pn nested-comments Occasionally you see code like .Ps void foo (int x) { int y; /* state information y = bar (); /* initialize y */ if (y == 4) \fI\&... etc\fR .Pe The code looks reasonable, and it is syntactically correct C, but in fact the comment after the declaration of \s10\f(CWy\fR\s0 is not terminated, so it includes the whole of the next line, which is almost certainly not the intention. \fIgcc\fR recognizes this if it finds the sequence \s10\f(CW/*\fR\s0 in a comment, and warns of this situation if you specify the \s10\f(CW-Wcomment\fR\s0 flag. .XX "C, gcc, -Wcomment flag" .Bh "Missing parentheses" .XX "C, warning, missing parentheses" What value does the following code return? .Ps int a = 11 << 4 & 7 << 2> 4; .Pe .XX "Kernighan, Brian" .XX "Ritchie, Dennis" The result is 0, but the real question is: in what order does the compiler evaluate the expression? You can find the real answer on page 53 of [K&R 88], but you don't want to do that all the time. We can re-write the code as .Ps int a = (11 << 4) & ((7 << 2)> 4); .Pe .XX "C, gcc, -Wparentheses flag" This makes it a lot clearer what is intended. \fIgcc\fR warns about what it considers to be missing parentheses if you select the \s10\f(CW-Wparentheses\fR\s0 flag. By its nature, this flag is subjective, and you may find that it complains about things that look fine to you. .Bh "Macro arguments in strings" .XX "C, warning, macro arguments in strings" .XX "C, gcc, -traditional flag" Some older versions of C replaced a macro argument in a string by the actual parameter. ANSI C does not do this, and the \fIgcc\fR preprocessor warns about it unless the \s10\f(CW-traditional\fR\s0 flag has been specified. .Bh "Functions with embedded extern definitions" .XX "C, warning, embedded extern definitions" K&R C would allow you to write things like .Ps int datafile; foo (x) { extern open (); datafile = open ("foo", 0777); } .Pe .XX "C, extern declaration" .XX "C, gcc, -traditional flag" .XX "C, gcc, -Wnested-externs flag" The \s10\fIextern\fR\s0 declaration was then valid until the end of the source file. In ANSI C, the scope of \s10\f(CWopen\fR\s0 would be the scope of \s10\f(CWfoo\fR\s0: outside of \s10\f(CWfoo\fR\s0, it would no longer be known. \fIgcc\fR issues a warning about \s10\f(CWextern\fR\s0 statements inside a function definition unless you supply the \s10\f(CW-traditional\fR\s0 flag. If you are using \s10\f(CW-traditional\fR\s0 and want these messages, you can supply the \s10\f(CW-Wnested-externs\fR\s0 flag as well. .Bh "Aggregate returns" .XX "C, warning, aggregate returns" In C, you can write code like .Ps struct foo { float y; int x; char text [20]; }; struct foo fritz; struct foo *franz; struct foo bar () { static struct foo foobar; /* return this struct */ \fI\&...\f(CW return foobar; } struct foo *baz () { static struct foo foobaz; /* return a pointer to this struct */ \fI\&... stuff\f(CW return &foobaz; } main () { \fI\&...\f(CW fritz = bar (); franz = baz (); .Pe The size of \s10\f(CWfoo\fR\s0 is about 32 bytes, depending on your \s10\f(CWint\fR\s0 and \s10\f(CWfloat\fR\s0 representation. This may seem a minor detail, but consider the two statements in \s10\f(CWmain\fR\s0: .Ls B .Li In \s10\f(CWfritz = bar ()\fR\s0, \s10\f(CWbar\fR\s0 computes a result and then returns the complete result to the calling function. To do this, the compiler typically copies the struct to a private global area before leaving the function. Back in \s10\f(CWmain\fR\s0, it copies this area into \s10\f(CWfritz\fR\s0. This is not a very efficient way to do things, even with 32 bytes. .Li \s10\f(CWfranz = baz ()\fR\s0 looks just the same, but here \s10\f(CWbaz\fR\s0 just returns a pointer to \s10\f(CWfoobaz\fR\s0, which is stored in \s10\f(CWfranz\fR\s0, and is much faster. .Le .XX "C, gcc, -Waggregate-return flag" It's easy to confuse these two ways of returning struct information. \fIgcc\fR warns you if you specify the \s10\f(CW-Waggregate-return\fR\s0 flag. .Ah "Problems running the compiler" .XX "C, problems running compiler" Of course, apart from warnings, you frequently see error messages from the compiler--they are still the most common reason for a build to fail. In this section, we'll look at some of the more common ones. .Bh "Undefined symbols" .XX "C, error message, undefined symbols" One of the most frequent compiler error messages you see during porting is that some symbol or another is not defined. At first sight, it seems strange that the compiler should find undefined symbols in a program which has already been installed on another platform: if there are such primitive errors in it, how could it have worked? .LP In almost every such case, you will find one of two problems: .Ls B .Li .XX "C, #ifdef directive" The definition you need may have been \fI#ifdef\fR'ed out. For example, in a manually configured package, if you forget to specify a processor architecture, the package may try to compile with no processor definitions, which is sure to give rise to this kind of problem. .Li The symbol may have been defined in a header file on the system where it was developed; this header file does something different on your system, so the symbol you need is never defined. .Le .XX "link.h, header file" .XX "gdb, program" While the second problem may seem odd, it's not that uncommon. For example, in most versions of UNIX System V.4.2, the system header file \fIlink.h\fR defines information and structures used by debuggers. In UnixWare 1.0, it defines information used by some Novell-specific communications protocols. If you try to compile \fIgdb\fR under UnixWare 1.0, you will have problems as a result: the system simply does not contain the definitions you need. .LP .XX "O_NDELAY" .XX "open, function" .XX "_POSIX_SOURCE" Something similar happens on newer System V systems with POSIX.1 compatibility: a program that seems formally correct may fail to compile with an undefined symbol \f(CWO_NDELAY\fR. \f(CWO_NDELAY\fR is a flag to \s10\f(CWopen\fR\s0, which specifies that the call to \s10\f(CWopen\fR\s0 should not wait for completion of the request. This can be very useful, for example, when the \s10\f(CWopen\fR\s0 is on a serial line and will not complete until an incoming call occurs. The flag is supported by almost all modern UNIX ports, but it is not defined in POSIX.1. The result is that the definition is carefully removed if you compile defining \f(CW-D_POSIX_SOURCE\fR. .LP .XX "O_NOCTTY" The solution seems straightforward enough: \f(CW#undef _POSIX_SOURCE\fR. If you do this, you may find that suddenly other macros are undefined, for example \f(CWO_NOCTTY\fR. System V.4 only defines this variable if \f(CW_POSIX_SOURCE\fR is set. .LP There's no obvious general solution to this problem. It is really caused by messy programming style: the programmer has mixed symbols defined only by POSIX.1 with those which are not defined in POSIX.1. The program may run on your current system, but may stop doing so at the next release. .Bh "Conflicts between preprocessor and compiler variables" .XX "C, conflicts between preprocessor and compiler variables" Occasionally you'll see things that seem to make absolutely no sense at all. For example, porting \fIgcc\fR, you could run into this problem: .Ps gcc -c -DIN_GCC -g -O3 -I. -I. -I./config \e -DGCC_INCLUDE_DIR=\e"/opt/lib/gcc-lib/i386--sysv/2.6.0/include\e" \e -DGPLUSPLUS_INCLUDE_DIR=\e"/opt/lib/g++-include\e" \e -DCROSS_INCLUDE_DIR=\e"/opt/lib/gcc-lib/i386--sysv/2.6.0/sys-include\e" \e -DTOOL_INCLUDE_DIR=\e"/opt/i386--sysv/include\e" \e -DLOCAL_INCLUDE_DIR=\e"/usr/local/include\e" \e -DSTD_PROTO_DIR=\e"/opt/lib/gcc-lib/i386--sysv/2.6.0\e" \e ./protoize.c \&./protoize.c:156: macro `puts' used without args .Pe If you look at this part of \fIprotoize.c\fR, you'll see lots of external definitions: .Ps extern int fflush (); extern int atoi (); extern int puts (); extern int fputs (); extern int fputc (); extern int link (); extern int unlink (); .Pe Line 156 is, not surprisingly, the definition of \s10\f(CWputs\fR\s0. But this is a definition, not a call, and certainly not a macro. And why didn't it complain about all the other definitions? There were many more than shown here. .LP .XX "preprocessor output, examining" .XX "C preprocessor output, examining" .Pn preprocessor-output In cases like this, it's good to remember that the compiler is \fInot\fR looking at this source file: the file has already passed through the preprocessor, and by the time it gets to the compiler it looks quite different. Let's look at the code that the compiler sees. We use the \s10\f(CW-E\fR\s0 flag to tell the compiler to stop after the preprocessor phase. In this case, we append to the command line: .Ps $ gcc -c -DIN_GCC -g -O3 -I. -I. -I./config \e -DGCC_INCLUDE_DIR=\e"/opt/lib/gcc-lib/i386--sysv/2.6.0/include\e" \e -DGPLUSPLUS_INCLUDE_DIR=\e"/opt/lib/g++-include\e" \e -DCROSS_INCLUDE_DIR=\e"/opt/lib/gcc-lib/i386--sysv/2.6.0/sys-include\e" \e -DTOOL_INCLUDE_DIR=\e"/opt/i386--sysv/include\e" \e -DLOCAL_INCLUDE_DIR=\e"/usr/local/include\e" \e -DSTD_PROTO_DIR=\e"/opt/lib/gcc-lib/i386--sysv/2.6.0\e" \e ./protoize.c \f(CB-E -o junk.c\f(CW $ .Pe We call the output file \fIjunk.c\fR, not the more correct \fIjunk.i\fR, because \fIemacs\fR doesn't understand the suffix \fI.i\fR, and so it does not load the correct macros. \fIjunk.c\fR consists of mainly empty lines. It starts with: .Ps # 1 "./config.h" 1 # 1 "./config/i386/xm-i386.h" 1 \fI40 empty lines\f(CW # 1 "./tm.h" 1 \fI19 empty lines\f(CW # 1 "./config/i386/gas.h" 1 \fI22 empty lines\f(CW .Pe This file seems to consist mainly of empty lines, and the lines that aren't empty don't seem to be C! In fact, the \s10\f(CW#\fR\s0 lines \fIare\fR C (see the \s10\f(CWline\fR\s0 directive on page \*[line-directive]), except that in this case the keyword \s10\f(CWline\fR\s0 has been omitted. The empty lines are where comments and preprocessor directives used to be. We're looking for line 156 of \fIprotoize.c\fR, so we should search for lines with \s10\f(CWprotoize.c\fR\s0 on them. We find a number of them: .Ps $ \f(CBgrep protoize.c junk.c\f(CW # 1 "./protoize.c" # 39 "./protoize.c" 2 # 59 "./protoize.c" 2 # 62 "./protoize.c" 2 # 63 "./protoize.c" 2 \fI\&... etc\f(CW # 78 "./protoize.c" 2 # 222 "./protoize.c" .Pe Clearly, our text is between lines 78 and 222. We position on the line \fIafter\fR the marker for line 78 and move down (156 - 78) or 78 lines. There we find: .Ps extern int fflush (); extern int atoi (); extern int ((fputs(( ), stdout) || (( stdout )->__bufp < ( stdout )->__put_limit ? (int) (unsigned char) (*( stdout )->__bufp++ = (unsigned char) ( '\n' )) :__flshfp (( stdout ), (unsigned char) ( '\n' ))) == (-1) ) ? (-1) : 0) ; extern int fputs (); extern int fputc (); extern int link (); extern int unlink (); .Pe .XX "C, gcc, -dD flag" Well, at any rate it's now clear why the compiler was complaining. But where did this junk come from? It can be difficult to figure this out. With \fIgcc\fR you can use the \s10\f(CW-dD\fR\s0 flag to keep the preprocessor definitions--unfortunately, the other preprocessor directives are still removed. If we use this flag as well, we find in \fIjunk.c\fR: .Ps # 491 "/opt/include/stdio.h" 2 \fI25 lines missing\f(CW extern int fputs (__const char *__s, FILE *__stream) ; /* Write a string, followed by a newline, to stdout. */ extern int puts (__const char *__s) ; #define puts(s) ((fputs((s), stdout) || __putc('\n', stdout) == EOF) ? EOF : 0) .Pe This looks strange: first we declare \s10\f(CWputs\fR\s0 as an external function, then we define it as a macro. This doesn't worry the preprocessor, but the results certainly worry the compiler. Looking at the original source of \fIstdio.h\fR, we see: .Ps /* Write a string, followed by a newline, to stdout. */ extern int puts __P ((__const char *__s)); #ifdef __OPTIMIZE__ #define puts(s) ((fputs((s), stdout) || __putc('\n', stdout) == EOF) ? EOF : 0) #endif /* Optimizing. */ .Pe No, this doesn't make sense--it's a real live bug in the header file. At the very least, the declaration of \s10\f(CWputs\ ()\fR\s0 should have been in an \s10\f(CW#else\fR\s0 clause. But that's not the real problem: too many programs try to define external functions where they're not needed, and this kind of definition would break them all. .LP .XX "indent, program" Preprocessor output usually looks even more illegible than this, particularly if lots of clever nested \f(CW#define\fRs have been performed. To make it more legible, especially if you find yourself in the unenviable position of having to modify it, you can run the preprocessor output through a program like \fIindent\fR, which improves legibility considerably. Before using \fIindent\fR, make note of the lines where the errors appeared. \fIindent\fR is not guaranteed to maintain the same number of lines. .Bh "Other preprocessors" .XX "C, other preprocessors" .XX "yacc, program" .XX "bison, program" .Pn other-preprocessors There are many other cases in which the source file you use is not the source file that the compiler gets. Examples are \fIyacc\fR and \fIbison\fR, which take a grammar file and make a (more or less illegible) \fI\&.c\fR file out of it; other examples are database preprocessors like Informix ESQL, which takes C source with embedded SQL statements and converts it into a form that the C compiler can compile. The preprocessor's output is intended to be read by a compiler, not by humans. .LP All of these preprocessors use lines beginning with \f(CW#\fR to insert information about the original line numbers and source files into their output. Not all of them do it correctly: the preprocessor should not insert extra lines into the source, otherwise you might end up with something like this example from an early version of Informix ESQL: .Ps #line 3326 "d3form.ec" date = key->valid_from; malloccheck (new = (struct mdef *) malloc (sizeof (struct mdef)), (&d3xstr[7043]) ); { static char *_sqlcmdtxt[] = { (&d3xstr[7081]), (&d3xstr[7157]), 0}; static _SQCURSOR _SQ0 = {0}; static struct sqlvar_struct _sqibind[] = { {103, sizeof(long)}, {103, sizeof(long)}, }; static struct sqlvar_struct _sqobind[] = { {103, sizeof(long)}, {100, 21}, {103, sizeof(long)}, {103, sizeof(long)}, }; _sqibind[0].sqldata =(char *)&date; _sqibind[1].sqldata =(char *)&date; _sqobind[0].sqldata =(char *)&mdef.field_number; \fI\&line 3352\f(CW _sqobind[1].sqldata =mdef.default_value; _sqobind[2].sqldata =(char *)&mdef.valid_from; _sqobind[3].sqldata =(char *)&mdef.valid_to; _iqslct(&_SQ0, _sqlcmdtxt, 2, _sqibind, 4, _sqobind); ;} #line 3343 "d3form.ec" new->field_number = mfld.field_number; /* take this entry anyway */ if (! sqlca.sqlcode) /* found--isn't this fun? */ { new->field_number = mdef.field_number; strcpy (new->default_value, mdef.default_value); new->valid_from = mdef.valid_from; new->valid_to = mdef.valid_to; } else new->default_value [0] = '0円'; /* no default */ \fI\&line 3352\f(CW CHKSQLERR ((&d3xstr[7225])); *data = new; /* return it */ } .Pe .XX "C, #line directive" Informix ESQL creates a slightly different format: the \f(CW#\fR lines include the keyword \f(CWline\fR, and don't have a trailing number. This format is easier on human eyes, but for the compiler the meaning is identical. The problem is that there are 33 lines of code between the two \fI#line\fR directives, which are supposed to be 17 lines apart. The original SQL \fIselect\fR statement has been expanded to many more output lines. This doesn't worry the compiler, but it means that we have two lines with the line number 3352. If you want to set a breakpoint on the real line 3352 (the second one), there's a good chance that you will set it on the first occurrence instead. If you single step through such code, the debugger will try to map the line numbers to the original source file and show you complete garbage. .Bh "Syntax errors" .XX "C, syntax errors" Syntax errors in previously functional programs usually have the same causes as undefined symbols, but they hit in a different way. A favourite one results from omitting \fI/usr/include/sys/types.h\fR. For example, consider \fIbar.c\fR: .Ps #include #ifdef USG #include #endif ushort num; int main (int argc, char *argv []) { num = atoi (argv [1]); printf ("First argument: %d\en", num); .\" AMAZING! You got the \n to print right the first time! This is a .\" seriously good sign. } .Pe If you compile this under BSD/OS, you get: .Ps $ \f(CBgcc -o bar bar.c\f(CW bar.c:6: parse error before `num' bar.c:6: warning: data definition has no type or storage class .Pe There's an error because \f(CWushort\fR hasn't been defined. The compiler expected a type specifier, so it reported a syntax error, not an undefined symbol. .Bh "Virtual memory exhausted" .XX "C, error, virtual memory exhausted" You occasionally see this message, particularly when you're using \fIgcc\fR, which has a particular hunger for memory. This may be due to unrealistically low virtual memory limits for your system--by default, some systems limit total virtual memory per process to 6 MB, but \fIgcc\fR frequently requires 16 or 20 MB of memory space, and on occasion it can use up to 32 MB. If your system has less than this available, increase the limit accordingly. Don't forget to ensure that you have enough swap space! .LP Sometimes this doesn't help. \fIgcc\fR seems to have particular difficulties with large data definitions; bit map definitions in X11 programs are the sort of things that cause problems. \fIxphoon\fR, which displays a picture of the current phase of the moon on the root window, is a good example of a \fIgcc\fR-breaker. .Bh "Compiler limits exceeded" .XX "C, error, compiler limits exceeded" .XX "C, #define directive" .XX "indent, program" Some compilers have difficulties with complicated expressions. This can cause \fIcc1\fR, the compiler itself, to fail with messages like "expression too complicated" or "out of tree space." Fixing such problems can be tricky. Straightforward code shouldn't give the compiler indigestion, but some nested \fI#define\fRs can cause remarkable increases in the complexity of expressions: in some cases, a single line can expand to over 16K of text. One way to get around the problem is to preprocess the code and then break the preprocessed code into simpler expressions. The \fIindent\fR program is invaluable here: preprocessor output is not intended to be human-readable, and most of the time it isn't. .Bh "Running compiler passes individually" .XX "C, running compiler passes individually" As we saw on page \*[cc], a compilation consists of four distinct passes. Running the linker separately is very common; running the assembler is the way to assemble \fI\&.s\fR files; but the first three phases usually run without interruption. Sometimes running the other phases separately can be useful as well: .Ls B .Li If you find yourself with header files that confuse your preprocessor, you can run a different preprocessor, collect the output and feed it to your compiler. Since the preprocessor is not machine-dependent, you could even do this on a different machine with different architecture, as long as you ensure that you use the correct system header files. As we saw on page \*[source-suffices], the preprocessor output for \fIfoo.c\fR would be called \fIfoo.i\fR, though it usually does no harm to pass preprocessed output through a preprocessor, since there should no longer be anything for the second preprocessor to do. .\" Also: Are you going to show us how to "substitute preprocessors"? .\" grog: must I? .Li If you want to report a compiler bug, it's frequently a good idea to supply the preprocessor output: the bug might be dependent on some header file conflict that doesn't exist on the system where the compiler development takes place. .Li If you suspect the compiler of generating incorrect code, you can stop compilation after the compiler phase and collect the generated assembler output. .Le .Bh "Incorrect code from compiler" .XX "C, incorrect code from compiler" Compilers sometimes generate incorrect code. Incorrect code is frequently difficult to debug because the source code looks (and might be) perfect. For example, a compiler might generate an instruction with an incorrect operand address, or it might assign two variables to a single location. About the only thing you can do here is to analyze the assembler output. .LP .XX "C, gcc, -v flag" One kind of compiler bug is immediately apparent: if the code is so bad that the assembler can't assemble it, you get messages from the assembler. Unfortunately, the message doesn't usually tell you that it comes from the assembler, but the line numbers change between the compiler and the assembler. If the line number seems completely improbable, either because it is larger than the number of lines in your source file, or because it seems to have nothing to do with the context of that line, there is a chance that the assembler produced the message There are various ways to confirm which pass of the compiler produced the message. If you're using \fIgcc\fR, the simplest one is to use the \f(CW-v\fR flag for the compiler, which "announces" each phase of compilation as it starts, together with the version numbers and parameters passed to the phase. This makes it relatively easy to figure out which pass is printing the error messages. Otherwise you can run the passes individually, as we saw on page \*[cc]. .\" XXX This is, of course, far too little. Since we're so far over target .\" already, and this would need at least 10 pages to do it justice, I think .\" we should just omit it. .\" .Bh "Cross-building and multiple targets" .\" A surprising number of problems arise when you start building software for a .\" different environment. Typical situations are .\" .Ls B .\" .Li .\" Building for a system which for some reason is not available for a direct .\" installation, like a production system that has to continue running an old .\" version of the software until the new version has been completely debugged. .\" .Li .\" Building for a similar machine with too few resources to run the software .\" development tools. This can include license restrictions. .\" .Li .\" Building for a remote system. .\" .Li .\" Building a standalone package for a system which does not run the same operating .\" system .\" .Li .\" Building a package for a machine with a different architecture. .\" .Li .\" Building multiple versions of a package. This could happen, for example, when .\" testing various build options, or building kernels for a number of machines in a .\" network. .\" .Le .\" Most problems encountered building in heterogeneous environments stem from .\" implicit usage of the machine's own properties, in particular the header and .\" library files. In the case of cross-compilation, even the other tools are .\" suspect. @

AltStyle によって変換されたページ (->オリジナル) /