1835 lines
		
	
	
	
		
			72 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			1835 lines
		
	
	
	
		
			72 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| <!-- $Id: devel.docb,v 1.3 1997-08-17 17:33:49 jfieber Exp $ -->
 | |
| <!-- The FreeBSD Documentation Project -->
 | |
| 
 | |
| <!DOCTYPE BOOK PUBLIC "-//Davenport//DTD DocBook V3.0//EN">
 | |
| <book>
 | |
| <bookinfo>
 | |
| <bookbiblio>
 | |
| <title>A User's Guide to FreeBSD Programming Tools</title>
 | |
| 
 | |
| <authorgroup>
 | |
| <author>
 | |
| <firstname>James</firstname>
 | |
| <surname>Raynard</surname>
 | |
| <affiliation>
 | |
| <address>
 | |
| <email>jraynard@freebsd.org</email>
 | |
| </address>
 | |
| </affiliation>
 | |
| </author></authorgroup>
 | |
| 
 | |
| <pubdate>August 17, 1997</pubdate>
 | |
| 
 | |
| <copyright>
 | |
| <year>1997</year>
 | |
| <holder>James Raynard</holder>
 | |
| </copyright>
 | |
| 
 | |
| <abstract><para>This document is an introduction to using some of the programming
 | |
| tools supplied with FreeBSD, although much of it will be applicable to
 | |
| many other versions of Unix. It does <emphasis>not</emphasis> attempt to describe
 | |
| coding in any detail. Most of the document assumes little or no
 | |
| previous programming knowledge, although it is hoped that most
 | |
| programmers will find something of value in it</para></abstract>
 | |
| </bookbiblio>
 | |
| </bookinfo>
 | |
| 
 | |
| <chapter>
 | |
| <title>Introduction<anchor id=foo></title>
 | |
|   
 | |
| <para>FreeBSD offers an excellent development environment. Compilers
 | |
| for C, C++, and Fortran and an assembler come with the basic system,
 | |
| not to mention a Perl interpreter and classic Unix tools such as
 | |
| <command>sed</> and <command>awk</>. If that is not enough, there are
 | |
| many more compilers and interpreters in the Ports collection. FreeBSD
 | |
| is very compatible with standards such as <acronym>POSIX</> and
 | |
| <acronym>ANSI</> C, as well with its own BSD heritage, so it is
 | |
| possible to write applications that will compile and run with little
 | |
| or no modification on a wide range of platforms.</para>
 | |
| 
 | |
| <para>However, all this power can be rather overwhelming at first if
 | |
| you've never written programs on a Unix platform before. This
 | |
| document aims to help you get up and running, without getting too
 | |
| deeply into more advanced topics. The intention is that this document
 | |
| should give you enough of the basics to be able to make some sense of
 | |
| the documentation.</para>
 | |
| 
 | |
| <para>Most of the document requires little or no knowledge of
 | |
| programming, although it does assume a basic competence with using
 | |
| Unix and a willingness to learn!</para>
 | |
|   
 | |
| </chapter>
 | |
| 
 | |
| <chapter>
 | |
| <title>Introduction to Programming</title>
 | |
| 
 | |
| <para>A program is a set of instructions that tell the computer to do
 | |
| various things; sometimes the instruction it has to perform depends
 | |
| on what happened when it performed a previous instruction. This
 | |
| section gives an overview of the two main ways in which you can give
 | |
| these instructions, or <quote>commands</quote> as they are usually
 | |
| called. One way uses an <firstterm>interpreter</>, the other a
 | |
| <firstterm>compiler</>. As human languages are too difficult for a
 | |
| computer to understand in an unambiguous way, commands are usually
 | |
| written in one or other languages specially designed for the
 | |
| purpose.</para>
 | |
| 
 | |
| 
 | |
|   
 | |
| <sect1>
 | |
| <title>Interpreters</title>
 | |
| 
 | |
| <para>With an interpreter, the language comes as an environment, where you
 | |
| type in commands at a prompt and the environment executes them for
 | |
| you. For more complicated programs, you can type the commands into a
 | |
| file and get the interpreter to load the file and execute the commands
 | |
| in it. If anything goes wrong, many interpreters will drop you into a
 | |
| debugger to help you track down the problem.</para>
 | |
|   
 | |
| <para>The advantage of this is that you can see the results of your
 | |
| commands immediately, and mistakes can be corrected readily. The
 | |
| biggest disadvantage comes when you want to share your programs with
 | |
| someone. They must have the same interpreter, or you must have some
 | |
| way of giving it to them, and they need to understand how to use it.
 | |
| Also users may not appreciate being thrown into a debugger if they
 | |
| press the wrong key! From a performance point of view, interpreters
 | |
| can use up a lot of memory, and generally do not generate code as
 | |
| efficiently as compilers.</para>
 | |
| 
 | |
| <para>In my opinion, interpreted languages are the best way to start
 | |
| if you have not done any programming before. This kind of environment
 | |
| is typically found with languages like Lisp, Smalltalk, Perl and
 | |
| Basic. It could also be argued that the Unix shell (<command>sh</>,
 | |
| <command>csh</>) is itself an interpreter, and many people do in fact
 | |
| write shell <quote>scripts</quote> to help with various
 | |
| <quote>housekeeping</> tasks on their machine. Indeed, part of the
 | |
| original Unix philosophy was to provide lots of small utility
 | |
| programs that could be linked together in shell scripts to perform
 | |
| useful tasks.</para>
 | |
|   
 | |
| </sect1>
 | |
| 
 | |
| <sect1>
 | |
| <title>Interpreters available with FreeBSD</title>
 | |
| 
 | |
| <para>Here is a list of interpreters that are available as <ulink
 | |
| URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/">FreeBSD
 | |
| packages</ulink>, with a brief discussion of some of the more popular
 | |
| interpreted languages. </para>
 | |
| 
 | |
| <para>To get one of these packages, all you need to do is to click on
 | |
| the hotlink for the package, then run
 | |
| <screen>$ <userinput>pkg_add <replaceable>package name</></userinput></screen>
 | |
| </para>
 | |
|   
 | |
| <para>as root. Obviously, you will need to have a fully functional FreeBSD
 | |
| 2.1.0 or later system for the package to work!</para>
 | |
|   
 | |
| <para>
 | |
| <variablelist>
 | |
| <varlistentry><term><acronym>BASIC</></term>
 | |
| 
 | |
| <listitem><para>Short for Beginner's All-purpose Symbolic Instruction
 | |
| Code. Developed in the 1950s for teaching University students to
 | |
| program and provided with every self-respecting personal computer in
 | |
| the 1980s, <acronym>BASIC</> has been the first programming language
 | |
| for many programmers. It's also the foundation for <trademark>Visual
 | |
| Basic</>.</para>
 | |
| 
 | |
| <para>The <ulink
 | |
| URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/bwbasic-2.10.tgz">Bywater
 | |
| Basic Interpreter</ulink> and the <ulink
 | |
| URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/pbasic-2.0.tgz">Phil
 | |
| Cockroft's Basic Interpreter</ulink> (formerly Rabbit Basic) are
 | |
| available as FreeBSD <ulink
 | |
| URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/">FreeBSD
 | |
| packages</ulink></para>
 | |
| </listitem>
 | |
| </varlistentry>
 | |
| 
 | |
| <varlistentry><term>Lisp</term>
 | |
| <listitem><para>A language that was developed in the late 1950s as an alternative to
 | |
| the <quote>number-crunching</quote> languages that were popular at the time.
 | |
| Instead of being based on numbers, Lisp is based on lists; in fact
 | |
| the name is short for <quote>List Processing</quote>. Very popular in AI
 | |
| (Artificial Intelligence) circles.</para>
 | |
|   
 | |
| <para>Lisp is an extremely powerful and sophisticated language, but
 | |
| can be rather large and unwieldy. </para>
 | |
| 
 | |
| <para>FreeBSD has <ulink
 | |
| URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/gcl-2.0.tgz">GNU
 | |
| Common Lisp</ulink> available as a package.</para>
 | |
|   
 | |
| </listitem>
 | |
| </varlistentry>
 | |
| 
 | |
| <varlistentry><term>Perl</term>
 | |
| <listitem><para>Very popular with system administrators for writing
 | |
| scripts; also often used on World Wide Web servers for writing <acronym>CGI</>
 | |
| scripts.</para>
 | |
| 
 | |
| <para>Version 4, which is probably still the most widely-used
 | |
| version, comes with FreeBSD; the newer <ulink
 | |
| URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/perl-5.001.tgz">Perl
 | |
| Version 5</ulink> is available as a package.</para>
 | |
| 
 | |
| </listitem>
 | |
| </varlistentry>
 | |
| 
 | |
| <varlistentry><term>Scheme</term>
 | |
| <listitem><para>A dialect of Lisp that is rather more compact and
 | |
| cleaner than Common Lisp. Popular in Universities as it is simple
 | |
| enough to teach to undergraduates as a first language, while it has a
 | |
| high enough level of abstraction to be used in research work.</para>
 | |
| 
 | |
| <para>FreeBSD has packages of the 
 | |
| <ulink URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/elk-3.0.tgz">Elk Scheme Interpreter</ulink>, the 
 | |
| <ulink URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/mit-scheme-7.3.tgz">MIT Scheme Interpreter</ulink> and the 
 | |
| <ulink URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/scm-4e1.tgz">SCM Scheme Interpreter</ulink>.</para>
 | |
|   
 | |
| </listitem>
 | |
| </varlistentry>
 | |
| 
 | |
| <varlistentry><term>Icon</term>
 | |
| <listitem><para><ulink URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/icon-9.0.tgz">The Icon Programming Language</ulink>.</para>
 | |
| </listitem>
 | |
| </varlistentry>
 | |
| 
 | |
| <varlistentry><term>Logo</term>
 | |
| <listitem><para><ulink URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/ucblogo-3.3.tgz">Brian Harvey's LOGO Interpreter</ulink>.</para>
 | |
| </listitem>
 | |
| </varlistentry>
 | |
| 
 | |
| <varlistentry><term>Python</term>
 | |
| <listitem><para><ulink URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/python-1.2">The Python Object-Oriented Programming Language</ulink></para>
 | |
| </listitem>
 | |
| </varlistentry>
 | |
| 
 | |
| </variablelist>
 | |
| </para>
 | |
|   
 | |
| </sect1>
 | |
| 
 | |
| <sect1>
 | |
| <title>Compilers</title>
 | |
| 
 | |
| <para>Compilers are rather different. First of all, you write your
 | |
| code in a file (or files) using an editor. You then run the compiler
 | |
| and see if it accepts your program. If it did not compile, grit your
 | |
| teeth and go back to the editor; if it did compile and gave you a
 | |
| program, you can run it either at a shell command prompt or in a
 | |
| debugger to see if it works properly.<footnote><para>If you run it in
 | |
| the shell, you may get a core dump.</para></footnote></para>
 | |
| 
 | |
| <para>Obviously, this is not quite as direct as using an interpreter.
 | |
| However it allows you to do a lot of things which are very difficult
 | |
| or even impossible with an interpreter, such as writing code which
 | |
| interacts closely with the operating system—or even writing
 | |
| your own operating system! It's also useful if you need to write very
 | |
| efficient code, as the compiler can take its time and optimise the
 | |
| code, which would not be acceptable in an interpreter. And
 | |
| distributing a program written for a compiler is usually more
 | |
| straightforward than one written for an interpreter—you can just
 | |
| give them a copy of the executable, assuming they have the same
 | |
| operating system as you.</para>
 | |
| 
 | |
| <para>Compiled languages include Pascal, C and C++. C and C++ are rather
 | |
| unforgiving languages, and best suited to more experienced
 | |
| programmers; Pascal, on the other hand, was designed as an educational
 | |
| language, and is quite a good language to start with. Unfortunately,
 | |
| FreeBSD doesn't have any Pascal support, except for a Pascal-to-C
 | |
| converter in the ports.</para>
 | |
|   
 | |
| <para>As the edit-compile-run-debug cycle is rather tedious when
 | |
| using separate programs, many commercial compiler makers have
 | |
| produced Integrated Development Environments (<acronym>IDE</acronym>s
 | |
| for short). FreeBSD does not have an <acronym>IDE</> as such; however
 | |
| it is possible to use Emacs for this purpose. This is discussed in
 | |
| <xref linkend="emacs">.</para>
 | |
|   
 | |
| </sect1>
 | |
| </chapter>
 | |
| 
 | |
| <chapter>
 | |
| <title>Compiling with <command>cc</command></title>
 | |
| 
 | |
| <para>This section deals only with the GNU compiler for C and C++,
 | |
| since that comes with the base FreeBSD system. It can be invoked by
 | |
| either <command>cc</> or <command>gcc</>. The details of producing a
 | |
| program with an interpreter vary considerably between interpreters,
 | |
| and are usually well covered in the documentation and on-line help
 | |
| for the interpreter.</para>
 | |
| 
 | |
| <para>Once you've written your masterpiece, the next step is to convert it
 | |
| into something that will (hopefully!) run on FreeBSD. This usually
 | |
| involves several steps, each of which is done by a separate
 | |
| program.</para>
 | |
| 
 | |
| <procedure>
 | |
| <step><para>Pre-process your source code to remove comments and do other
 | |
| tricks like expanding macros in C.
 | |
| </para></step>
 | |
| 
 | |
| <step><para>Check the syntax of your code to see if you have obeyed the
 | |
| rules of the language. If you have not, it will complain!
 | |
| </para></step>
 | |
| 
 | |
| <step><para>Convert the source code into assembly
 | |
| language—this is very close to machine code, but still
 | |
| understandable by humans. Allegedly.<footnote><para>To be strictly
 | |
| accurate, <command>cc</> converts the source code into its own,
 | |
| machine-independent <firstterm>p-code</> instead of assembly language
 | |
| at this stage.</para></footnote></para></step>
 | |
| 
 | |
| <step><para>Convert the assembly language into machine
 | |
| code—yep, we are talking bits and bytes, ones and zeros
 | |
| here.</para></step>
 | |
| 
 | |
| <step><para>Check that you have used things like functions and global
 | |
| variables in a consistent way. For example, if you have called a
 | |
| non-existent function, it will complain.</para></step>
 | |
| 
 | |
| <step><para>If you are trying to produce an executable from several
 | |
| source code files, work out how to fit them all together.</para></step>
 | |
| 
 | |
| <step><para>Work out how to produce something that the system's run-time
 | |
| loader will be able to load into memory and run.</para></step>
 | |
| 
 | |
| <step><para>Finally, write the executable on the file
 | |
| system.</para></step>
 | |
| 
 | |
| </procedure>
 | |
|   
 | |
| <para>The word <firstterm>compiling</> is often used to refer to just
 | |
| steps 1 to 4—the others are referred to as
 | |
| <firstterm>linking</>. Sometimes step 1 is referred to as
 | |
| <firstterm>pre-processing</> and steps 3-4 as
 | |
| <firstterm>assembling</>.</para>
 | |
| 
 | |
| <para>Fortunately, almost all this detail is hidden from you, as
 | |
| <command>cc</> is a front end that manages calling all these programs
 | |
| with the right arguments for you; simply typing
 | |
| <screen>$ <userinput>cc foobar.c</></screen></para>
 | |
|   
 | |
| <para>will cause <filename>foobar.c</> to be compiled by all the
 | |
| steps above. If you have more than one file to compile, just do
 | |
| something like
 | |
| <screen>$ <userinput>cc foo.c bar.c</></screen>
 | |
| </para>
 | |
|   
 | |
| <para>Note that the syntax checking is just that—checking the
 | |
| syntax. It will not check for any logical mistakes you may have made,
 | |
| like putting the program into an infinite loop, or using a bubble
 | |
| sort when you meant to use a binary sort.<footnote><para>In case you
 | |
| didn't know, a binary sort is an efficient way of sorting things into
 | |
| order and a bubble sort isn't.</para></footnote></para>
 | |
| 
 | |
| <para>There are lots and lots of options for <command>cc</>, which
 | |
| are all in the man page.  Here are a few of the most important ones,
 | |
| with examples of how to use them.</para>
 | |
| 
 | |
| <variablelist>
 | |
| <varlistentry><term><option>-o <replaceable>filename</replaceable></></term>
 | |
| 
 | |
| <listitem><para>The output name of the file. If you do not use this
 | |
| option, <command>cc</> will  produce an executable called
 | |
| <filename>a.out</>.<footnote><para>The reasons for this are buried in
 | |
| the mists of history.</para></footnote></para>
 | |
| 
 | |
| <informalexample>
 | |
| <screen>$ <userinput>cc foobar.c</>               <lineannotation>executable is <filename>a.out</></>
 | |
| $ <userinput>cc -o foobar foobar.c</>     <lineannotation>executable is <filename>foobar</></></screen>
 | |
| </informalexample>
 | |
| </listitem>
 | |
| </varlistentry>
 | |
| 
 | |
| <varlistentry><term><option>-c</option></term>
 | |
| <listitem><para>Just compile the file, do not link it. Useful for toy
 | |
| programs where you just want to check the syntax, or if you are using
 | |
| a <filename>Makefile</filename>.</para>
 | |
| 
 | |
| <informalexample>
 | |
| <screen>$ <userinput>cc -c foobar.c</userinput></screen>
 | |
| </informalexample>
 | |
|   
 | |
| <para>This will produce an <firstterm>object file</> (not an
 | |
| executable) called <filename>foobar.o</filename>. This can be linked
 | |
| together with other object files into an executable.</para>
 | |
| 
 | |
| </listitem>
 | |
| </varlistentry>
 | |
| 
 | |
| <varlistentry><term><option>-g</option></term>
 | |
| 
 | |
| <listitem><para>Create a debug version of the executable. This makes
 | |
| the compiler put information into the executable about which line of
 | |
| which source file corresponds to which function call. A debugger can
 | |
| use this information to show the source code as you step through the
 | |
| program, which is <emphasis>very</emphasis> useful; the disadvantage
 | |
| is that all this extra information makes the program much bigger.
 | |
| Normally, you compile with <option>-g</option> while you are
 | |
| developing a program and then compile a <quote>release
 | |
| version</quote> without <option>-g</option> when you're satisfied it
 | |
| works properly.</para>
 | |
| 
 | |
| <informalexample>
 | |
| <screen>$ <userinput>cc -g foobar.c</userinput></screen>
 | |
| </informalexample>
 | |
|   
 | |
| <para>This will produce a debug version of the
 | |
| program.<footnote><para>Note, we didn't use the <option>-o</option>
 | |
| flag to specify the executable name, so we will get an executable
 | |
| called <filename>a.out</filename>. Producing a debug version called
 | |
| <filename>foobar</filename> is left as an exercise for the
 | |
| reader!</para></footnote></para>
 | |
| 
 | |
| </listitem>
 | |
| </varlistentry>
 | |
| 
 | |
| <varlistentry><term><option>-O</option></term>
 | |
| 
 | |
| <listitem><para>Create an optimised version of the executable. The
 | |
| compiler performs various clever tricks to try and produce an
 | |
| executable that runs faster than normal. You can add a number after
 | |
| the <option>-O</option> to specify a higher level of optimisation,
 | |
| but this often exposes bugs in the compiler's optimiser. For
 | |
| instance, the version of <command>cc</command> that comes with the
 | |
| 2.1.0 release of FreeBSD is known to produce bad code with the
 | |
| <option>-O2</option> option in some circumstances.</para>
 | |
| 
 | |
| <para>Optimisation is usually only turned on when compiling a release
 | |
| version.</para>
 | |
| 
 | |
| <informalexample>
 | |
| <screen>$ <userinput>cc -O -o foobar foobar.c</userinput></screen>
 | |
| </informalexample>
 | |
|   
 | |
| <para>This will produce an optimised version of
 | |
| <filename>foobar</filename>.</para>
 | |
| 
 | |
| </listitem>
 | |
| </varlistentry>
 | |
| </variablelist>
 | |
| 
 | |
| <para>The following three flags will force <command>cc</command> to
 | |
| check that your code complies to the relevant international standard,
 | |
| often referred to as the <acronym>ANSI</acronym> standard, though
 | |
| strictly speaking it is an <acronym>ISO</acronym> standard.</para>
 | |
| 
 | |
| <variablelist>
 | |
| 
 | |
| <varlistentry><term><option>-Wall</option></term>
 | |
| 
 | |
| <listitem><para>Enable all the warnings which the authors of
 | |
| <command>cc</command> believe are worthwhile. Despite the name, it
 | |
| will not enable all the warnings <command>cc</command> is capable
 | |
| of.</para></listitem>
 | |
| 
 | |
| </varlistentry>
 | |
| 
 | |
| <varlistentry><term><option>-ansi</option></term>
 | |
| 
 | |
| <listitem>
 | |
| <para>Turn off most, but not all, of the non-<acronym>ANSI</> C
 | |
| features provided by <command>cc</command>. Despite the name, it does
 | |
| not guarantee strictly that your code will comply to the
 | |
| standard.</para>
 | |
| </listitem>
 | |
| 
 | |
| </varlistentry>
 | |
| 
 | |
| <varlistentry><term><option>-pedantic</option></term>
 | |
| 
 | |
| <listitem>
 | |
| <para>Turn off <emphasis>all</emphasis>
 | |
| <command>cc</command>'s non-<acronym>ANSI</> C features.</para>
 | |
| </listitem>
 | |
| 
 | |
| </varlistentry>
 | |
| </variablelist>
 | |
| 
 | |
| <para>Without these flags, <command>cc</command> will allow you to
 | |
| use some of its non-standard extensions to the standard. Some of
 | |
| these are very useful, but will not work with other compilers—in
 | |
| fact, one of the main aims of the standard is to allow people to
 | |
| write code that will work with any compiler on any system. This is
 | |
| known as <firstterm>portable code</firstterm>.</para>
 | |
| 
 | |
| <para>Generally, you should try to make your code as portable as
 | |
| possible, as otherwise you may have to completely re-write the
 | |
| program later to get it to work somewhere else—and who knows
 | |
| what you may be using in a few years time?</para>
 | |
|   
 | |
| <informalexample>
 | |
| <screen>$ <userinput>cc -Wall -ansi -pedantic -o foobar foobar.c</userinput></screen>
 | |
| </informalexample>
 | |
| 
 | |
| <para>This will produce an executable <filename>foobar</filename>
 | |
| after checking <filename>foobar.c</filename> for standard
 | |
| compliance.</para>
 | |
|   
 | |
| <variablelist>
 | |
| 
 | |
| <varlistentry><term><option>-l<replaceable>library</replaceable></option></term>
 | |
| 
 | |
| <listitem><para>Specify a function library to be used during when
 | |
| linking.</para>
 | |
| 
 | |
| <para>The most common example of this is when compiling a program that
 | |
| uses some of the mathematical functions in C. Unlike most other
 | |
| platforms, these are in a separate library from the standard C one
 | |
| and you have to tell the compiler to add it.</para>
 | |
|   
 | |
| <para>The rule is that if the library is called
 | |
| <filename>lib<replaceable>something</replaceable>.a</filename>, you
 | |
| give <command>cc</command> the argument
 | |
| <option>-l<replaceable>something</replaceable></option>. For example,
 | |
| the math library is <filename>libm.a</filename>, so you give
 | |
| <command>cc</command> the argument <option>-lm</option>. A common
 | |
| <quote>gotcha</quote> with the math library is that it has to be the
 | |
| last library on the command line.</para>
 | |
| 
 | |
| <informalexample>
 | |
| <screen>$ <userinput>cc -o foobar foobar.c -lm</userinput></screen>
 | |
| </informalexample>
 | |
| 
 | |
| <para>This will link the math library functions into
 | |
| <filename>foobar</filename>.</para>
 | |
| 
 | |
| <para>If you are compiling C++ code, you need to add
 | |
| <option>-lg++</option>, or <option>-lstdc++</option> if you are using
 | |
| FreeBSD 2.2 or later, to the command line argument to link the C++
 | |
| library functions. Alternatively, you can run <command>c++</command>
 | |
| instead of <command>cc</command>, which does this for you.
 | |
| <command>c++</command> can also be invoked as <command>g++</command>
 | |
| on FreeBSD.</para>
 | |
| 
 | |
| <informalexample>
 | |
| <screen>$ <userinput>cc -o foobar foobar.cc -lg++</userinput>     <lineannotation>For FreeBSD 2.1.6 and earlier</>
 | |
| $ <userinput>cc -o foobar foobar.cc -lstdc++</userinput>  <lineannotation>For FreeBSD 2.2 and later</>
 | |
| $ <userinput>c++ -o foobar foobar.cc</userinput></screen>
 | |
| </informalexample>
 | |
| 
 | |
| <para>Each of these will both produce an executable
 | |
| <filename>foobar</filename> from the C++ source file
 | |
| <filename>foobar.cc</filename>. Note that, on Unix systems, C++
 | |
| source files traditionally end in <filename>.C</filename>,
 | |
| <filename>.cxx</filename> or <filename>.cc</filename>, rather than
 | |
| the <trademark>MS-DOS</trademark> style <filename>.cpp</filename>
 | |
| (which was already used for something else). <command>gcc</command>
 | |
| used to rely on this to work out what kind of compiler to use on the
 | |
| source file; however, this restriction no longer applies, so you may
 | |
| now call your C++ files <filename>.cpp</filename> with
 | |
| impunity!</para>
 | |
| 
 | |
| </listitem>
 | |
| </varlistentry>
 | |
| </variablelist>
 | |
|   
 | |
| <sect1>
 | |
| <title>Common <command>cc</command> Queries and Problems</title>
 | |
| 
 | |
| <para>Q. I am trying to write a program which uses the
 | |
| <function>sin()</function> function and I get an error like this.
 | |
| What does it mean?
 | |
| <informalexample>
 | |
| <screen>/var/tmp/cc0143941.o: Undefined symbol `_sin' referenced from text segment</screen>
 | |
| </informalexample>
 | |
| </para>
 | |
|   
 | |
| <para>A. When using mathematical functions like
 | |
| <function>sin()</function>, you have to tell <command>cc</command> to
 | |
| link in the math library, like so:
 | |
| <informalexample>
 | |
| <screen>$ <userinput>cc -o foobar foobar.c -lm</userinput></screen>
 | |
| </informalexample></para>
 | |
| 
 | |
| <para>Q. All right, I wrote this simple program to practice using
 | |
| <option>-lm</option>. All it does is raise 2.1 to the power of 6.
 | |
| <informalexample>
 | |
| <programlisting>#include <stdio.h>
 | |
| 
 | |
| int main() {
 | |
| 	float f;
 | |
| 
 | |
| 	f = pow(2.1, 6);
 | |
| 	printf("2.1 ^ 6 = %f\n", f);
 | |
| 	return 0;
 | |
| }</programlisting>
 | |
| </informalexample>
 | |
| and I compiled it as:
 | |
| <informalexample>
 | |
| <screen>$ <userinput>cc temp.c -lm</userinput></screen>
 | |
| </informalexample>
 | |
| like you said I should, but I get this when I run it:
 | |
| <informalexample>
 | |
| <screen>$ <userinput>./a.out</userinput>
 | |
| 2.1 ^ 6 = 1023.000000</screen>
 | |
| </informalexample>
 | |
| </para>
 | |
|   
 | |
| <para>This is <emphasis>not</emphasis> the right answer! What is
 | |
| going on?</para>
 | |
| 
 | |
| <para>A. When the compiler sees you call a function, it checks if it
 | |
| has already seen a prototype for it. If it has not, it assumes the
 | |
| function returns an <type>int</type>, which is
 | |
| definitely not what you want here.</para>
 | |
| 
 | |
| <para>Q. So how do I fix this?</para>
 | |
|   
 | |
| <para>A. The prototypes for the mathematical functions are in
 | |
| <filename>math.h</filename>. If you include this file, the compiler
 | |
| will be able to find the prototype and it will stop doing strange
 | |
| things to your calculation!
 | |
| <informalexample>
 | |
| <programlisting>#include <math.h>
 | |
| #include <stdio.h>
 | |
| 
 | |
| int main() {
 | |
| ...</programlisting>
 | |
| </informalexample>
 | |
| </para>
 | |
|   
 | |
| <para>After recompiling it as you did before, run it:
 | |
| <informalexample>
 | |
| <screen>$ <userinput>./a.out</userinput>
 | |
| 2.1 ^ 6 = 85.766121</screen>
 | |
| </informalexample>
 | |
| </para>
 | |
|   
 | |
| <para>If you are using any of the mathematical functions,
 | |
| <emphasis>always</emphasis> include <filename>math.h</filename> and
 | |
| remember to link in the math library.</para>
 | |
| 
 | |
| <para>Q. I compiled a file called <filename>foobar.c</filename> and I
 | |
| cannot find an executable called <filename>foobar</filename>. Where's
 | |
| it gone?</para>
 | |
| 
 | |
| <para>A. Remember, <command>cc</command> will call the executable
 | |
| <filename>a.out</filename> unless you tell it differently. Use the
 | |
| <option>-o <replaceable>filename</replaceable></option> option:
 | |
| <informalexample>
 | |
| <screen>$ <userinput>cc -o foobar foobar.c</userinput></screen>
 | |
| </informalexample>
 | |
| </para>
 | |
| 
 | |
| <para>Q. OK, I have an executable called <filename>foobar</filename>,
 | |
| I can see it when I run <command>ls</command>, but when I type in
 | |
| <command>foobar</command> at the command prompt it tells me there is
 | |
| no such file. Why can it not find it?</para>
 | |
| 
 | |
| <para>A. Unlike <trademark>MS-DOS</trademark>, Unix does not look in the
 | |
| current directory when it is trying to find out which executable you
 | |
| want it to run, unless you tell it to. Either type
 | |
| <command>./foobar</command>, which means <quote>run the file called
 | |
| <filename>foobar</filename> in the current directory</quote>, or
 | |
| change your <systemitem class=environvar>PATH</systemitem>
 | |
| environment variable so that it looks something like
 | |
| <informalexample>
 | |
| <screen>bin:/usr/bin:/usr/local/bin:.</screen>
 | |
| </informalexample>
 | |
| The dot at the end means <quote>look in the current directory if it is not in
 | |
| any of the others</quote>.</para>
 | |
|   
 | |
| <para>Q. I called my executable <filename>test</filename>, but
 | |
| nothing happens when I run it. What is going on?</para>
 | |
| 
 | |
| <para>A. Most Unix systems have a program called
 | |
| <command>test</command> in <filename>/usr/bin</filename> and the
 | |
| shell is picking that one up before it gets to checking the current
 | |
| directory. Either type:
 | |
| <informalexample>
 | |
| <screen>$ <userinput>./test</userinput></screen>
 | |
| </informalexample>
 | |
| or choose a better name for your program!</para>
 | |
|   
 | |
| <para>Q. I compiled my program and it seemed to run all right at
 | |
| first, then there was an error and it said something about <errorname>core
 | |
| dumped</errorname>. What does that mean?</para>
 | |
| 
 | |
| <para>A. The name <firstterm>core dump</firstterm> dates back to the
 | |
| very early days of Unix, when the machines used core memory for
 | |
| storing data. Basically, if the program failed under certain
 | |
| conditions, the system would write the contents of core memory to
 | |
| disk in a file called <filename>core</filename>, which the programmer
 | |
| could then pore over to find out what went wrong.</para>
 | |
| 
 | |
| <para>Q. Fascinating stuff, but what I am supposed to do now?</para>
 | |
|   
 | |
| <para>A. Use <command>gdb</command> to analyse the core (see <xref
 | |
| linkend="debugging">).</para>
 | |
|   
 | |
| <para>Q. When my program dumped core, it said something about a
 | |
| <errorname>segmentation fault</errorname>. What's that?</para>
 | |
| 
 | |
| <para>A. This basically means that your program tried to perform some sort
 | |
| of illegal operation on memory; Unix is designed to protect the
 | |
| operating system and other programs from rogue programs.</para>
 | |
|   
 | |
| <para>Common causes for this are:
 | |
| <itemizedlist>
 | |
| <listitem><para>Trying to write to a <symbol>NULL</symbol> pointer, eg
 | |
| <programlisting>char *foo = NULL;
 | |
| strcpy(foo, "bang!");</programlisting>
 | |
| </para></listitem>
 | |
| 
 | |
| <listitem><para>Using a pointer that hasn't been initialised, eg
 | |
| <programlisting>char *foo;
 | |
| strcpy(foo, "bang!");</programlisting>
 | |
| The pointer will have some random value that, with luck,
 | |
| will point into an area of memory that isn't available to
 | |
| your program and the kernel will kill your program before
 | |
| it can do any damage. If you're unlucky, it'll point
 | |
| somewhere inside your own program and corrupt one of your
 | |
| data structures, causing the program to fail
 | |
| mysteriously.</para></listitem>
 | |
| 
 | |
| <listitem><para>Trying to access past the end of an array, eg
 | |
| <programlisting>int bar[20];
 | |
| bar[27] = 6;</programlisting></para></listitem>
 | |
| 
 | |
| <listitem><para> Trying to store something in read-only memory, eg
 | |
| <programlisting>char *foo = "My string";
 | |
| strcpy(foo, "bang!");</programlisting>
 | |
| Unix compilers often put string literals like
 | |
| <literal>"My string"</literal> into
 | |
| read-only areas of memory.</para></listitem>
 | |
| 
 | |
| <listitem><para>Doing naughty things with
 | |
| <function>malloc()</function> and <function>free()</function>, eg
 | |
| <programlisting>char bar[80];
 | |
| free(bar);</programlisting>
 | |
| or
 | |
| <programlisting>char *foo = malloc(27);
 | |
| free(foo);
 | |
| free(foo);</programlisting>
 | |
| </para></listitem>
 | |
| 
 | |
| </itemizedlist></para>
 | |
| 
 | |
| <para>Making one of these mistakes will not always lead to an
 | |
| error, but they are always bad practice. Some systems and
 | |
| compilers are more tolerant than others, which is why programs
 | |
| that ran well on one system can crash when you try them on an
 | |
| another.</para>
 | |
|   
 | |
| <para>Q. Sometimes when I get a core dump it says <errorname>bus
 | |
| error</errorname>. It says in my Unix book that this means a hardware
 | |
| problem, but the computer still seems to be working. Is this
 | |
| true?</para>
 | |
| 
 | |
| <para>A. No, fortunately not (unless of course you really do have a hardware
 | |
| problem…). This is usually another way of saying that you
 | |
| accessed memory in a way you shouldn't have.</para>
 | |
|   
 | |
| <para>Q. This dumping core business sounds as though it could be quite
 | |
| useful, if I can make it happen when I want to. Can I do this, or
 | |
| do I have to wait until there's an error?</para>
 | |
|   
 | |
| <para>A. Yes, just go to another console or xterm, do
 | |
| <screen>$ <userinput>ps</userinput></screen>
 | |
| to find out the process ID of your program, and do
 | |
| <screen>$ <userinput>kill -ABRT <replaceable>pid</replaceable></userinput></screen>
 | |
| where <parameter><replaceable>pid</replaceable></parameter> is the
 | |
| process ID you looked up.</para>
 | |
|   
 | |
| <para>This is useful if your program has got stuck in an infinite
 | |
| loop, for instance. If your program happens to trap
 | |
| <symbol>SIGABRT</symbol>, there are several other signals which have
 | |
| a similar effect.</para>
 | |
| 
 | |
| </sect1>
 | |
| </chapter>
 | |
| 
 | |
| 
 | |
| <chapter>
 | |
| <title>Make</title>
 | |
| 
 | |
| <sect1>
 | |
| <title>What is <command>make</command>?</title>
 | |
| 
 | |
| <para>When you're working on a simple program with only one or two source
 | |
| files, typing in
 | |
| <screen>$ <userinput>cc file1.c file2.c</userinput></screen>
 | |
| is not too bad, but it quickly becomes very tedious when there are
 | |
| several files—and it can take a while to compile, too.</para>
 | |
|   
 | |
| <para>One way to get around this is to use object files and only recompile
 | |
| the source file if the source code has changed. So we could have
 | |
| something like:
 | |
| <screen>$ <userinput>cc file1.o file2.o</userinput> … <userinput>file37.c</userinput> &hellip</screen>
 | |
| if we'd changed <filename>file37.c</filename>, but not any of the
 | |
| others, since the last time we compiled.  This may speed up the
 | |
| compilation quite a bit, but  doesn't solve the typing
 | |
| problem.</para>
 | |
| 
 | |
| <para>Or we could write a shell script to solve the typing problem, but it
 | |
| would have to re-compile everything, making it very inefficient on a
 | |
| large project.</para>
 | |
|   
 | |
| <para>What happens if we have hundreds of source files lying about? What if
 | |
| we're working in a team with other people who forget to tell us when
 | |
| they've changed one of their source files that we use?</para>
 | |
|   
 | |
| <para>Perhaps we could put the two solutions together and write something
 | |
| like a shell script that would contain some kind of magic rule saying
 | |
| when a source file needs compiling. Now all we need now is a program
 | |
| that can understand these rules, as it's a bit too complicated for the
 | |
| shell.</para>
 | |
|   
 | |
| <para>This program is called <command>make</command>. It reads in a
 | |
| file, called a <firstterm>makefile</firstterm>, that tells it how
 | |
| different files depend on each other, and works out which files need
 | |
| to be re-compiled and which ones don't. For example, a rule could say
 | |
| something like <quote>if <filename>fromboz.o</filename> is older than
 | |
| <filename>fromboz.c</filename>, that means someone must have changed
 | |
| <filename>fromboz.c</filename>, so it needs to be
 | |
| re-compiled.</quote> The makefile also has rules telling make
 | |
| <emphasis>how</emphasis> to re-compile the source file, making it a
 | |
| much more powerful tool.</para>
 | |
| 
 | |
| <para>Makefiles are typically kept in the same directory as the
 | |
| source they apply to, and can be called
 | |
| <filename>makefile</filename>, <filename>Makefile</filename> or
 | |
| <filename>MAKEFILE</filename>. Most programmers use the name
 | |
| <filename>Makefile</filename>, as this puts it near the top of a
 | |
| directory listing, where it can easily be seen.<footnote><para>They
 | |
| don't use the <filename>MAKEFILE</filename> form as block capitals
 | |
| are often used for documentation files like
 | |
| <filename>README</filename>.</para></footnote></para>
 | |
|   
 | |
| </sect1>
 | |
| 
 | |
| <sect1>
 | |
| <title>Example of using <command>make</command></title>
 | |
| 
 | |
| <para>Here's a very simple make file:
 | |
| <programlisting>foo: foo.c
 | |
| 	cc -o foo foo.c</programlisting>
 | |
| It consists of two lines, a dependency line and a creation line.</para>
 | |
|   
 | |
| <para>The dependency line here consists of the name of the program
 | |
| (known as the <firstterm>target</firstterm>), followed by a colon,
 | |
| then whitespace, then the name of the source file. When
 | |
| <command>make</command> reads this line, it looks to see if
 | |
| <filename>foo</filename> exists; if it exists, it compares the time
 | |
| <filename>foo</filename> was last modified to the time
 | |
| <filename>foo.c</filename> was last modified. If
 | |
| <filename>foo</filename> does not exist, or is older than
 | |
| <filename>foo.c</filename>, it then looks at the creation line to
 | |
| find out what to do. In other words, this is the rule for working out
 | |
| when <filename>foo.c</filename> needs to be re-compiled.</para>
 | |
| 
 | |
| <para>The creation line starts with a <token>tab</token> (press the
 | |
| <keycap>tab</keycap> key) and then the command you would type to
 | |
| create <filename>foo</filename> if you were doing it at a command
 | |
| prompt. If <filename>foo</filename> is out of date, or does not
 | |
| exist, <command>make</command> then executes this command to create
 | |
| it. In other words, this is the rule which tells make how to
 | |
| re-compile <filename>foo.c</filename>.</para>
 | |
| 
 | |
| <para>So, when you type <userinput>make</userinput>, it will make
 | |
| sure that <filename>foo</filename> is up to date with respect to your
 | |
| latest changes to <filename>foo.c</filename>. This principle can be
 | |
| extended to <filename>Makefile</filename>s with hundreds of
 | |
| targets—in fact, on FreeBSD, it is possible to compile the
 | |
| entire operating system just by typing <userinput>make
 | |
| world</userinput> in the appropriate directory!</para>
 | |
| 
 | |
| <para>Another useful property of makefiles is that the targets don't have
 | |
| to be programs. For instance, we could have a make file that looks
 | |
| like this:
 | |
| <programlisting>foo: foo.c
 | |
| 	cc -o foo foo.c
 | |
| 
 | |
| install:
 | |
| 	cp foo /home/me</programlisting></para>
 | |
|   
 | |
| <para>We can tell make which target we want to make by typing:
 | |
| <screen>$ <userinput>make <replaceable>target</replaceable></userinput></screen>
 | |
| <command>make</command> will then only look at that target and ignore any
 | |
| others. For example, if we type <userinput>make foo</userinput> with the 
 | |
| makefile above, make will ignore the <action>install</action> target.</para>
 | |
|   
 | |
| <para>If we just type <userinput>make</userinput> on its own, make
 | |
| will always look at the first target and then stop without looking at
 | |
| any others. So if we typed <userinput>make</userinput> here, it will
 | |
| just go to the <action>foo</action> target, re-compile
 | |
| <filename>foo</filename> if necessary, and then stop without going on
 | |
| to the <action>install</action> target.</para>
 | |
| 
 | |
| <para>Notice that the <action>install</action> target doesn't
 | |
| actually depend on anything! This means that the command on the
 | |
| following line is always executed when we try to make that target by
 | |
| typing <userinput>make install</userinput>. In this case, it will
 | |
| copy <filename>foo</filename> into the user's home directory. This is
 | |
| often used by application makefiles, so that the application can be
 | |
| installed in the correct directory when it has been correctly
 | |
| compiled.</para>
 | |
| 
 | |
| <para>This is a slightly confusing subject to try and explain. If you
 | |
| don't quite understand how <command>make</command> works, the best
 | |
| thing to do is to write a simple program like <quote>hello
 | |
| world</quote> and a make file like the one above and experiment. Then
 | |
| progress to using more than one source file, or having the source
 | |
| file include a header file. The <command>touch</command> command is
 | |
| very useful here—it changes the date on a file without you
 | |
| having to edit it.</para>
 | |
|   
 | |
| </sect1>
 | |
| 
 | |
| <sect1>
 | |
| <title>FreeBSD Makefiles</title>
 | |
| 
 | |
| <para>Makefiles can be rather complicated to write. Fortunately,
 | |
| BSD-based systems like FreeBSD come with some very powerful ones as
 | |
| part of the system.  One very good example of this is the FreeBSD
 | |
| ports system. Here's the essential part of a typical ports
 | |
| <filename>Makefile</filename>:
 | |
| <programlisting>MASTER_SITES=   ftp://freefall.cdrom.com/pub/FreeBSD/LOCAL_PORTS/
 | |
| DISTFILES=      scheme-microcode+dist-7.3-freebsd.tgz
 | |
| 
 | |
| .include <bsd.port.mk></programlisting></para>
 | |
|   
 | |
| <para>Now, if we go to the directory for this port and type
 | |
| <userinput>make</userinput>, the following happens:</para>
 | |
| 
 | |
| <procedure>
 | |
| <step><para>A check is made to see if the source code for this port is
 | |
| already on the system.</para></step>
 | |
| 
 | |
| <step><para>If it isn't, an FTP connection to the URL in
 | |
| <symbol>MASTER_SITES</symbol> is set up to download the
 | |
| source.</para></step>
 | |
| 
 | |
| <step><para>The checksum for the source is calculated and compared it with
 | |
| one for a known, good, copy of the source. This is to make sure that
 | |
| the source was not corrupted while in transit.</para></step>
 | |
| 
 | |
| <step><para>Any changes required to make the source work on FreeBSD are
 | |
| applied—this is known as <firstterm>patching</firstterm>.</para></step>
 | |
| 
 | |
| <step><para>Any special configuration needed for the source is done.
 | |
| (Many Unix program distributions try to work out which version of
 | |
| Unix they are being compiled on and which optional Unix features are
 | |
| present—this is where they are given the information in the
 | |
| FreeBSD ports scenario).</para></step>
 | |
| 
 | |
| <step><para>The source code for the program is compiled. In effect,
 | |
| we change to the directory where the source was unpacked and do
 | |
| <command>make</command>—the program's own make file has the
 | |
| necessary information to build the program.</para></step>
 | |
| 
 | |
| <step><para>We now have a compiled version of the program. If we
 | |
| wish, we can test it now; when we feel confident about the program,
 | |
| we can type <userinput>make install</userinput>. This will cause the
 | |
| program and any supporting files it needs to be copied into the
 | |
| correct location; an entry is also made into a <database>package
 | |
| database</database>, so that the port can easily be uninstalled later
 | |
| if we change our mind about it.</para></step>
 | |
| 
 | |
| </procedure>
 | |
|   
 | |
| <para>Now I think you'll agree that's rather impressive for a four
 | |
| line script!</para>
 | |
| 
 | |
| <para>The secret lies in the last line, which tells
 | |
| <command>make</command> to look in the system makefile called
 | |
| <filename>bsd.port.mk</filename>. It's easy to overlook this line,
 | |
| but this is where all the clever stuff comes from—someone has
 | |
| written a makefile that tells <command>make</command> to do all the
 | |
| things above (plus a couple of other things I didn't mention,
 | |
| including handling any errors that may occur) and anyone can get
 | |
| access to that just by putting a single line in their own make
 | |
| file!</para>
 | |
| 
 | |
| <para>If you want to have a look at these system makefiles, they're
 | |
| in <filename>/usr/share/mk</filename>, but it's probably best to wait
 | |
| until you've had a bit of practice with makefiles, as they are very
 | |
| complicated (and if you do look at them, make sure you have a flask
 | |
| of strong coffee handy!)</para>
 | |
| 
 | |
| </sect1>
 | |
| 
 | |
| <sect1>
 | |
| <title>More advanced uses of <command>make</command></title>
 | |
| 
 | |
| <para><command>Make</command> is a very powerful tool, and can do much
 | |
| more than the simple example above shows. Unfortunately, there are
 | |
| several different versions of <command>make</command>, and they all
 | |
| differ considerably. The best way to learn what they can do is
 | |
| probably to read the documentation—hopefully this introduction will
 | |
| have given you a base from which you can do this.</para>
 | |
| 
 | |
| <para>The version of make that comes with FreeBSD is the <application>Berkeley
 | |
| make</application>; there is a tutorial for it in
 | |
| <filename>/usr/share/doc/psd/12.make</filename>. To view it, do
 | |
| <screen>$ <userinput>zmore paper.ascii.gz</userinput></screen>
 | |
| in that directory.</para>
 | |
|   
 | |
| <para>Many applications in the ports use <application>GNU
 | |
| make</application>, which has a very good set of <quote>info</quote>
 | |
| pages. If you have installed any of these ports, <application>GNU
 | |
| make</application> will automatically have been installed as
 | |
| <command>gmake</command>. It's also available as a port and package
 | |
| in its own right.</para>
 | |
| 
 | |
| <para>To view the info pages for <application>GNU make</application>,
 | |
| you will have to edit the <filename>dir</filename> file in the
 | |
| <filename>/usr/local/info</filename> directory to add an entry for
 | |
| it. This involves adding a line like
 | |
| <programlisting> * Make: (make).                 The GNU Make utility.</programlisting>
 | |
| to the file. Once you have done this, you can type
 | |
| <userinput>info</userinput> and then select
 | |
| <guimenuitem>make</guimenuitem> from the menu (or in
 | |
| <application>Emacs</application>, do <userinput>C-h
 | |
| i</userinput>).</para>
 | |
| 
 | |
| </sect1>
 | |
| </chapter>
 | |
| 
 | |
| <chapter id="debugging">
 | |
| <title>Debugging</title>
 | |
| 
 | |
| <sect1>
 | |
| <title>The Debugger</title>
 | |
| 
 | |
| <para>The debugger that comes with FreeBSD is called
 | |
| <command>gdb</command> (<application>GNU
 | |
| debugger</application>). You start it up by typing
 | |
| <screen>$ <userinput>gdb <replaceable>progname</replaceable></userinput></screen>
 | |
| although most people prefer to run it inside
 | |
| <application>Emacs</application>. You can do this by:
 | |
| <screen><userinput>M-x gdb RET <replaceable>progname</replaceable> RET</userinput></screen></para>
 | |
|   
 | |
| <para>Using a debugger allows you to run the program under more
 | |
| controlled circumstances. Typically, you can step through the program
 | |
| a line at a time, inspect the value of variables, change them, tell
 | |
| the debugger to run up to a certain point and then stop, and so on.
 | |
| You can even attach to a program that's already running, or load a
 | |
| core file to investigate why the program crashed. It's even possible
 | |
| to debug the kernel, though that's a little trickier than the user
 | |
| applications we'll be discussing in this section.</para>
 | |
| 
 | |
| <para><command>gdb</command> has quite good on-line help, as well as
 | |
| a set of info pages, so this section will concentrate on a few of the
 | |
| basic commands.</para>
 | |
| 
 | |
| <para>Finally, if you find its text-based command-prompt style
 | |
| off-putting, there's a graphical front-end for it <ulink
 | |
| URL="http://www.freebsd.org/ports/devel.html">xxgdb</ulink>
 | |
| in the ports collection.</para>
 | |
| 
 | |
| <para>This section is intended to be an introduction to using
 | |
| <command>gdb</command> and does not cover specialised topics such as
 | |
| debugging the kernel.</para>
 | |
|   
 | |
| </sect1>
 | |
| 
 | |
| <sect1>
 | |
| <title>Running a program in the debugger</title>
 | |
| 
 | |
| <para>You'll need to have compiled the program with the
 | |
| <option>-g</option> option to get the most out of using
 | |
| <command>gdb</command>. It will work without, but you'll only see the
 | |
| name of the function you're in, instead of the source code. If you
 | |
| see a line like:
 | |
| <screen>… (no debugging symbols found) …</screen>when
 | |
| <command>gdb</command> starts up, you'll know that the program wasn't
 | |
| compiled with the <option>-g</option> option.</para>
 | |
|   
 | |
| <para>At the <command>gdb</command> prompt, type <userinput>break
 | |
| main</userinput>. This will tell the debugger to skip over the
 | |
| preliminary set-up code in the program and start at the beginning of
 | |
| your code. Now type <userinput>run</userinput> to start the
 | |
| program—it will start at the beginning of the set-up code and
 | |
| then get stopped by the debugger when it calls
 | |
| <function>main()</function>. (If you've ever wondered where
 | |
| <function>main()</function> gets called from, now you know!).</para>
 | |
| 
 | |
| <para>You can now step through the program, a line at a time, by
 | |
| pressing <command>n</command>.  If you get to a function call, you can
 | |
| step into it by pressing <command>s</command>. Once you're in a
 | |
| function call, you can return from stepping into a function call by
 | |
| pressing <command>f</command>. You can also use <command>up</command> and
 | |
| <command>down</command> to take a quick look at the caller.</para>
 | |
| 
 | |
| <para>Here's a simple example of how to spot a mistake in a program
 | |
| with <command>gdb</command>. This is our program (with a deliberate
 | |
| mistake):
 | |
| <programlisting>#include <stdio.h>
 | |
| 
 | |
| int bazz(int anint);
 | |
| 
 | |
| main() {
 | |
| 	int i;
 | |
| 
 | |
| 	printf("This is my program\n");
 | |
| 	bazz(i);
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| int bazz(int anint) {
 | |
| 	printf("You gave me %d\n", anint);
 | |
| 	return anint;
 | |
| }</programlisting>
 | |
| </para>
 | |
|   
 | |
| <para>This program sets <symbol>i</symbol> to be <literal>5</literal>
 | |
| and passes it to a function <function>bazz()</function> which prints
 | |
| out the number we gave it.</para>
 | |
| 
 | |
| <para>When we compile and run the program we get
 | |
| <screen>$ <userinput>cc -g -o temp temp.c</userinput>
 | |
| $ <userinput>./temp</userinput>
 | |
| This is my program
 | |
| anint = 4231</screen></para>
 | |
|   
 | |
| <para>That wasn't what we expected! Time to see what's going
 | |
| on!<screen>$ <userinput>gdb temp</userinput>
 | |
| GDB is free software and you are welcome to distribute copies of it
 | |
|  under certain conditions; type "show copying" to see the conditions.
 | |
| There is absolutely no warranty for GDB; type "show warranty" for details.
 | |
| GDB 4.13 (i386-unknown-freebsd), Copyright 1994 Free Software Foundation, Inc.
 | |
| (gdb) <userinput>break main</>				<lineannotation>Skip the set-up code</>
 | |
| Breakpoint 1 at 0x160f: file temp.c, line 9.	<lineannotation><command>gdb</command> puts breakpoint at <function>main()</></>
 | |
| (gdb) <userinput>run</>					<lineannotation>Run as far as <function>main()</></>
 | |
| Starting program: /home/james/tmp/temp		<lineannotation>Program starts running</>
 | |
| 
 | |
| Breakpoint 1, main () at temp.c:9		<lineannotation><command>gdb</command> stops at <function>main()</></>
 | |
| (gdb) <userinput>n</>						<lineannotation>Go to next line</>
 | |
| This is my program				<lineannotation>Program prints out</>
 | |
| (gdb) <userinput>s</>						<lineannotation>step into <function>bazz()</></>
 | |
| bazz (anint=4231) at temp.c:17			<lineannotation><command>gdb</command> displays stack frame</>
 | |
| (gdb)</screen></para>
 | |
| 
 | |
|   
 | |
| <para>Hang on a minute! How did <symbol>anint</symbol> get to be
 | |
| <literal>4231</literal>? Didn't we set it to be <literal>5</literal>
 | |
| in <function>main()</function>? Let's move up to
 | |
| <function>main()</function> and have a look.</para>
 | |
| 
 | |
| <para><screen>(gdb) <userinput>up</>					<lineannotation>Move up call stack</>
 | |
| #1  0x1625 in main () at temp.c:11		<lineannotation><command>gdb</command> displays stack frame</>
 | |
| (gdb) <userinput>p i</>					<lineannotation>Show us the value of <symbol>i</></>
 | |
| $1 = 4231					<lineannotation><command>gdb</command> displays <literal>4231</></></screen>
 | |
| Oh dear! Looking at the code, we forgot to initialise
 | |
| <symbol>i</symbol>. We meant to put
 | |
| <programlisting><lineannotation>…</>
 | |
| main() {
 | |
| 	int i;
 | |
| 
 | |
| 	i = 5;
 | |
| 	printf("This is my program\n");
 | |
| <lineannotation>&hellip</></programlisting>
 | |
| but we left the <literal>i=5;</literal> line out.  As we didn't
 | |
| initialise <symbol>i</symbol>, it had whatever number happened to be
 | |
| in that area of memory when the program ran, which in this case
 | |
| happened to be <literal>4231</literal>.</para>
 | |
| 
 | |
| <note><para><command>gdb</command> displays the stack frame
 | |
| every time we go into or out of a function, even if we're using
 | |
| <command>up</command> and <command>down</command> to move around the
 | |
| call stack.  This shows the name of the function and the values of
 | |
| its arguments, which helps us keep track of where we are and what's
 | |
| going on. (The stack is a storage area where the program stores
 | |
| information about the arguments passed to functions and where to go
 | |
| when it returns from a function call).</para></note>
 | |
| 
 | |
| </sect1>
 | |
| 
 | |
| <sect1>
 | |
| <title>Examining a core file</title>
 | |
| 
 | |
| <para>A core file is basically a file which contains the complete
 | |
| state of the process when it crashed. In <quote>the good old
 | |
| days</quote>, programmers had to print out hex listings of core files
 | |
| and sweat over machine code manuals, but now life is a bit easier.
 | |
| Incidentally, under FreeBSD and other 4.4BSD systems, a core file is
 | |
| called <filename><replaceable>progname</>.core</> instead of just
 | |
| <filename>core</filename>, to make it clearer which program a core
 | |
| file belongs to.</para>
 | |
| 
 | |
| <para>To examine a core file, start up <command>gdb</command> in the
 | |
| usual way. Instead of typing <command>break</command> or
 | |
| <command>run</command>, type
 | |
| <screen>(gdb) <userinput>core <replaceable>progname</replaceable>.core</userinput></screen>
 | |
| If you're not in the same directory as the core file, you'll have to
 | |
| do <userinput>dir /path/to/core/file</userinput> first.</para>
 | |
|   
 | |
| <para>You should see something like this:
 | |
| <screen>$ <userinput>gdb a.out</userinput>
 | |
| GDB is free software and you are welcome to distribute copies of it
 | |
|  under certain conditions; type "show copying" to see the conditions.
 | |
| There is absolutely no warranty for GDB; type "show warranty" for details.
 | |
| GDB 4.13 (i386-unknown-freebsd), Copyright 1994 Free Software Foundation, Inc.
 | |
| (gdb) <userinput>core a.out.core</userinput>
 | |
| Core was generated by `a.out'.
 | |
| Program terminated with signal 11, Segmentation fault.
 | |
| Cannot access memory at address 0x7020796d.
 | |
| #0  0x164a in bazz (anint=0x5) at temp.c:17
 | |
| (gdb)</screen></para>
 | |
|   
 | |
| <para>In this case, the program was called
 | |
| <filename>a.out</filename>, so the core file is called
 | |
| <filename>a.out.core</filename>. We can see that the program crashed
 | |
| due to trying to access an area in memory that was not available to
 | |
| it in a function called <function>bazz</function>.</para>
 | |
| 
 | |
| <para>Sometimes it's useful to be able to see how a function was
 | |
| called, as the problem could have occurred a long way up the call
 | |
| stack in a complex program. The <command>bt</command> command causes
 | |
| <command>gdb</command> to print out a back-trace of the call
 | |
| stack:
 | |
| <screen>(gdb) <userinput>bt</userinput>
 | |
| #0  0x164a in bazz (anint=0x5) at temp.c:17
 | |
| #1  0xefbfd888 in end ()
 | |
| #2  0x162c in main () at temp.c:11
 | |
| (gdb)</screen>The <function>end()</function> function is called when
 | |
| a program crashes; in this case, the <function>bazz()</function>
 | |
| function was called from <function>main()</function>.</para>
 | |
| 
 | |
| </sect1>
 | |
| 
 | |
| <sect1>
 | |
| <title>Attaching to a running program</title>
 | |
| 
 | |
| <para>One of the neatest features about <command>gdb</command> is
 | |
| that it can attach to a program that's already running. Of course,
 | |
| that assumes you have sufficient permissions to do so. A common
 | |
| problem is when you are stepping through a program that forks, and
 | |
| you want to trace the child, but the debugger will only let you trace
 | |
| the parent.</para>
 | |
| 
 | |
| <para>What you do is start up another <command>gdb</command>, use
 | |
| <command>ps</command> to find the process ID for the child, and
 | |
| do<screen>(gdb) <userinput>attach <replaceable>pid</replaceable></userinput></screen>  
 | |
| in <command>gdb</command>, and then debug as usual.</para>
 | |
|   
 | |
| <para><quote>That's all very well,</quote> you're probably thinking,
 | |
| <quote>but by the time I've done that, the child process will be over
 | |
| the hill and far away</quote>. Fear not, gentle reader, here's how to
 | |
| do it (courtesy of the <command>gdb</command> info pages):
 | |
| <screen><lineannotation>&hellip</lineannotation>
 | |
| if ((pid = fork()) < 0)		/* _Always_ check this */
 | |
| 	error();
 | |
| else if (pid == 0) {		/* child */
 | |
| 	int PauseMode = 1;
 | |
| 
 | |
| 	while (PauseMode)
 | |
| 		sleep(10);	/* Wait until someone attaches to us */
 | |
| 	<lineannotation>&hellip</lineannotation>
 | |
| } else {			/* parent */
 | |
| 	<lineannotation>&hellip</lineannotation></screen>
 | |
| Now all you have to do is attach to the child, set
 | |
| <symbol>PauseMode</symbol> to <literal>0</literal>, and
 | |
| wait for the <function>sleep()</function> call to return!</para>
 | |
|   
 | |
| </sect1>
 | |
| </chapter>
 | |
| 
 | |
| <chapter id="emacs">
 | |
| <title>Using Emacs as a Development Environment</title>
 | |
| 
 | |
| <sect1>
 | |
| <title>Emacs</title>
 | |
| 
 | |
| <para>Unfortunately, Unix systems don't come with the kind of
 | |
| everything-you-ever-wanted-and-lots-more-you-didn't-in-one-gigantic-package
 | |
| integrated development environments that other systems
 | |
| have.<footnote><para>At least, not unless you pay out very large sums
 | |
| of money.</para></footnote> However, it is possible to set up your
 | |
| own environment. It may not be as pretty, and it may not be quite as
 | |
| integrated, but you can set it up the way you want it. And it's free.
 | |
| And you have the source to it.</para>
 | |
| 
 | |
| <para>The key to it all is Emacs. Now there are some people who
 | |
| loathe it, but many who love it. If you're one of the former, I'm
 | |
| afraid this section will hold little of interest to you. Also, you'll
 | |
| need a fair amount of memory to run it—I'd recommend 8MB in
 | |
| text mode and 16MB in X as the bare minimum to get reasonable
 | |
| performance.</para>
 | |
| 
 | |
| <para>Emacs is basically a highly customisable editor—indeed,
 | |
| it has been customised to the point where it's more like an operating
 | |
| system than an editor! Many developers and sysadmins do in fact
 | |
| spend practically all their time working inside Emacs, leaving it
 | |
| only to log out.</para>
 | |
| 
 | |
| <para>It's impossible even to summarise everything Emacs can do here, but
 | |
| here are some of the features of interest to developers:
 | |
| <itemizedlist>
 | |
| 
 | |
| <listitem><para>Very powerful editor, allowing search-and-replace on
 | |
| both strings and regular expressions (patterns), jumping to start/end
 | |
| of block expression, etc, etc.</para></listitem>
 | |
| 
 | |
| <listitem><para>Pull-down menus and online help.</para></listitem>
 | |
| 
 | |
| <listitem><para>Language-dependent syntax highlighting and
 | |
| indentation.</para></listitem>
 | |
| 
 | |
| <listitem><para>Completely customisable.</para></listitem>
 | |
| 
 | |
| <listitem><para>You can compile and debug programs within
 | |
| Emacs.</para></listitem>
 | |
| 
 | |
| <listitem><para>On a compilation error, you can jump to the offending
 | |
| line of source code.</para></listitem>
 | |
| 
 | |
| <listitem><para>Friendly-ish front-end to the <command>info</command>
 | |
| program used for reading GNU hypertext documentation, including the
 | |
| documentation on Emacs itself.</para></listitem>
 | |
| 
 | |
| <listitem><para>Friendly front-end to <command>gdb</command>,
 | |
| allowing you to look at the source code as you step through your
 | |
| program.</para></listitem>
 | |
| 
 | |
| <listitem><para>You can read Usenet news and mail while your program
 | |
| is compiling.</para></listitem>
 | |
| 
 | |
| </itemizedlist>And doubtless many more that I've overlooked.</para>
 | |
| 
 | |
| <para>Emacs can be installed on FreeBSD using <ulink
 | |
| URL="http://www.freebsd.org/ports/editors">the Emacs
 | |
| port</ulink>.</para>
 | |
| 
 | |
| <para>Once it's installed, start it up and do <userinput>C-h
 | |
| t</userinput> to read an Emacs tutorial—that means hold down
 | |
| the <keycap>control</keycap> key, press <keycap>h</keycap>, let go of
 | |
| the <keycap>control</keycap> key, and then press <keycap>t</keycap>.
 | |
| (Alternatively, you can you use the mouse to select <guimenuitem>Emacs
 | |
| Tutorial</guimenuitem> from the <guimenu>Help</guimenu> menu).</para>
 | |
| 
 | |
| <para>Although Emacs does have menus, it's well worth learning the
 | |
| key bindings, as it's much quicker when you're editing something to
 | |
| press a couple of keys than to try and find the mouse and then click
 | |
| on the right place. And, when you're talking to seasoned Emacs users,
 | |
| you'll find they often casually throw around expressions like
 | |
| <quote><literal>M-x replace-s RET foo RET bar RET</literal></quote>
 | |
| so it's useful to know what they mean. And in any case, Emacs has far
 | |
| too many useful functions for them to all fit on the menu
 | |
| bars.</para>
 | |
| 
 | |
| <para>Fortunately, it's quite easy to pick up the key-bindings, as
 | |
| they're displayed next to the menu item. My advice is to use the
 | |
| menu item for, say, opening a file until you understand how it works
 | |
| and feel confident with it, then try doing C-x C-f. When you're happy
 | |
| with that, move on to another menu command.</para>
 | |
| 
 | |
| <para>If you can't remember what a particular combination of keys
 | |
| does, select <guimenuitem>Describe Key</guimenuitem> from the
 | |
| <guimenu>Help</guimenu> menu and type it in—Emacs will tell you
 | |
| what it does. You can also use the <guimenuitem>Command
 | |
| Apropos</guimenuitem> menu item to find out all the commands which
 | |
| contain a particular word in them, with the key binding next to
 | |
| it.</para>
 | |
| 
 | |
| <para>By the way, the expression above means hold down the
 | |
| <keysym>Meta</keysym> key, press <keysym>x</keysym>, release the
 | |
| <keysym>Meta</keysym> key, type <userinput>replace-s</userinput>
 | |
| (short for <literal>replace-string</literal>—another feature of
 | |
| Emacs is that you can abbreviate commands), press the
 | |
| <keysym>return</keysym> key, type <userinput>foo</userinput> (the
 | |
| string you want replaced), press the <keysym>return</keysym> key,
 | |
| type bar (the string you want to replace <literal>foo</literal> with)
 | |
| and press <keysym>return</keysym> again. Emacs will then do the
 | |
| search-and-replace operation you've just requested.</para>
 | |
| 
 | |
| <para>If you're wondering what on earth the <keysym>Meta</keysym> key
 | |
| is, it's a special key that many Unix workstations have.
 | |
| Unfortunately, PC's don't have one, so it's usually the
 | |
| <keycap>alt</keycap> key (or if you're unlucky, the <keysym>escape</keysym>
 | |
| key).</para>
 | |
| 
 | |
| <para>Oh, and to get out of Emacs, do <command>C-x C-c</command>
 | |
| (that means hold down the <keysym>control</keysym> key, press
 | |
| <keysym>c</keysym>, press <keysym>x</keysym> and release the
 | |
| <keysym>control</keysym> key). If you have any unsaved files open,
 | |
| Emacs will ask you if you want to save them. (Ignore the bit in the
 | |
| documentation where it says <command>C-z</command> is the usual way
 | |
| to leave Emacs—that leaves Emacs hanging around in the
 | |
| background, and is only really useful if you're on a system which
 | |
| doesn't have virtual terminals).</para>
 | |
| 
 | |
| </sect1>
 | |
| 
 | |
| <sect1>
 | |
| <title>Configuring Emacs</title>
 | |
| 
 | |
| <para>Emacs does many wonderful things; some of them are built in,
 | |
| some of them need to be configured.</para>
 | |
| 
 | |
| <para>Instead of using a proprietary macro language for
 | |
| configuration, Emacs uses a version of Lisp specially adapted for
 | |
| editors, known as Emacs Lisp. This can be quite useful if you want to
 | |
| go on and learn something like Common Lisp, as it's considerably
 | |
| smaller than Common Lisp (although still quite big!).</para>
 | |
| 
 | |
| <para>The best way to learn Emacs Lisp is to download the <ulink
 | |
| URL="ftp://prep.ai.mit.edu:pub/gnu/elisp-manual-19-2.4.tar.gz">Emacs
 | |
| Tutorial</ulink></para>
 | |
| 
 | |
| <para>However, there's no need to actually know any Lisp to get
 | |
| started with configuring Emacs, as I've included a sample
 | |
| <filename>.emacs</filename> file, which should be enough to get you
 | |
| started. Just copy it into your home directory and restart Emacs if
 | |
| it's already running; it will read the commands from the file and
 | |
| (hopefully) give you a useful basic setup.</para>
 | |
| 
 | |
| </sect1>
 | |
| 
 | |
| <sect1>
 | |
| <title>A sample <filename>.emacs</filename> file</title>
 | |
| 
 | |
| <para>Unfortunately, there's far too much here to explain it in detail;
 | |
| however there are one or two points worth mentioning.</para>
 | |
|   
 | |
| <para>
 | |
| <itemizedlist>
 | |
| 
 | |
| <listitem><para>Everything beginning with a <literal>;</> is a
 | |
| comment and is ignored by Emacs.</para></listitem>
 | |
| 
 | |
| <listitem><para>In the first line, the
 | |
| <literal>-*- Emacs-Lisp -*-</literal> is so that we can
 | |
| edit the <filename>.emacs</filename> file itself within Emacs and get
 | |
| all the fancy features for editing Emacs Lisp. Emacs usually tries to
 | |
| guess this based on the filename, and may not get it right for
 | |
| <filename>.emacs</filename>. </para></listitem>
 | |
| 
 | |
| <listitem><para>The <keysym>tab</keysym> key is bound to an
 | |
| indentation function in some modes, so when you press the tab key, it
 | |
| will indent the current line of code. If you want to put a
 | |
| <token>tab</token> character in whatever you're writing, hold the
 | |
| <keysym>control</keysym> key down while you're pressing the
 | |
| <keysym>tab</keysym> key.</para></listitem>
 | |
| 
 | |
| <listitem><para>This file supports syntax highlighting for C, C++,
 | |
| Perl, Lisp and Scheme, by guessing the language from the
 | |
| filename.</para></listitem>
 | |
| 
 | |
| <listitem><para>Emacs already has a pre-defined function called
 | |
| <function>next-error</function>. In a compilation output window, this
 | |
| allows you to move from one compilation error to the next by doing
 | |
| <command>M-n</command>; we define a complementary function,
 | |
| <function>previous-error</function>, that allows you to go to a
 | |
| previous error by doing <command>M-p</command>. The nicest feature of
 | |
| all is that <command>C-c C-c</command> will open up the source file
 | |
| in which the error occurred and jump to the appropriate
 | |
| line.</para></listitem>
 | |
| 
 | |
| <listitem><para> We enable Emacs's ability to act as a server, so
 | |
| that if you're doing something outside Emacs and you want to edit a
 | |
| file, you can just type in 
 | |
| <screen>$ <userinput>emacsclient <replaceable>filename</replaceable></userinput></screen>
 | |
| and then you can edit the file in your Emacs!<footnote><para>Many
 | |
| Emacs users set their <systemitem
 | |
| class=environvar>EDITOR</systemitem> environment to
 | |
| <literal>emacsclient</literal> so this happens every time they need
 | |
| to edit a file.</para></footnote></para></listitem>
 | |
| 
 | |
| </itemizedlist>
 | |
| </para>
 | |
|   
 | |
| <example>
 | |
| <title>A sample <filename>.emacs</filename> file</title>
 | |
| <screen>;; -*-Emacs-Lisp-*-
 | |
| 
 | |
| ;; This file is designed to be re-evaled; use the variable first-time
 | |
| ;; to avoid any problems with this.
 | |
| (defvar first-time t 
 | |
|   "Flag signifying this is the first time that .emacs has been evaled")
 | |
| 
 | |
| ;; Meta
 | |
| (global-set-key "\M- " 'set-mark-command)
 | |
| (global-set-key "\M-\C-h" 'backward-kill-word)
 | |
| (global-set-key "\M-\C-r" 'query-replace)
 | |
| (global-set-key "\M-r" 'replace-string)
 | |
| (global-set-key "\M-g" 'goto-line)
 | |
| (global-set-key "\M-h" 'help-command)
 | |
| 
 | |
| ;; Function keys
 | |
| (global-set-key [f1] 'manual-entry)
 | |
| (global-set-key [f2] 'info)
 | |
| (global-set-key [f3] 'repeat-complex-command)
 | |
| (global-set-key [f4] 'advertised-undo)
 | |
| (global-set-key [f5] 'eval-current-buffer)
 | |
| (global-set-key [f6] 'buffer-menu)
 | |
| (global-set-key [f7] 'other-window)
 | |
| (global-set-key [f8] 'find-file)
 | |
| (global-set-key [f9] 'save-buffer)
 | |
| (global-set-key [f10] 'next-error)
 | |
| (global-set-key [f11] 'compile)
 | |
| (global-set-key [f12] 'grep)
 | |
| (global-set-key [C-f1] 'compile)
 | |
| (global-set-key [C-f2] 'grep)
 | |
| (global-set-key [C-f3] 'next-error)
 | |
| (global-set-key [C-f4] 'previous-error)
 | |
| (global-set-key [C-f5] 'display-faces)
 | |
| (global-set-key [C-f8] 'dired)
 | |
| (global-set-key [C-f10] 'kill-compilation)
 | |
| 
 | |
| ;; Keypad bindings
 | |
| (global-set-key [up] "\C-p")
 | |
| (global-set-key [down] "\C-n")
 | |
| (global-set-key [left] "\C-b")
 | |
| (global-set-key [right] "\C-f")
 | |
| (global-set-key [home] "\C-a")
 | |
| (global-set-key [end] "\C-e")
 | |
| (global-set-key [prior] "\M-v")
 | |
| (global-set-key [next] "\C-v")
 | |
| (global-set-key [C-up] "\M-\C-b")
 | |
| (global-set-key [C-down] "\M-\C-f")
 | |
| (global-set-key [C-left] "\M-b")
 | |
| (global-set-key [C-right] "\M-f")
 | |
| (global-set-key [C-home] "\M-<")
 | |
| (global-set-key [C-end] "\M->")
 | |
| (global-set-key [C-prior] "\M-<")
 | |
| (global-set-key [C-next] "\M->")
 | |
| 
 | |
| ;; Mouse
 | |
| (global-set-key [mouse-3] 'imenu)
 | |
| 
 | |
| ;; Misc
 | |
| (global-set-key [C-tab] "\C-q\t")	; Control tab quotes a tab.
 | |
| (setq backup-by-copying-when-mismatch t)
 | |
| 
 | |
| ;; Treat 'y' or <CR> as yes, 'n' as no.
 | |
| (fset 'yes-or-no-p 'y-or-n-p)
 | |
|     (define-key query-replace-map [return] 'act)
 | |
|     (define-key query-replace-map [?\C-m] 'act)
 | |
| 
 | |
| ;; Load packages
 | |
| (require 'desktop)
 | |
| (require 'tar-mode)
 | |
| 
 | |
| ;; Pretty diff mode
 | |
| (autoload 'ediff-buffers "ediff" "Intelligent Emacs interface to diff" t)
 | |
| (autoload 'ediff-files "ediff" "Intelligent Emacs interface to diff" t)
 | |
| (autoload 'ediff-files-remote "ediff"
 | |
|   "Intelligent Emacs interface to diff") </screen>
 | |
| 
 | |
| <screen>(if first-time
 | |
|     (setq auto-mode-alist
 | |
| 	  (append '(("\\.cpp$" . c++-mode)
 | |
| 		    ("\\.hpp$" . c++-mode)
 | |
|                     ("\\.lsp$" . lisp-mode)
 | |
| 		    ("\\.scm$" . scheme-mode)
 | |
| 		    ("\\.pl$" . perl-mode)
 | |
| 		    ) auto-mode-alist)))
 | |
| 
 | |
| ;; Auto font lock mode
 | |
| (defvar font-lock-auto-mode-list 
 | |
|   (list 'c-mode 'c++-mode 'c++-c-mode 'emacs-lisp-mode 'lisp-mode 'perl-mode 'scheme-mode)
 | |
|   "List of modes to always start in font-lock-mode")
 | |
| 
 | |
| (defvar font-lock-mode-keyword-alist
 | |
|   '((c++-c-mode . c-font-lock-keywords)
 | |
|     (perl-mode . perl-font-lock-keywords))
 | |
|   "Associations between modes and keywords")
 | |
| 
 | |
| (defun font-lock-auto-mode-select ()
 | |
|   "Automatically select font-lock-mode if the current major mode is
 | |
| in font-lock-auto-mode-list"
 | |
|   (if (memq major-mode font-lock-auto-mode-list) 
 | |
|       (progn
 | |
| 	(font-lock-mode t))
 | |
|     )
 | |
|   )
 | |
| 
 | |
| (global-set-key [M-f1] 'font-lock-fontify-buffer)
 | |
| 
 | |
| ;; New dabbrev stuff
 | |
| ;(require 'new-dabbrev)
 | |
| (setq dabbrev-always-check-other-buffers t)
 | |
| (setq dabbrev-abbrev-char-regexp "\\sw\\|\\s_")
 | |
| (add-hook 'emacs-lisp-mode-hook
 | |
| 	  '(lambda () 
 | |
| 	     (set (make-local-variable 'dabbrev-case-fold-search) nil)
 | |
| 	     (set (make-local-variable 'dabbrev-case-replace) nil)))
 | |
| (add-hook 'c-mode-hook
 | |
| 	  '(lambda () 
 | |
| 	     (set (make-local-variable 'dabbrev-case-fold-search) nil)
 | |
| 	     (set (make-local-variable 'dabbrev-case-replace) nil)))
 | |
| (add-hook 'text-mode-hook
 | |
| 	  '(lambda () 
 | |
| 	     (set (make-local-variable 'dabbrev-case-fold-search) t)
 | |
| 	     (set (make-local-variable 'dabbrev-case-replace) t)))
 | |
| 
 | |
| ;; C++ and C mode...
 | |
| (defun my-c++-mode-hook ()
 | |
|   (setq tab-width 4)
 | |
|   (define-key c++-mode-map "\C-m" 'reindent-then-newline-and-indent)
 | |
|   (define-key c++-mode-map "\C-ce" 'c-comment-edit)
 | |
|   (setq c++-auto-hungry-initial-state 'none)
 | |
|   (setq c++-delete-function 'backward-delete-char)
 | |
|   (setq c++-tab-always-indent t)
 | |
|   (setq c-indent-level 4)
 | |
|   (setq c-continued-statement-offset 4)
 | |
|   (setq c++-empty-arglist-indent 4))
 | |
| 
 | |
| (defun my-c-mode-hook ()
 | |
|   (setq tab-width 4)
 | |
|   (define-key c-mode-map "\C-m" 'reindent-then-newline-and-indent)
 | |
|   (define-key c-mode-map "\C-ce" 'c-comment-edit)
 | |
|   (setq c-auto-hungry-initial-state 'none)
 | |
|   (setq c-delete-function 'backward-delete-char)
 | |
|   (setq c-tab-always-indent t)
 | |
| ;; BSD-ish indentation style
 | |
|   (setq c-indent-level 4)
 | |
|   (setq c-continued-statement-offset 4)
 | |
|   (setq c-brace-offset -4)
 | |
|   (setq c-argdecl-indent 0)
 | |
|   (setq c-label-offset -4))
 | |
| 
 | |
| ;; Perl mode
 | |
| (defun my-perl-mode-hook ()
 | |
|   (setq tab-width 4)
 | |
|   (define-key c++-mode-map "\C-m" 'reindent-then-newline-and-indent)
 | |
|   (setq perl-indent-level 4)
 | |
|   (setq perl-continued-statement-offset 4))
 | |
| 
 | |
| ;; Scheme mode...
 | |
| (defun my-scheme-mode-hook ()
 | |
|   (define-key scheme-mode-map "\C-m" 'reindent-then-newline-and-indent))
 | |
| 
 | |
| ;; Emacs-Lisp mode...
 | |
| (defun my-lisp-mode-hook ()
 | |
|   (define-key lisp-mode-map "\C-m" 'reindent-then-newline-and-indent)
 | |
|   (define-key lisp-mode-map "\C-i" 'lisp-indent-line)
 | |
|   (define-key lisp-mode-map "\C-j" 'eval-print-last-sexp))
 | |
| 
 | |
| ;; Add all of the hooks...
 | |
| (add-hook 'c++-mode-hook 'my-c++-mode-hook)
 | |
| (add-hook 'c-mode-hook 'my-c-mode-hook)
 | |
| (add-hook 'scheme-mode-hook 'my-scheme-mode-hook)
 | |
| (add-hook 'emacs-lisp-mode-hook 'my-lisp-mode-hook)
 | |
| (add-hook 'lisp-mode-hook 'my-lisp-mode-hook)
 | |
| (add-hook 'perl-mode-hook 'my-perl-mode-hook)
 | |
| 
 | |
| ;; Complement to next-error
 | |
| (defun previous-error (n)
 | |
|   "Visit previous compilation error message and corresponding source code."
 | |
|   (interactive "p")
 | |
|   (next-error (- n)))</screen>
 | |
| 
 | |
| <screen>;; Misc...
 | |
| (transient-mark-mode 1)
 | |
| (setq mark-even-if-inactive t)
 | |
| (setq visible-bell nil)
 | |
| (setq next-line-add-newlines nil)
 | |
| (setq compile-command "make")
 | |
| (setq suggest-key-bindings nil)
 | |
| (put 'eval-expression 'disabled nil)
 | |
| (put 'narrow-to-region 'disabled nil)
 | |
| (put 'set-goal-column 'disabled nil)
 | |
| 
 | |
| ;; Elisp archive searching
 | |
| (autoload 'format-lisp-code-directory "lispdir" nil t)
 | |
| (autoload 'lisp-dir-apropos "lispdir" nil t)
 | |
| (autoload 'lisp-dir-retrieve "lispdir" nil t)
 | |
| (autoload 'lisp-dir-verify "lispdir" nil t)
 | |
| 
 | |
| ;; Font lock mode
 | |
| (defun my-make-face (face colour &optional bold)
 | |
|   "Create a face from a colour and optionally make it bold"
 | |
|   (make-face face)
 | |
|   (copy-face 'default face)
 | |
|   (set-face-foreground face colour)
 | |
|   (if bold (make-face-bold face))
 | |
|   )
 | |
| 
 | |
| (if (eq window-system 'x)
 | |
|     (progn
 | |
|       (my-make-face 'blue "blue")
 | |
|       (my-make-face 'red "red")
 | |
|       (my-make-face 'green "dark green")
 | |
|       (setq font-lock-comment-face 'blue)
 | |
|       (setq font-lock-string-face 'bold)
 | |
|       (setq font-lock-type-face 'bold)
 | |
|       (setq font-lock-keyword-face 'bold)
 | |
|       (setq font-lock-function-name-face 'red)
 | |
|       (setq font-lock-doc-string-face 'green)
 | |
|       (add-hook 'find-file-hooks 'font-lock-auto-mode-select)
 | |
| 
 | |
|       (setq baud-rate 1000000)
 | |
|       (global-set-key "\C-cmm" 'menu-bar-mode)
 | |
|       (global-set-key "\C-cms" 'scroll-bar-mode)
 | |
|       (global-set-key [backspace] 'backward-delete-char)
 | |
| 					;      (global-set-key [delete] 'delete-char)
 | |
|       (standard-display-european t)
 | |
|       (load-library "iso-transl")))
 | |
| 
 | |
| ;; X11 or PC using direct screen writes
 | |
| (if window-system
 | |
|     (progn
 | |
|       ;;      (global-set-key [M-f1] 'hilit-repaint-command)
 | |
|       ;;      (global-set-key [M-f2] [?\C-u M-f1])
 | |
|       (setq hilit-mode-enable-list  
 | |
| 	    '(not text-mode c-mode c++-mode emacs-lisp-mode lisp-mode
 | |
| 		  scheme-mode)
 | |
| 	    hilit-auto-highlight nil
 | |
| 	    hilit-auto-rehighlight 'visible
 | |
| 	    hilit-inhibit-hooks nil
 | |
| 	    hilit-inhibit-rebinding t)
 | |
|       (require 'hilit19)
 | |
|       (require 'paren))
 | |
|   (setq baud-rate 2400)			; For slow serial connections
 | |
|   )
 | |
| 
 | |
| ;; TTY type terminal
 | |
| (if (and (not window-system) 
 | |
| 	 (not (equal system-type 'ms-dos)))
 | |
|     (progn
 | |
|       (if first-time
 | |
| 	  (progn
 | |
| 	    (keyboard-translate ?\C-h ?\C-?)
 | |
| 	    (keyboard-translate ?\C-? ?\C-h)))))
 | |
| 
 | |
| ;; Under UNIX
 | |
| (if (not (equal system-type 'ms-dos))
 | |
|     (progn
 | |
|       (if first-time
 | |
| 	  (server-start))))
 | |
| 
 | |
| ;; Add any face changes here
 | |
| (add-hook 'term-setup-hook 'my-term-setup-hook)
 | |
| (defun my-term-setup-hook ()
 | |
|   (if (eq window-system 'pc)
 | |
|       (progn
 | |
| ;;	(set-face-background 'default "red")
 | |
| 	)))
 | |
| 
 | |
| ;; Restore the "desktop" - do this as late as possible
 | |
| (if first-time
 | |
|     (progn
 | |
|       (desktop-load-default)
 | |
|       (desktop-read)))
 | |
| 
 | |
| ;; Indicate that this file has been read at least once
 | |
| (setq first-time nil)
 | |
| 
 | |
| ;; No need to debug anything now
 | |
| (setq debug-on-error nil)
 | |
| 
 | |
| ;; All done
 | |
| (message "All done, %s%s" (user-login-name) ".")
 | |
| </screen>
 | |
| </example>
 | |
|   
 | |
| </sect1>
 | |
| 
 | |
| <sect1>
 | |
| <title>Extending the Range of Languages Emacs Understands</title>
 | |
| 
 | |
| <para>Now, this is all very well if you only want to program in the
 | |
| languages already catered for in the <filename>.emacs</filename> file
 | |
| (C, C++, Perl, Lisp and Scheme), but what happens if a new language
 | |
| called <quote>whizbang</quote> comes out, full of exciting
 | |
| features?</para>
 | |
| 
 | |
| <para>The first thing to do is find out if whizbang
 | |
| comes with any files that tell Emacs about the language. These
 | |
| usually end in <filename>.el</filename>, short for <quote>Emacs
 | |
| Lisp</quote>. For example, if whizbang is a FreeBSD
 | |
| port, we can locate these files by doing
 | |
| <screen>$ <userinput>find /usr/ports/lang/whizbang -name "*.el" -print</userinput></screen>
 | |
| and install them by copying them into the Emacs site Lisp directory. On
 | |
| FreeBSD 2.1.0-RELEASE, this is
 | |
| <filename>/usr/local/share/emacs/site-lisp</filename>.</para>
 | |
| 
 | |
| <para>So for example, if the output from the find command was
 | |
| <screen>/usr/ports/lang/whizbang/work/misc/whizbang.el</screen>
 | |
| we would do
 | |
| <screen>$ <userinput>cp /usr/ports/lang/whizbang/work/misc/whizbang.el /usr/local/share/emacs/site-lisp</userinput></screen>
 | |
| </para>
 | |
|   
 | |
| <para>Next, we need to decide what extension whizbang source files
 | |
| have. Let's say for the sake of argument that they all end in
 | |
| <filename>.wiz</filename>. We need to add an entry to our
 | |
| <filename>.emacs</filename> file to make sure Emacs will be able to
 | |
| use the information in <filename>whizbang.el</filename>.</para>
 | |
| 
 | |
| <para>Find the <symbol>auto-mode-alist entry</symbol> in
 | |
| <filename>.emacs</filename> and add a line for whizbang, such
 | |
| as:
 | |
| <programlisting><lineannotation>…</>
 | |
| ("\\.lsp$" . lisp-mode)
 | |
| ("\\.wiz$" . whizbang-mode)
 | |
| ("\\.scm$" . scheme-mode)
 | |
| <lineannotation>…</></programlisting>  
 | |
| This means that Emacs will automatically go into
 | |
| <function>whizbang-mode</function> when you edit a file ending in
 | |
| <filename>.wiz</filename>.</para>
 | |
| 
 | |
| <para>Just below this, you'll find the
 | |
| <symbol>font-lock-auto-mode-list</symbol> entry. Add
 | |
| <function>whizbang-mode</function> to it like so:
 | |
| <programlisting>;; Auto font lock mode
 | |
| (defvar font-lock-auto-mode-list 
 | |
|   (list 'c-mode 'c++-mode 'c++-c-mode 'emacs-lisp-mode 'whizbang-mode 'lisp-mode 'perl-mode 'scheme-mode)
 | |
|   "List of modes to always start in font-lock-mode")</programlisting>
 | |
| This means that Emacs will always enable
 | |
| <function>font-lock-mode</function> (ie syntax highlighting) when
 | |
| editing a <filename>.wiz</filename> file.</para>
 | |
| 
 | |
| <para>And that's all that's needed. If there's anything else you want
 | |
| done automatically when you open up a <filename>.wiz</filename> file,
 | |
| you can add a <function>whizbang-mode hook</function> (see
 | |
| <function>my-scheme-mode-hook</function> for a simple example that
 | |
| adds <function>auto-indent</function>).</para>
 | |
|   
 | |
| </sect1>
 | |
| </chapter>
 | |
| 
 | |
| <chapter>
 | |
| <title>Further Reading</title>
 | |
| 
 | |
| <itemizedlist>
 | |
| <listitem><para>Brian Harvey and Matthew Wright
 | |
| <emphasis>Simply Scheme</emphasis>
 | |
| MIT 1994.<!-- <br> -->
 | |
| ISBN 0-262-08226-8</para></listitem>
 | |
| 
 | |
| <listitem><para>Randall Schwartz
 | |
| <emphasis>Learning Perl</emphasis>
 | |
| O'Reilly 1993<!-- <br> -->
 | |
| ISBN 1-56592-042-2</para></listitem>
 | |
| 
 | |
| <listitem><para>Patrick Henry Winston and Berthold Klaus Paul Horn
 | |
| <emphasis>Lisp (3rd Edition)</emphasis>
 | |
| Addison-Wesley 1989<!-- <br> -->
 | |
| ISBN 0-201-08319-1</para></listitem>
 | |
| 
 | |
| <listitem><para>Brian W. Kernighan and Rob Pike
 | |
| <emphasis>The Unix Programming Environment</emphasis>
 | |
| Prentice-Hall 1984<!-- <br> -->
 | |
| ISBN 0-13-937681-X</para></listitem>
 | |
| 
 | |
| <listitem><para>Brian W. Kernighan and Dennis M. Ritchie
 | |
| <emphasis>The C Programming Language (2nd Edition)</emphasis>
 | |
| Prentice-Hall 1988<!-- <br> -->
 | |
| ISBN 0-13-110362-8</para></listitem>
 | |
| 
 | |
| <listitem><para>Bjarne Stroustrup
 | |
| <emphasis>The C++ Programming Language</emphasis>
 | |
| Addison-Wesley 1991<!-- <br> -->
 | |
| ISBN 0-201-53992-6</para></listitem>
 | |
| 
 | |
| <listitem><para>W. Richard Stevens
 | |
| <emphasis>Advanced Programming in the Unix Environment</emphasis>
 | |
| Addison-Wesley 1992<!-- <br> -->
 | |
| ISBN 0-201-56317-7</para></listitem>
 | |
| 
 | |
| <listitem><para>W. Richard Stevens
 | |
| <emphasis>Unix Network Programming</emphasis>
 | |
| Prentice-Hall 1990<!-- <br> -->
 | |
| ISBN 0-13-949876-1</para></listitem>
 | |
| 
 | |
| </itemizedlist>
 | |
| 
 | |
| </chapter>
 | |
| </book>
 |