Presented by Chad D Kersey on September 16, 2009
Located in CoC 52
Table of Contents
- 1. Introduction
- 2. Libraries
- 2.1. Algorithms and Data Structures
- 2.2. Graphics
- 2.3. Sound
- 2.4. Networking
- 2.5. Concurrency/Parallel Computing
- 2.6. User Interface
- 3. Text Editors
- 4. Invoking the Compiler
- 5. Invoking the Linker
- 6. A Simple Makefile
- 7. Getting Started With the Debugger
- 8. Examining Object Files
- 9. Resources
1. Introduction
This text is meant as a companion to the presentation given on the sixteenth of September, an introductory treatment of the Linux development environment. As such, it is itself incomplete, but should at least provide a useful resource for a student of computing who wishes to know more about the libraries and tools available in most Linux distributions. Also included is the partial source code to a text adventure game program, "Lugventure", intended to serve as an example. In a subdirectory within this program’s source directory is another, even simpler program whose sole purpose is illustrating the creation and use of dynamically linked libraries in one’s programs.
The source code: lugventure.tar.gz.
The presentation itself, and therefore this document, is intended for those who already have some knowledge of programming; perhaps able to write C and C++, but who are also unfamiliar with the Linux development environment. This includes people coming from other Unix-like operating systems that do not use ELF binaries or the GNU development toolchain.
2. Libraries
What follows is a brief list of popular open source libraries for various common tasks:
2.1. Algorithms and Data Structures
- Boost
- The de-facto standard library for C++; templates for a wide variety of data structures and algorithms.
2.2. Graphics
- Open GL
- The widely-supported real-time 3D graphics library.
- Simple Directmedia Layer (SDL)
- Fast, portable graphics and sound library.
2.3. Sound
- libsndfile
- Simple library for opening audio files; allows their contents to be read as a series of integers.
- JACK Audio Connection Kit
- Complex, full-featured audio I/O library with support for explicit mixing and postprocessing.
- Simple Directmedia Layer
- Fast, portable graphics and sound library.
- OpenAL
- OpenGL’s audio equivalent; a 3D sound library with support for features like doppler shift.
2.4. Networking
- Boost
- Boost, in addition to typical network features, includes support for transmitting serialized C++ objects over network connections.
- BSD Sockets
- The standard, plain network interface. Supports a variety of protocols but chances are you’d use this for TCP or UDP.
- libpurple
- A universal internat chat client library.
2.5. Concurrency/Parallel Computing
- POSIX Threads
- The standard, universally supported threading library.
- MPI
- Industry standard message passing library.
- OpenMP
- Fine-grained parallelization framework. Requires compiler support (supported by GCC).
2.6. User Interface
- GNU Readline
- A must for commandline interfaces. Provides emacs or vi-like editing on the command line, and command history.
- Gimp Tool Kit
- Standard GUI toolkit for GNU applications.
- Qt
- C++ GUI toolkit used by all KDE applications.
- Pimpin’ Penguin
- Library for building console GUIs.
3. Text Editors
Once you’ve designed your magnum software opus, figured out what libraries you’re going to use, and factored it into a set of procedures, objects, data structures, old men with pickaxes, or whatever abstraction your language of choice prefers, you’re going to have to actually type the thing. For that you’ll find a text editor helpful. If you’re not familiar with text editors in the Unix world, there is vi and its derivatives, and emacs and its derivatives; people like to argue about which one of these two categories is best. There are also a whole lot of text editors that people don’t argue about, and instead just use them to
edit text files, like Joe’s Own Editor and KATE, the KDE Advanced Text Editor. Whatever text editor you pick, learn to use it and learn to use it well.
4. Invoking the Compiler
Commands invoking the compiler are rarely typed by hand, and are instead typically generated by the build system. However, knowing how to handle the compiler is essential if you’re going to do any kind of customization of the build process whatsoever, and it’s also useful for generating one-off binaries from single source files. Use the command gcc for C input, g++ for C++, and invoke as follows, following the arguments with a list of input files.
- -o
- Tell compiler where to place output. The following argument is taken to be the output filename.
- -g
- Tell the compiler to add debugging symbols, so the program can be debugged with GDB. When using this, don’t use -O.
- -O[0-3]
- Set the level of optimization. -O0 means do not optimize, and is the default.
- -fPIC
- Produce position-independent code; needed to produce shared libraries.
- -c
- Compile and assemble only; output will be object file.
- -S
- Compile only; output will be an assembly file.
- -pedantic
- Issue warnings demanded by ISO standard.
- -Wall
- Enable all warnings.
- -Werror
- Treat warnings as errors.
5. Invoking the Linker
The linker, can be invoked either with its own command "ld", or through
the compiler by providing object files as arguments. The compiler will
pass linker flags through to the linker. The following linker flags are
important for first-time users:
- -o
- Set output; works same as compiler.
- -L[directory]
- Add given directory to library search path.
- -l[library]
- Link against lib[library].so.
- -shared
- Produce a shared library.
6. A Simple Makefile
The sample makefile in Lugventure demonstrates some of the more common
tasks performed with makefiles. When using Make, it is a good strategy to
rely as much as possible on the builtin implicit rules, and only write
rules when necessary. When writing rules, it is possible to define them as
"pattern rules", so that they apply to multiple input types. A rule for
making shared objects out of C++ source might look like:
%.so: %.cpp
%(CXX) -fPIC -shared -o $@ $<
In this example %.so: %.cpp is a wildcard to build any .so from
its corresponding .cpp file, if the .cpp file exists. $(CXX) is
an expansion of variable "CXX"; set by default to the c++ compiler
command. $@ expands to the name of the output files, and
$< expands to the name of the input files.
7. Getting Started With the Debugger
The debugger is invoked by running gdb [path to program]. Once
GDB is running, the program itself can be started with run
[arguments]. Ctrl+C can be used at any time to pause program
execution, bringing you to a GDB prompt. Also, if an error or breakpoint
is encountered, you will be placed at a GDB prompt. The first thing
typically done when an error occurrs is running bt. This will
provide a stack trace, listing the chain of procedure calls that led to
the current state of affairs.
A level in the call stack can be selected
with the frame command, relevant code can be listed with
list, local variables can be listed with locals, and
arguments to the current function can be printed with args. Any
valid expression can be evaluated, using the most recent program values,
and printed with the print command. More info on any command
can be obtained by typing help [command].
8. Examining Object Files
A common error when working with multiple object files and libraries is
not being able to resolve a symbol that you can swear is in one of the
files you are linking again. This and many other reasons may prompt you to
want to investigate the contents of an object file. Among other things,
this is what readelf was designed for.
The basic command to list symbols in an object file is readelf -s
[filename]. Especially in C++ programs, the truncated lines this
produces may omit necessary information. To avoid truncating lines for
formatting, use readelf -s -W. When working with C++ programs, it
is also useful to be able to un-mangle the C++ symbol names.
c++filt, distributed with GCC, provides just this feature.
Running readelf -s -W [filename] | c++filt provides a list of all
symbols provided by a C++ object file in un-mangled C++.
9. Resources
- www.boost.org
- Boost home page.
- www.libsdl.org
- SDL home page.
- www.mega-nerd.com/libsndfile/
- libsndfile home page.
- man dlopen
- Manual for dynamic loader interface mentioned in presentation.
- man pthreads
- Manual for Posix Threads library.
- readelf --help
- Usage info for readelf. It does quite a bit more than just
list symbols. - c++filt --help
- Usage info for c++filt.
- Type "help" in GDB; it’s better than any of the existing print manuals,
and more to-the-point than most tutorials (once you know the basics). - gprof, another useful utility, not mentioned in the
presentation, is the GNU profiler. Google "gprof tutorial" to get
started with this.