2332 lines
83 KiB
XML
2332 lines
83 KiB
XML
<?xml version="1.0" encoding="ISO8859-1" standalone="no"?>
|
|
<!--
|
|
The FreeBSD Documentation Project
|
|
|
|
$FreeBSD$
|
|
-->
|
|
|
|
<chapter id="tools">
|
|
<chapterinfo>
|
|
<authorgroup>
|
|
<author>
|
|
<firstname>James</firstname>
|
|
<surname>Raynard</surname>
|
|
<contrib>Contributed by </contrib>
|
|
</author>
|
|
<author>
|
|
<firstname>Murray</firstname>
|
|
<surname>Stokely</surname>
|
|
</author>
|
|
</authorgroup>
|
|
</chapterinfo>
|
|
|
|
<title>Programming Tools</title>
|
|
<sect1 id="tools-synopsis"><title>Synopsis</title>
|
|
|
|
<para>This chapter 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 chapter assumes little or no previous
|
|
programming knowledge, although it is hoped that most
|
|
programmers will find something of value in it.</para>
|
|
|
|
</sect1>
|
|
|
|
<sect1 id="tools-intro"><title>Introduction</title>
|
|
|
|
<para>FreeBSD offers an excellent development environment.
|
|
Compilers for C and C++ and an assembler come with the
|
|
basic system, not to mention classic &unix;
|
|
tools such as <command>sed</command> and <command>awk</command>.
|
|
If that is not enough, there are many more compilers and
|
|
interpreters in the Ports collection. The following section,
|
|
<link linkend="tools-programming">Introduction to Programming</link>,
|
|
lists some of the available options. FreeBSD is very
|
|
compatible with standards such as <acronym>&posix;</acronym> and
|
|
<acronym>ANSI</acronym> 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 have 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>
|
|
|
|
</sect1>
|
|
|
|
<sect1 id="tools-programming">
|
|
<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</firstterm>, the other a
|
|
<firstterm>compiler</firstterm>. 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>
|
|
|
|
<sect2>
|
|
<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>, <command>csh</command>) is itself an
|
|
interpreter, and many people do in fact write shell
|
|
<quote>scripts</quote> to help with various
|
|
<quote>housekeeping</quote> 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>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Interpreters available with FreeBSD</title>
|
|
|
|
<para>Here is a list of interpreters that are available from
|
|
the &os; Ports Collection, with a brief discussion of
|
|
some of the more popular interpreted languages.</para>
|
|
|
|
<para>Instructions on how to get and install applications
|
|
from the Ports Collection can be found in the
|
|
<ulink url="&url.books.handbook;/ports-using.html">
|
|
Ports section</ulink> of the handbook.</para>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><acronym>BASIC</acronym></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</acronym> has been the first programming
|
|
language for many programmers. It is also the foundation
|
|
for Visual Basic.</para>
|
|
|
|
<para>The Bywater Basic Interpreter can be found in the
|
|
Ports Collection as
|
|
<filename role="package">lang/bwbasic</filename>
|
|
and the Phil Cockroft's Basic Interpreter
|
|
(formerly Rabbit Basic) is available as
|
|
<filename role="package">lang/pbasic</filename>.</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 <acronym>AI</acronym> (Artificial Intelligence)
|
|
circles.</para>
|
|
|
|
<para>Lisp is an extremely powerful and sophisticated
|
|
language, but can be rather large and unwieldy.</para>
|
|
|
|
<para>Various implementations of Lisp that can run on &unix;
|
|
systems are available in the Ports Collection for &os;.
|
|
GNU Common Lisp can be found as
|
|
<filename role="package">lang/gcl</filename>. CLISP
|
|
by Bruno Haible and Michael Stoll is available as
|
|
<filename role="package">lang/clisp</filename>.
|
|
For CMUCL, which includes a highly-optimizing compiler too, or
|
|
simpler Lisp implementations like SLisp, which implements most
|
|
of the Common Lisp constructs in a few hundred lines of C code,
|
|
<filename role="package">lang/cmucl</filename> and
|
|
<filename role="package">lang/slisp</filename> are available
|
|
respectively.</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</acronym> scripts.</para>
|
|
|
|
<para>Perl is available in the Ports Collection as
|
|
<filename role="package">lang/perl5.8</filename> for all
|
|
&os; releases, and is installed as <command>/usr/bin/perl</command>
|
|
in the base system 4.X releases.</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>Scheme is available from the Ports Collection as
|
|
<filename role="package">lang/elk</filename> for the
|
|
Elk Scheme Interpreter. The MIT Scheme Interpreter
|
|
can be found in
|
|
<filename role="package">lang/mit-scheme</filename>
|
|
and the SCM Scheme Interpreter in
|
|
<filename role="package">lang/scm</filename>.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>Icon</term>
|
|
|
|
<listitem>
|
|
<para>Icon is a high-level language with extensive
|
|
facilities for processing strings and structures.
|
|
The version of Icon for &os; can be found in the
|
|
Ports Collection as
|
|
<filename role="package">lang/icon</filename>.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>Logo</term>
|
|
|
|
<listitem>
|
|
<para>Logo is a language that is easy to learn, and has
|
|
been used as an introductory programming language in
|
|
various courses. It is an excellent tool to work with
|
|
when teaching programming in small ages, as it makes the
|
|
creation of elaborate geometric shapes an easy task even
|
|
for very small children.</para>
|
|
|
|
<para>The latest version of Logo for &os; is available from
|
|
the Ports Collection in
|
|
<filename role="package">lang/logo</filename>.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>Python</term>
|
|
|
|
<listitem>
|
|
<para>Python is an Object-Oriented, interpreted language.
|
|
Its advocates argue that it is one of the best languages
|
|
to start programming with, since it is relatively easy
|
|
to start with, but is not limited in comparison to other
|
|
popular interpreted languages that are used for the
|
|
development of large, complex applications (Perl and
|
|
Tcl are two other languages that are popular for such tasks).</para>
|
|
|
|
<para>The latest version of Python is available from the
|
|
Ports Collection in
|
|
<filename role="package">lang/python</filename>.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>Ruby</term>
|
|
|
|
<listitem>
|
|
<para>Ruby is an interpreter, pure object-oriented programming
|
|
language. It has become widely popular because of its easy
|
|
to understand syntax, flexibility when writing code, and the
|
|
ability to easily develop and maintain large, complex
|
|
programs.</para>
|
|
|
|
<para>Ruby is available from the Ports Collection as
|
|
<filename role="package">lang/ruby18</filename>.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>Tcl and Tk</term>
|
|
|
|
<listitem>
|
|
<para>Tcl is an embeddable, interpreted language, that has
|
|
become widely used and became popular mostly because of its portability to many
|
|
platforms. It can be used both for quickly writing
|
|
small, prototype applications, or (when combined with
|
|
Tk, a GUI toolkit) fully-fledged, featureful
|
|
programs.</para>
|
|
|
|
<para>Various versions of Tcl are available as ports
|
|
for &os;. The latest version, Tcl 8.5, can be found in
|
|
<filename role="package">lang/tcl85</filename>.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<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 is also useful if you need to write very efficient
|
|
code, as the compiler can take its time and optimize the code,
|
|
which would not be acceptable in an interpreter. Moreover,
|
|
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. FreeBSD does not include Pascal
|
|
support in the base system, but
|
|
the Free Pascal Compiler is
|
|
available in the Ports Collection as
|
|
<filename role="package">lang/fpc</filename>.</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 include
|
|
an IDE in the base system, but <filename role="package">devel/kdevelop</filename> is
|
|
available in the Ports Collection and many use
|
|
<application>Emacs</application> for this purpose. Using
|
|
<application>Emacs</application> as an IDE is discussed in
|
|
<xref linkend="emacs"/>.</para>
|
|
</sect2>
|
|
|
|
|
|
</sect1>
|
|
|
|
|
|
<sect1 id="tools-compiling">
|
|
<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</command> or <command>gcc</command>. 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 have 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</command> converts the
|
|
source code into its own, machine-independent
|
|
<firstterm>p-code</firstterm> 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 filesystem.</para>
|
|
</step>
|
|
</procedure>
|
|
|
|
<para>The word <firstterm>compiling</firstterm> is often used to refer to
|
|
just steps 1 to 4—the others are referred to as
|
|
<firstterm>linking</firstterm>. Sometimes step 1 is referred to as
|
|
<firstterm>pre-processing</firstterm> and steps 3-4 as
|
|
<firstterm>assembling</firstterm>.</para>
|
|
|
|
<para>Fortunately, almost all this detail is hidden from you, as
|
|
<command>cc</command> is a front end that manages calling all these
|
|
programs with the right arguments for you; simply typing</para>
|
|
|
|
<screen>&prompt.user; <userinput>cc foobar.c</userinput></screen>
|
|
|
|
<para>will cause <filename>foobar.c</filename> to be compiled by all the
|
|
steps above. If you have more than one file to compile, just do
|
|
something like</para>
|
|
|
|
<screen>&prompt.user; <userinput>cc foo.c bar.c</userinput></screen>
|
|
|
|
<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 did not know, a binary sort is an efficient
|
|
way of sorting things into order and a bubble sort
|
|
is not.</para>
|
|
</footnote></para>
|
|
|
|
<para>There are lots and lots of options for <command>cc</command>, which
|
|
are all in the manual 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></option></term>
|
|
|
|
<listitem>
|
|
<para>The output name of the file. If you do not use this
|
|
option, <command>cc</command> will produce an executable called
|
|
<filename>a.out</filename>.
|
|
|
|
<footnote>
|
|
<para>The reasons for this are buried in the mists of
|
|
history.</para>
|
|
</footnote></para>
|
|
|
|
<informalexample>
|
|
<screen>&prompt.user; <userinput>cc foobar.c</userinput> <lineannotation>executable is <filename>a.out</filename></lineannotation>
|
|
&prompt.user; <userinput>cc -o foobar foobar.c</userinput> <lineannotation>executable is <filename>foobar</filename></lineannotation>
|
|
</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>&prompt.user; <userinput>cc -c foobar.c</userinput>
|
|
</screen>
|
|
</informalexample>
|
|
|
|
<para>This will produce an <firstterm>object file</firstterm> (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 are
|
|
satisfied it works properly.</para>
|
|
|
|
<informalexample>
|
|
<screen>&prompt.user; <userinput>cc -g foobar.c</userinput>
|
|
</screen>
|
|
</informalexample>
|
|
|
|
<para>This will produce a debug version of the
|
|
program.
|
|
|
|
<footnote>
|
|
<para>Note, we did not 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 optimized version of the executable. The
|
|
compiler performs various clever tricks to try to produce
|
|
an executable that runs faster than normal. You can add a
|
|
number after the <option>-O</option> to specify a higher
|
|
level of optimization, but this often exposes bugs in the
|
|
compiler's optimizer. 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>Optimization is usually only turned on when compiling
|
|
a release version.</para>
|
|
|
|
<informalexample>
|
|
<screen>&prompt.user; <userinput>cc -O -o foobar foobar.c</userinput>
|
|
</screen>
|
|
</informalexample>
|
|
|
|
<para>This will produce an optimized 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</acronym> 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</acronym> 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 rewrite 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>&prompt.user; <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 at link time.</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>&prompt.user; <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>&prompt.user; <userinput>cc -o foobar foobar.cc -lg++</userinput> <lineannotation>For FreeBSD 2.1.6 and earlier</lineannotation>
|
|
&prompt.user; <userinput>cc -o foobar foobar.cc -lstdc++</userinput> <lineannotation>For FreeBSD 2.2 and later</lineannotation>
|
|
&prompt.user; <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
|
|
&ms-dos; 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>
|
|
|
|
<sect2>
|
|
<title>Common <command>cc</command> Queries and Problems</title>
|
|
|
|
<qandaset>
|
|
<qandaentry>
|
|
<question>
|
|
<para>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?</para>
|
|
|
|
<informalexample>
|
|
<screen>/var/tmp/cc0143941.o: Undefined symbol `_sin' referenced from text segment
|
|
</screen>
|
|
</informalexample>
|
|
</question>
|
|
|
|
<answer>
|
|
<para>When using mathematical functions like
|
|
<function>sin()</function>, you have to tell
|
|
<command>cc</command> to link in the math library, like
|
|
so:</para>
|
|
|
|
<informalexample>
|
|
<screen>&prompt.user; <userinput>cc -o foobar foobar.c -lm</userinput>
|
|
</screen>
|
|
</informalexample>
|
|
</answer>
|
|
</qandaentry>
|
|
|
|
<qandaentry>
|
|
<question>
|
|
<para>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.</para>
|
|
|
|
<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>
|
|
|
|
<para>and I compiled it as:</para>
|
|
|
|
<informalexample>
|
|
<screen>&prompt.user; <userinput>cc temp.c -lm</userinput>
|
|
</screen>
|
|
</informalexample>
|
|
|
|
<para>like you said I should, but I get this when I run
|
|
it:</para>
|
|
|
|
<informalexample>
|
|
<screen>&prompt.user; <userinput>./a.out</userinput>
|
|
2.1 ^ 6 = 1023.000000
|
|
</screen>
|
|
</informalexample>
|
|
|
|
<para>This is <emphasis>not</emphasis> the right answer!
|
|
What is going on?</para>
|
|
</question>
|
|
|
|
<answer>
|
|
<para>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>
|
|
</answer>
|
|
</qandaentry>
|
|
|
|
<qandaentry>
|
|
<question>
|
|
<para>So how do I fix this?</para>
|
|
</question>
|
|
|
|
<answer>
|
|
<para>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!</para>
|
|
|
|
<informalexample>
|
|
<programlisting>#include <math.h>
|
|
#include <stdio.h>
|
|
|
|
int main() {
|
|
...
|
|
</programlisting>
|
|
</informalexample>
|
|
|
|
<para>After recompiling it as you did before, run
|
|
it:</para>
|
|
|
|
<informalexample>
|
|
<screen>&prompt.user; <userinput>./a.out</userinput>
|
|
2.1 ^ 6 = 85.766121
|
|
</screen>
|
|
</informalexample>
|
|
|
|
<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>
|
|
</answer>
|
|
</qandaentry>
|
|
|
|
<qandaentry>
|
|
<question>
|
|
<para>I compiled a file called
|
|
<filename>foobar.c</filename> and I cannot find an
|
|
executable called <filename>foobar</filename>. Where has
|
|
it gone?</para>
|
|
</question>
|
|
|
|
<answer>
|
|
<para>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:</para>
|
|
|
|
<informalexample>
|
|
<screen>&prompt.user; <userinput>cc -o foobar foobar.c</userinput>
|
|
</screen>
|
|
</informalexample>
|
|
</answer>
|
|
</qandaentry>
|
|
|
|
<qandaentry>
|
|
<question>
|
|
<para>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>
|
|
</question>
|
|
|
|
<answer>
|
|
<para>Unlike &ms-dos;, &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 <envar>PATH</envar>
|
|
environment
|
|
variable so that it looks something like</para>
|
|
|
|
<informalexample>
|
|
<screen>bin:/usr/bin:/usr/local/bin:.
|
|
</screen>
|
|
</informalexample>
|
|
|
|
<para>The dot at the end means <quote>look in the current
|
|
directory if it is not in any of the
|
|
others</quote>.</para>
|
|
</answer>
|
|
</qandaentry>
|
|
|
|
<qandaentry>
|
|
<question>
|
|
<para>I called my executable <filename>test</filename>,
|
|
but nothing happens when I run it. What is going
|
|
on?</para>
|
|
</question>
|
|
|
|
<answer>
|
|
<para>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:</para>
|
|
|
|
<informalexample>
|
|
<screen>&prompt.user; <userinput>./test</userinput>
|
|
</screen>
|
|
</informalexample>
|
|
|
|
<para>or choose a better name for your program!</para>
|
|
</answer>
|
|
</qandaentry>
|
|
|
|
<qandaentry>
|
|
<question>
|
|
<para>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>
|
|
</question>
|
|
|
|
<answer>
|
|
<para>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>
|
|
</answer>
|
|
</qandaentry>
|
|
|
|
<qandaentry>
|
|
<question>
|
|
<para>Fascinating stuff, but what I am supposed to do
|
|
now?</para>
|
|
</question>
|
|
|
|
<answer>
|
|
<para>Use <command>gdb</command> to analyze the core (see
|
|
<xref linkend="debugging"/>).</para>
|
|
</answer>
|
|
</qandaentry>
|
|
|
|
<qandaentry>
|
|
<question>
|
|
<para>When my program dumped core, it said something about
|
|
a <errorname>segmentation fault</errorname>. What is
|
|
that?</para>
|
|
</question>
|
|
|
|
<answer>
|
|
<para>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:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>Trying to write to a <symbol>NULL</symbol>
|
|
pointer, eg</para>
|
|
|
|
<programlisting>char *foo = NULL;
|
|
strcpy(foo, "bang!");
|
|
</programlisting>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Using a pointer that has not been initialized,
|
|
eg</para>
|
|
|
|
<programlisting>char *foo;
|
|
strcpy(foo, "bang!");
|
|
</programlisting>
|
|
|
|
<para>The pointer will have some random value that,
|
|
with luck, will point into an area of memory that
|
|
is not available to your program and the kernel will
|
|
kill your program before it can do any damage. If
|
|
you are unlucky, it will 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</para>
|
|
|
|
<programlisting>int bar[20];
|
|
bar[27] = 6;
|
|
</programlisting>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Trying to store something in read-only memory,
|
|
eg</para>
|
|
|
|
<programlisting>char *foo = "My string";
|
|
strcpy(foo, "bang!");
|
|
</programlisting>
|
|
|
|
<para>&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</para>
|
|
|
|
<programlisting>char bar[80];
|
|
free(bar);
|
|
</programlisting>
|
|
|
|
<para>or</para>
|
|
|
|
<programlisting>char *foo = malloc(27);
|
|
free(foo);
|
|
free(foo);
|
|
</programlisting>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<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>
|
|
</answer>
|
|
</qandaentry>
|
|
|
|
<qandaentry>
|
|
<question>
|
|
<para>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>
|
|
</question>
|
|
|
|
<answer>
|
|
<para>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 should not have.</para>
|
|
</answer>
|
|
</qandaentry>
|
|
|
|
<qandaentry>
|
|
<question>
|
|
<para>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 is an
|
|
error?</para>
|
|
</question>
|
|
|
|
<answer>
|
|
<para>Yes, just go to another console or xterm, do</para>
|
|
|
|
<screen>&prompt.user; <userinput>ps</userinput>
|
|
</screen>
|
|
|
|
<para>to find out the process ID of your program, and
|
|
do</para>
|
|
|
|
<screen>&prompt.user; <userinput>kill -ABRT <replaceable>pid</replaceable></userinput>
|
|
</screen>
|
|
|
|
<para>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>
|
|
|
|
<para>Alternatively, you can create a core dump from
|
|
inside your program, by calling the
|
|
<function>abort()</function> function. See the manual page
|
|
of &man.abort.3; to learn more.</para>
|
|
|
|
<para>If you want to create a core dump from outside your
|
|
program, but do not want the process to terminate, you
|
|
can use the <command>gcore</command> program. See the
|
|
manual page of &man.gcore.1; for more information.</para>
|
|
|
|
</answer>
|
|
</qandaentry>
|
|
</qandaset>
|
|
</sect2>
|
|
</sect1>
|
|
|
|
<sect1 id="tools-make">
|
|
<title>Make</title>
|
|
|
|
<sect2>
|
|
<title>What is <command>make</command>?</title>
|
|
|
|
<para>When you are working on a simple program with only one or
|
|
two source files, typing in</para>
|
|
|
|
<screen>&prompt.user; <userinput>cc file1.c file2.c</userinput></screen>
|
|
|
|
<para>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:</para>
|
|
|
|
<screen>&prompt.user; <userinput>cc file1.o file2.o</userinput> … <userinput>file37.c</userinput> …</screen>
|
|
|
|
<para>if we had 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 does not 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 are working in a team with other people who
|
|
forget to tell us when they have 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 is 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 do not.
|
|
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 do not use the <filename>MAKEFILE</filename> form
|
|
as block capitals are often used for documentation files
|
|
like <filename>README</filename>.</para>
|
|
</footnote></para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Example of using <command>make</command></title>
|
|
|
|
<para>Here is a very simple make file:</para>
|
|
|
|
<programlisting>foo: foo.c
|
|
cc -o foo foo.c</programlisting>
|
|
|
|
<para>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
|
|
do not have to be programs. For instance, we could have a make
|
|
file that looks like this:</para>
|
|
|
|
<programlisting>foo: foo.c
|
|
cc -o foo foo.c
|
|
|
|
install:
|
|
cp foo /home/me</programlisting>
|
|
|
|
<para>We can tell make which target we want to make by
|
|
typing:</para>
|
|
|
|
<screen>&prompt.user; <userinput>make <replaceable>target</replaceable></userinput></screen>
|
|
|
|
<para><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 <maketarget>install</maketarget> 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
|
|
<maketarget>foo</maketarget> target, re-compile
|
|
<filename>foo</filename> if necessary, and then stop without
|
|
going on to the <maketarget>install</maketarget> target.</para>
|
|
|
|
<para>Notice that the <maketarget>install</maketarget> target does not
|
|
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 to explain.
|
|
If you do not 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>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Make and include-files</title>
|
|
|
|
<para>C code often starts with a list of files to include, for
|
|
example stdio.h. Some of these files are system-include
|
|
files, some of them are from the project you are now working
|
|
on:
|
|
</para>
|
|
|
|
<programlisting>#include <stdio.h>
|
|
#include "foo.h"
|
|
|
|
int main(....</programlisting>
|
|
|
|
<para>To make sure that this file is recompiled the moment
|
|
<filename>foo.h</filename> is changed, you have to add it in
|
|
your <filename>Makefile</filename>:</para>
|
|
|
|
<programlisting>foo: foo.c foo.h</programlisting>
|
|
|
|
<para>The moment your project is getting bigger and you have
|
|
more and more own include-files to maintain, it will be a
|
|
pain to keep track of all include files and the files which
|
|
are depending on it. If you change an include-file but
|
|
forget to recompile all the files which are depending on
|
|
it, the results will be devastating. <command>gcc</command>
|
|
has an option to analyze your files and to produce a list
|
|
of include-files and their dependencies: <option>-MM</option>.
|
|
</para>
|
|
|
|
<para>If you add this to your Makefile:</para>
|
|
|
|
<programlisting>depend:
|
|
gcc -E -MM *.c > .depend</programlisting>
|
|
|
|
<para>and run <userinput>make depend</userinput>, the file
|
|
<filename>.depend</filename> will appear with a list of
|
|
object-files, C-files and the include-files:</para>
|
|
|
|
<programlisting>foo.o: foo.c foo.h</programlisting>
|
|
|
|
<para>If you change <filename>foo.h</filename>, next time
|
|
you run <command>make</command> all files depending on
|
|
<filename>foo.h</filename> will be recompiled.</para>
|
|
|
|
<para>Do not forget to run <command>make depend</command> each
|
|
time you add an include-file to one of your files.</para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<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 is the essential part of a
|
|
typical ports <filename>Makefile</filename>:</para>
|
|
|
|
<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>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 is not, 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 will agree that is 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 is 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 did not 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 are in <filename>/usr/share/mk</filename>, but it is
|
|
probably best to wait until you have 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>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<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</para>
|
|
|
|
<screen>&prompt.user; <userinput>zmore paper.ascii.gz</userinput></screen>
|
|
|
|
<para>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 is 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</para>
|
|
|
|
<programlisting> * Make: (make). The GNU Make utility.</programlisting>
|
|
|
|
<para>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>
|
|
</sect2>
|
|
</sect1>
|
|
|
|
<sect1 id="debugging">
|
|
<title>Debugging</title>
|
|
|
|
<sect2>
|
|
<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</para>
|
|
|
|
<screen>&prompt.user; <userinput>gdb <replaceable>progname</replaceable></userinput></screen>
|
|
|
|
<para>although many people prefer to run it inside
|
|
<application>Emacs</application>. You can do this by:</para>
|
|
|
|
<screen><userinput>M-x gdb RET <replaceable>progname</replaceable> RET</userinput></screen>
|
|
|
|
<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 is already running, or load a core file to investigate why
|
|
the program crashed. It is even possible to debug the kernel,
|
|
though that is a little trickier than the user applications
|
|
we will 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 is a graphical front-end for it
|
|
(<filename role="package">devel/xxgdb</filename>) in the Ports
|
|
Collection.</para>
|
|
|
|
<para>This section is intended to be an introduction to using
|
|
<command>gdb</command> and does not cover specialized topics
|
|
such as debugging the kernel.</para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Running a program in the debugger</title>
|
|
|
|
<para>You will 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 will only
|
|
see the name of the function you are in, instead of the source
|
|
code. If you see a line like:</para>
|
|
|
|
<screen>… (no debugging symbols found) …</screen>
|
|
|
|
<para>when <command>gdb</command> starts up, you will know that
|
|
the program was not 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 that you are not interested in watching the
|
|
preliminary set-up code in the program being run, and that it
|
|
should stop execution 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 have 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 are 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 is a simple example of how to spot a mistake in a
|
|
program with <command>gdb</command>. This is our program
|
|
(with a deliberate mistake):</para>
|
|
|
|
<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>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</para>
|
|
|
|
<screen>&prompt.user; <userinput>cc -g -o temp temp.c</userinput>
|
|
&prompt.user; <userinput>./temp</userinput>
|
|
This is my program
|
|
anint = 4231</screen>
|
|
|
|
<para>That was not what we expected! Time to see what is going
|
|
on!</para>
|
|
|
|
<screen>&prompt.user; <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</userinput> <lineannotation>Skip the set-up code</lineannotation>
|
|
Breakpoint 1 at 0x160f: file temp.c, line 9. <lineannotation><command>gdb</command> puts breakpoint at <function>main()</function></lineannotation>
|
|
(gdb) <userinput>run</userinput> <lineannotation>Run as far as <function>main()</function></lineannotation>
|
|
Starting program: /home/james/tmp/temp <lineannotation>Program starts running</lineannotation>
|
|
|
|
Breakpoint 1, main () at temp.c:9 <lineannotation><command>gdb</command> stops at <function>main()</function></lineannotation>
|
|
(gdb) <userinput>n</userinput> <lineannotation>Go to next line</lineannotation>
|
|
This is my program <lineannotation>Program prints out</lineannotation>
|
|
(gdb) <userinput>s</userinput> <lineannotation>step into <function>bazz()</function></lineannotation>
|
|
bazz (anint=4231) at temp.c:17 <lineannotation><command>gdb</command> displays stack frame</lineannotation>
|
|
(gdb)</screen>
|
|
|
|
<para>Hang on a minute! How did <symbol>anint</symbol> get to be
|
|
<literal>4231</literal>? Did we not 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>
|
|
|
|
<screen>(gdb) <userinput>up</userinput> <lineannotation>Move up call stack</lineannotation>
|
|
#1 0x1625 in main () at temp.c:11 <lineannotation><command>gdb</command> displays stack frame</lineannotation>
|
|
(gdb) <userinput>p i</userinput> <lineannotation>Show us the value of <symbol>i</symbol></lineannotation>
|
|
$1 = 4231 <lineannotation><command>gdb</command> displays <literal>4231</literal></lineannotation></screen>
|
|
|
|
<para>Oh dear! Looking at the code, we forgot to initialize
|
|
<symbol>i</symbol>. We meant to put</para>
|
|
|
|
<programlisting><lineannotation>…</lineannotation>
|
|
main() {
|
|
int i;
|
|
|
|
i = 5;
|
|
printf("This is my program\n");
|
|
<lineannotation>…</lineannotation></programlisting>
|
|
|
|
<para>but we left the <literal>i=5;</literal> line out. As we
|
|
did not initialize <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 are 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 is 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>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<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</replaceable>.core</filename> 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</para>
|
|
|
|
<screen>(gdb) <userinput>core <replaceable>progname</replaceable>.core</userinput></screen>
|
|
|
|
<para>If you are not in the same directory as the core file,
|
|
you will have to do <userinput>dir
|
|
/path/to/core/file</userinput> first.</para>
|
|
|
|
<para>You should see something like this:</para>
|
|
|
|
<screen>&prompt.user; <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>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 is 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:</para>
|
|
|
|
<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>
|
|
|
|
<para>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>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<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 is 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</para>
|
|
|
|
<screen>(gdb) <userinput>attach <replaceable>pid</replaceable></userinput></screen>
|
|
|
|
<para>in <command>gdb</command>, and then debug as usual.</para>
|
|
|
|
<para><quote>That is all very well,</quote> you are probably
|
|
thinking, <quote>but by the time I have done that, the child
|
|
process will be over the hill and far away</quote>. Fear
|
|
not, gentle reader, here is how to do it (courtesy of the
|
|
<command>gdb</command> info pages):</para>
|
|
|
|
<screen><lineannotation>…</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>…</lineannotation>
|
|
} else { /* parent */
|
|
<lineannotation>…</lineannotation></screen>
|
|
|
|
<para>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>
|
|
</sect2>
|
|
</sect1>
|
|
|
|
<sect1 id="emacs">
|
|
<title>Using Emacs as a Development Environment</title>
|
|
|
|
<sect2>
|
|
<title>Emacs</title>
|
|
|
|
<para>Emacs is a highly customizable
|
|
editor—indeed, it has been customized to the point where
|
|
it is 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 is impossible even to summarize everything Emacs can do
|
|
here, but here are some of the features of interest to
|
|
developers:</para>
|
|
|
|
<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 customizable.</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>
|
|
</itemizedlist>
|
|
|
|
<para>And doubtless many more that have been overlooked.</para>
|
|
|
|
<para>Emacs can be installed on &os; using
|
|
the <filename role="package">editors/emacs</filename>
|
|
port.</para>
|
|
|
|
<para>Once it is 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 is well worth learning
|
|
the key bindings, as it is much quicker when you are editing
|
|
something to press a couple of keys than to try to find the
|
|
mouse and then click on the right place. And, when you are
|
|
talking to seasoned Emacs users, you will find they often
|
|
casually throw around expressions like <quote><literal>M-x
|
|
replace-s RET foo RET bar RET</literal></quote> so it is
|
|
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 is quite easy to pick up the key-bindings,
|
|
as they are 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 are happy with that, move on to
|
|
another menu command.</para>
|
|
|
|
<para>If you can not 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 have just requested.</para>
|
|
|
|
<para>If you are wondering what on earth the
|
|
<keysym>Meta</keysym> key is, it is a special key that many
|
|
&unix; workstations have. Unfortunately, PC's do not have one,
|
|
so it is usually the <keycap>alt</keycap> key (or if you are
|
|
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>x</keysym>, press <keysym>c</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 are on a system
|
|
which does not have virtual terminals).</para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<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. Working with Emacs Lisp can
|
|
be quite helpful if you want to go on and learn something like
|
|
Common Lisp. Emacs Lisp has many features of Common Lisp,
|
|
although it is considerably smaller (and thus easier to
|
|
master).</para>
|
|
|
|
<para>The best way to learn Emacs Lisp is to download the <ulink
|
|
url="ftp://ftp.gnu.org/old-gnu/emacs/elisp-manual-19-2.4.tar.gz">Emacs
|
|
Tutorial</ulink></para>
|
|
|
|
<para>However, there is no need to actually know any Lisp to get
|
|
started with configuring Emacs, as I have 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 is already running; it will read the
|
|
commands from the file and (hopefully) give you a useful basic
|
|
setup.</para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>A sample <filename>.emacs</filename> file</title>
|
|
|
|
<para>Unfortunately, there is far too much here to explain it in
|
|
detail; however there are one or two points worth
|
|
mentioning.</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>Everything beginning with a <literal>;</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 are writing, hold the <keysym>control</keysym> key down
|
|
while you are 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 are doing something outside Emacs and you want to
|
|
edit a file, you can just type in</para>
|
|
|
|
<screen>&prompt.user; <userinput>emacsclient <replaceable>filename</replaceable></userinput>
|
|
</screen>
|
|
|
|
<para>and then you can edit the file in your
|
|
Emacs!
|
|
|
|
<footnote>
|
|
<para>Many Emacs users set their <envar>EDITOR</envar>
|
|
environment to
|
|
<literal>emacsclient</literal> so this happens every
|
|
time they need to edit a file.</para>
|
|
</footnote></para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<example>
|
|
<title>A sample <filename>.emacs</filename> file</title>
|
|
|
|
<programlisting>;; -*-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")
|
|
|
|
(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)))
|
|
|
|
;; 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)
|
|
(if (>= emacs-major-version 21)
|
|
(setq show-trailing-whitespace t))
|
|
|
|
;; 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 color &optional bold)
|
|
"Create a face from a color and optionally make it bold"
|
|
(make-face face)
|
|
(copy-face 'default face)
|
|
(set-face-foreground face color)
|
|
(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) ".")
|
|
</programlisting>
|
|
</example>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<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</para>
|
|
|
|
<screen>&prompt.user; <userinput>find /usr/ports/lang/whizbang -name "*.el" -print</userinput></screen>
|
|
|
|
<para>and install them by copying them into the Emacs site Lisp
|
|
directory. On &os;, this is
|
|
<filename>/usr/local/share/emacs/site-lisp</filename>.</para>
|
|
|
|
<para>So for example, if the output from the find command
|
|
was</para>
|
|
|
|
<screen>/usr/ports/lang/whizbang/work/misc/whizbang.el</screen>
|
|
|
|
<para>we would do</para>
|
|
|
|
<screen>&prompt.root; <userinput>cp /usr/ports/lang/whizbang/work/misc/whizbang.el /usr/local/share/emacs/site-lisp</userinput></screen>
|
|
|
|
<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:</para>
|
|
|
|
<programlisting><lineannotation>…</lineannotation>
|
|
("\\.lsp$" . lisp-mode)
|
|
("\\.wiz$" . whizbang-mode)
|
|
("\\.scm$" . scheme-mode)
|
|
<lineannotation>…</lineannotation></programlisting>
|
|
|
|
<para>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 will find the
|
|
<symbol>font-lock-auto-mode-list</symbol> entry. Add
|
|
<function>whizbang-mode</function> to it like so:</para>
|
|
|
|
<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>
|
|
|
|
<para>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 is all that is needed. If there is 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>
|
|
</sect2>
|
|
</sect1>
|
|
|
|
<sect1 id="tools-reading">
|
|
<title>Further Reading</title>
|
|
|
|
<para>For information about setting up a development environment
|
|
for contributing fixes to FreeBSD itself, please see
|
|
&man.development.7;.</para>
|
|
|
|
<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>
|
|
</sect1>
|
|
|
|
</chapter>
|