Building the Package
Total Page:16
File Type:pdf, Size:1020Kb
5 Building the package Nowwehav e 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 make can have instore for you. Youcan find the corresponding theoretical material in Chapter 19, Make. Preparation If you’re unlucky, a port can go seriously wrong. The first time that error messages appear thick and fast and scroll offthe screen before you can read them, you could get the impression that the packages were built this way deliberately to annoyyou. Alittle bit of preparation can go a long way towards keeping you in control of what’sgoing on. Here are some suggestions: Makesure you have enough space One of the most frequent reasons of failure of a build is that the file system fills up. If possi- ble, ensure that you have enough space before you start. The trouble is, howmuch is enough? Hardly anypackage will tell you howmuch 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 takeupalot 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 objects with strip,inother words removing the symbols from the file. Use a windowing system The sheer size of a complicated port can be a problem. Likeprogram 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’snot uncommon to find yourself having to compare and modify up to 20 different files in 5 different directories, not to mention running make and the debugger.Inadddition, a single line of output from make can easily be 5000 or 10000 characters long, manytimes the screen capacity of a conventional terminal. 59 5February 2005 02:09 60 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 theydon’teasily handle multiple files) open all the time, and run the compiler and debugger in other windows. If multiple directories are involved, it’seasier to maintain multiple xterms, one per directory,than to con- tinually change directories. Acorrectly set up xterm will allowyou to scroll back as far as you want — I find that 250 lines is adequate. Keep a log file Sooner or later,you’re going to run into a bug that you can’tfiximmediately: you will have to experiment a bit before you can fix the problem. Likefinding your way through a labyrinth, the first time through you will probably not takethe most direct route, and it’snice to be able to find your way back again. In the original labyrinth, Theseus used a ball of string to find his wayboth 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 emacs,which can handle multiple files at a time, you can keep the log in the edi- tor buffer and remove the notes again when you back out the changes. 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. Tobeofuse likethis, it helps to keep additional information. Forexample, here are some extracts from a log file for the gcc: 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" 5February 2005 02:09 Chapter 5: Building the package 61 fi truncate_target=yes ;; Keeping notes about problems you have with older versions helps a lot: this example repre- sents the results of a considerable time spent debugging the make procedure. If you didn’t have the log, you’drisk tripping overthis problem every time. Save makeoutput Typically,tobuild a package, after you have configured it, you simply type $ make Then the fireworks start. Youcan sit and watch, but it gets rather boring to watch a package compile for hours on end, so you usually leave italone once you have a reasonable expecta- tion 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: 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 This is from a real life attempt to compile X11R6, normally a fairly docile port. The target makedepend failed to compile, but why? The reason has long since scrolled offthe screen.* Youcan have your cakeand eat it too if you use tee to save your output: $ make 2>&1 | tee -a Make.log This performs the following actions: •Itcopies error output (file descriptor 2) to standard output (file descriptor 1) with the expression 2>&1. •Itpipes the combined standard output to the program tee,which echos it to its standard output and also copies it to the file Make.log. *Well, there is aclue, but it’svery difficult to see unless you have been hacking X11 configurations longer than is good for your health. OSDefines 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 OSDefines,soitfound its way to the surface. 5February 2005 02:09 62 •Inthis case, I specified the -a option, which tells tee to append to anyexisting Make.log. If I don’tsupply this flag, it will erase anyprevious contents. Depending on what you’re doing, you may or may not want to use this flag. If you’re not sure what your make is going to do, and especially if the Makefile is complicated, consider using the -n option. This option tells make to perform a “dry run”: it prints out the commands that it would execute, but doesn’tactually execute them. These comparatively simple conventions can save a lot of pain. Iuse a primitive script called Make which contains just the single line: make 2>&1 $* | tee -a Make.log It’sagood idea to always use the same name for the log files so that you can find them easily. Standard targets Building packages consists of more than just compiling and linking, and by convention many Makefilescontain a number of targets with specific meanings. In the following sections we’ll look at some of the most common ones. makedepend makedepend creates a list of dependencies for your source tree, and usually appends it to the Makefile.Usually it will perform this task with makedepend,but sometimes you will see a depend target that uses gcc with the -M flag or cpp. depend should be the first target to run, since it influences which other commands need to be executed. Unfortunately,most Makefiles don’thav e a depend target. It’snot difficult to write one, and it pays offinthe reduction of strange, unaccountable bugs after a rebuild of the package. Here’sastarting point: depend: makedepend *.[ch] 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,ifthe package is this complicated, it will also have a depend target. Even if you have a depend target, it does not always work as well as you would hope. If you makesome really far-reaching changes, and things don’twork the way you expect, it’sworth starting from scratch with a makeclean to be sure that the makestill works. makeall makeall is the normal way to perform the build.