13. Software Development

Q: How Do I Compile Programs?
Q: How Do I Port XXX to Linux?
Q: Can I Use Code or a Compiler Compiled for a 486 on a 386?
Q: What Does gcc -O6 Do?
Q: What Do I Do About Errors Trying to Compile the Kernel?
Q: How Do I Make a Shared Library?
Q: Why Are My Programs So Large?
Q: How To Prevent Errors when Linking Programs with Math Functions
Q: How To Program XYZ Under Linux
Q: How To Upgrade/Recompile a Kernel
Q: What Is a .gz File? And a .tgz? And .bz2? And... ?
Q: Where Are linux/*.h and asm/*.h?
Q: Configuring Emacs' Default Settings

Q: How Do I Compile Programs?

A: Most Linux software is written in C and compiled with the GNU C compiler. GCC is a part of every Linux distribution. The latest compiler version, documentation, and patches are on ftp://ftp.gnu.org/pub/gnu/.

Programs that are written in C++ must be compiled with the GNU G++ compiler, which is also included in Linux distributions and available from the same place as GCC.

To build version 2.0.x kernels, you will need GCC version 2.7.2.x, approximately. Trying to build an early Linux kernel with a different compiler, like GCC 2.8.x, EGCS, or PGCC, may cause problems because of GCC related code dependencies. Kernel versions 2.2, 2.4, and the 2.5 development kernels should compile correctly with more recent compilers.

Information on the EGCS compiler is at http://www.gnu.org/software/gcc/gcc.html.

Note that at this time, the kernel developers are not answering bug requests for earlier kernels, but instead are concentrating on developing 2.5.x version kernels and maintaining 2.2.x and 2.4.x version kernels.

[J.H.M. Dassen, Axel Boldt]

Q: How Do I Port XXX to Linux?

A: In general, *nix programs need very little porting. Simply follow the installation instructions. If you don't know and don't know how to find out the answers to some of the questions asked during the installation procedure, you can guess, but this tends to produce buggy programs. In this case, you're probably better off asking someone else to do the port.

If you have a BSD-ish program, you should try using -I/usr/include/bsd and -lbsd on the appropriate parts of the compilation lines.

Q: Can I Use Code or a Compiler Compiled for a 486 on a 386?

A: Yes, unless it's the kernel.

The -m486 option to GCC, which is used to compile binaries for x486 machines, merely changes certain optimizations. This makes for slightly larger binaries that run somewhat faster on a 486. They still work fine on a 386, though, with a small performance hit.

However, from version 1.3.35 the kernel uses 486 or Pentium-specific instructions if configured for a 486 or Pentium, thus making it unusable on a 386.

GCC can be configured for a 386 or 486; the only difference is that configuring it for a 386 makes -m386 the default and configuring for a 486 makes -m486 the default. In either case, these can be overridden on a per-compilation basis or by editing /usr/lib/gcc-lib/i*-linux/ n.n.n/specs.

There is an alpha version of GCC that knows how to do optimization well for the 586, but it is quite unreliable, especially at high optimization settings. The Pentium GCC can be found on ftp://tsx-11.mit.edu/pub/linux/ALPHA/pentium-gcc/.

The ordinary 486 GCC supposedly produces better code for the Pentium using the -m386, or at least slightly smaller.

Q: What Does gcc -O6 Do?

A: Currently, the same as -O2 (GCC 2.5) or -O3 (GCC 2.6, 2.7). Any number greater than that does the same thing. The Makefiles of newer kernels use -O2, and you should probably do the same.

Q: What Do I Do About Errors Trying to Compile the Kernel?

A: See the previous question regarding the header files.

Remember that when you apply a patch to the kernel, you must use the -p0 or -p1 option: otherwise, the patch may be misapplied. See the patch manual page for details.

ld: unrecognized option -qmagic means that you should get a newer linker, from ftp://tsx-11.mit.edu/pub/linux/packages/GCC/, in the file binutils-2.8.1.0.1.bin.tar.gz.

Q: How Do I Make a Shared Library?

A: For ELF,

 $ gcc -fPIC -c *.c
 $ gcc -shared -Wl,-soname,libfoo.so.1 -o libfoo.so.1.0 *.o

For a.out, get tools-n.nn.tar.gz from tsx-11.mit.edu/pub/linux/packages/GCC/src/. It comes with documentation that will tell you what to do. Note that a.out shared libraries are a very tricky business. Consider upgrading your libraries to ELF shared libraries. See the ELF HOWTO, at ftp://metalab.unc.edu/pub/Linux/docs/HOWTO/.

Q: Why Are My Programs So Large?

A: With an ELF compiler (What's All This about ELF? glibc?), the most common cause of large executables is the lack of an appropriate .so library link for one of the libraries you're using. There should be a link like libc.so for every library like libc.so.5.2.18.

With an a.out compiler the most common cause of large executables is the -g linker (compiler) flag. This produces (as well as debugging information in the output file) a program which is statically linkedone which includes a copy of the C library instead of a dynamically linked copy.

Other things worth investigating are -O and -O2, which enable optimization (check the GCC documentation), and -s (or the strip command) which strip the symbol information from the resulting binary (making debugging totally impossible).

You may wish to use -N on very small executables (less than 8K with the -N), but you shouldn't do this unless you understand its performance implications, and definitely never with daemons.

Q: How To Prevent Errors when Linking Programs with Math Functions

A: Older run-time libraries included the math library in the C run-time library. It was not necessary to specify the math library separately when compiling. If the compiler generates a message like this when linking a program that uses math functions:

 /tmp/ccDUQM4J.o: In function "main":
 /tmp/ccDUQM4J.o(.text+0x19): undefined reference to "sqrt"
 collect2: ld returned 1 exit status 

You need use the -lm option with GCC to link with the math libraries:

 # gcc -o program program.c -lm 

Make sure also to use the statement #include <math.h> in the source file.

[Florian Schmidt]

Q: How To Program XYZ Under Linux

A: Read the manuals, or a good book on Unix and the manual pages (type man man). There is a lot of GNU Info documentation, which is often more useful as a tutorial. Run Emacs and type F1-i, or type info info if you don't have or don't like Emacs. Note that the Emacs libc node may not exactly describe the latest Linux libc, or GNU glibc2. But the GNU project and LDP are always looking for volunteers to upgrade their library documentation.

Anyway, between the existing Texinfo documentation, and the manual pages in sections 2 and 3, should provide enough information to get started.

As with all free software, the best tutorial is the source code itself.

The latest release of the Linux manual pages, a collection of useful GNU Info documentation, and various other information related to programming Linux, can be found on metalab.unc.edu/pub/Linux/docs/man-pages/.

Q: How To Upgrade/Recompile a Kernel

A: See the Kernel HOWTO or the README files which come with the kernel release on ftp://ftp.cs.helsinki.fi/pub/Software/Linux/Kernel/ and mirrors. See Where Are the Linux FTP Archives?. You may already have a version of the kernel source code installed on your system, but if it is part of a standard distribution it is likely to be somewhat out of date (this is not a problem if you only want a custom configured kernel, but it probably is if you need to upgrade.)

With newer kernels you can (and should) make all of the following targets. Don't forget that you can specify multiple targets with one command.

 $ make clean dep install modules modules_install 

Also remember to update the module dependencies.

 $ depmod -a 

This command can be run automatically at boot time. On Debian/GNU Linux systems, the command is part of the /etc/init.d/modutils script, and can be linked appropriately in the /etc/rcx.d/ directories. For more information on depmod, see the manual page.

Make sure you are using the most recent version of the modutils utilities, as well as all other supporting packages. Refer to the file Documentation/Changes in the kernel source tree for specifics, and be sure to consult the README file in the modutils package.

Remember that to make the new kernel boot you must run lilo after copying the kernel into your root partition. The Makefile in some kernels have a special zlilo target for this; try:

 $ make zlilo 

On current systems, however, you can simply copy the zImage or bzImage file (in arch/i386/boot/ to the /boot/ directory on the root file system, or to a floppy using the dd command. Refer also to the question, How do I get LILO to boot the kernel image?

Kernel version numbers with an odd minor version (ie, 1.1.x, 1.3.x) are the testing releases; stable production kernels have even minor versions (1.0.x, 1.2.x). If you want to try the testing kernels you should probably subscribe to the linux-kernel mailing list. See What Mailing Lists Are There?.

The Web site http://www.kernelnotes.org/ has lots of information and links to other sites that provide information about Linux kernel updates.

Also refer to the answers for, Why Doesn't My PCMCIA Card Work after Upgrading the Kernel? and How Do I Get LILO to Boot the Kernel Image?.

A: Alternatively, on Debian GNU/Linux systems, get a kernel source package from the Debian archive or from a Debian GNU/Linux CD. Then, follow the directions in the README file that is located in the kernel-package subdirectory.

Q: What Is a .gz File? And a .tgz? And .bz2? And... ?

A: .gz (and .z) files are compressed using GNU gzip. You need to use gunzip (which is a symlink to the gzip command that comes with most Linux installations) to unpack the file.

.taz, .tar.Z, and .tz are tar files (made with tar) and compressed using compress. The standard *nix compress is proprietary software, but free equivalents like ncompress exist.

.tgz (or .tpz) is a tar file compressed with gzip.

.bz2 is a file compressed by the more recently introduced (and efficient) bzip2.

.lsm is a Linux Software Map entry, in the form of a short text file. Details about the LSM project and the LSM itself are available in the subdirectory on ftp://metalab.unc.edu/pub/Linux/docs/.

.deb is a Debian Binary Package - the binary package format used by the Debian GNU/Linux distribution. It is manipulated using dpkg and dpkg-deb (available on Debian systems and from: http://ftp.debian.org/pool/main/d/dpkg/. If you use anonymous FTP, connect to: ftp://ftp.debian.org/debian/pool/main/d/dpkg/).

.rpm is a Red Hat RPM package, which is used in the Red Hat and similar distributions.

.sit is a compressed Macintosh archive made with StuffIt, a commercial program. Aladdin Systems Inc., the manufacturer of StuffIt, has a free expander utility that will uncompress these archives. You can download it at http://www.aladdinsys.com/expander/.

The file command can often tell you what a file is.

If you find that gzip complains when you try to uncompress a file, you probably downloaded it in ASCII mode by mistake. You must download most things in binary mode: get, to download the file.

Q: Where Are linux/*.h and asm/*.h?

A: The files /usr/include/linux/ and /usr/include/asm/ are often soft links to the directories where the kernel headers are. They are usually under /usr/src/kernel*/.

If you don't have the kernel sources, download them. Refer to the answer for How To Upgrade/Recompile a Kernel.

Then, use rm to remove any garbage, and ln to create the links:

 $ rm -rf /usr/include/linux /usr/include/asm
 $ ln -sf /usr/src/linux/include/linux /usr/include/linux
 $ ln -sf /usr/src/linux/include/asm-<architecture> /usr/include/asm

The assembly language files reside in architecture-specific directories, so you need to link /usr/src/include/asm to /usr/src/linux/include/asm-i386 on PC compatible systems, to /usr/src/linux/include/asm-sparc on Sun Sparc systems, to /usr/src/linux/include/asm-ppc on PPC systems, and so on.

You'll also find that you may need to do "make config" as in a newly-unpacked kernel source tree, to create linux/autoconf.h.

Q: Configuring Emacs' Default Settings

A: Create a file in your home directory named .emacs with the Emacs Lisp commands that you want to run every time Emacs starts up. You won't see the file in the directory listing. (The leading '.' tells ls not to display it, unless you use the -a command line switch with ls.)

Any kind of Emacs Lisp statement will work in the .emacs file, including entire defuns. Emacs uses lisp variables and statements extensively, and many of the editing functions are written in Emacs Lisp. For example, to enable word wrapping whenever you edit a file that ends with .txt, add the following statement. This is from the Emacs Texinfo help document ( F1-i, then m Emacs Return):

 (add-hook text-mode-hook
        '(lambda () (auto-fill-mode1)))

This adds a statement that calls a hook function whenever a text editing mode is entered for that buffer. The value of text-mode-hook, which is a variable, to auto-fill-mode, which is a function.

If you want to turn off the menu bar at the top of each Emacs frame, add this statement:

 (menu-bar-mode -1)

And if you want to include an Emacs Lisp program that someone has written, like msb.el (an enhanced, pop-up buffer menu), make sure the lisp file is in a directory where Emacs can find it (usually it will be named Site-lisp), and add these statements in the .emacs file:

 (require 'msb)
 (msb-mode 1) 

Most tasks have several possible solutions in Emacs Lisp. Any task that can be programmed in Emacs Lisp is valid in the .emacs file. For more information, consult the Texinfo documentation. There is also a FAQ list for Emacs (refer to: What other FAQ's are there for Linux? ).