This handout continues with a summary of the commands you will use
when compiling C++ programs on a Linux system. For further
information on each of these, consult the corresponding man
page (for example, do man g++
). Many of the utilities come
from the GNU project, which doesn't like to maintain man
pages,
so frequently there will be more information in the info
system
(do info g++
, for example).
g++
. If you just have a single source
file, for example myprog.cc
, then you may compile and link it
in one step with the command
g++ myprog.cc -o myprogIf there are no errors, this will produce an executable named
myprog
in the current directory. To run it, type
./myprog(the
./
prefix tells the command shell where to find the
program, since by default it may not look in the current
directory for programs).
If your program consists of several source files, you will need to
compile each of them into an object file and then link them
together into an executable. For example, suppose that
myprog2.cc
uses a class that is implemented in myclass.cc
(there should also be an interface in myclass.h
, but the
#include
line in myprog.cc
handles that; by the way,
most facilities from the Standard Library will be automatically linked
with your program, so the #include
is all that you need to use
them). You will use g++
, with the -c
(for ``compile'')
option, once on each source file to produce the object files, which
have a .o
extension:
g++ -c myprog2.cc g++ -c myclass.ccThen the object files need to be linked together with the command
g++ myprog2.o myclass.o -o myprog2This process is considerably simplified by writing a make file (see below).
There are many options you may supply to g++
; see the
documentation for a list (with full descriptions in the info
viewer). Some of the most common are -Wall
, which tells the
compiler to print all of the warnings of possibly incorrect code that
it finds, -g
, which causes the compiler to insert debugging
information in the compiled code (for use with gdb
), and
-O
, which turns on some of the code optimizations (unlike some
compilers, g++
allows -O
to be used with -g
,
although optimized code might do some unexpected things while
debugging). For example, the file myprog.cc
could be compiled
with warnings and debugging information by executing
g++ -Wall -g myprog.cc -o myprog
make
command takes this file and executes all of
the required steps to bring the project up to date.
Here is a simple make file, which should be stored in the project
directory under the name Makefile
:
# Make file for myprog2 myprog2 : myprog2.o myclass.o g++ myprog2.o myclass.o -o myprog2 myprog2.o : myprog2.cc myclass.h g++ -c myprog2.cc myclass.o : myclass.cc myclass.h g++ -c myclass.cc
The first line is a comment; make
ignores any line that starts
with #
. The next two lines describe how to make the full
program (make
will use the first such entry in the make file as
the default target to be made, so it is a good idea to put the
entry to link your program first). The line with the colon describes
the conditions under which the rule will be applied. It says that the
file myprog2
depends on the files myprog2.o
and
myclass.o
; if myprog2
doesn't exist, or is older than
either of the .o
files, then the body of the rule will be used
to produce an up-to-date version of myprog2
. The body of the
rule, the line with g++
, gives the command to execute.
It is important to note that this line starts with a TAB
character; it will not work if the line starts with spaces.
The following entries describe how to produce the .o
files, if
they don't exist or are out-of-date. As before, the line with the
colon describes the dependencies of each file: myprog2.o
depends on both myprog2.cc
and myclass.h
, so it will
need to be recompiled if either of those files has been changed. In
general, the list of dependencies for an object file will be the
corresponding source file plus all of the (non-standard) header files
that it includes. There is a tool called makedepend
which will
automate the process of generating these dependency lists; see
man makedepend
.
Instead of creating a make file such as the above from scratch for each project, it is a good idea to start with a make file template and customize it. Here is a simple example:
# Makefile template # # Fill in the definitions of the variables: # SRCS = a list of your .cc files # HDRS = a list of your .h files # PROG = the name of the executable you are making # # Then execute "make depend" followed by "make" # # Use "make print" to send nicely formatted listings to the Linux lab printer # Use "make clean" to remove the executable and other files generated by make SRCS = myprog2.cc myclass.cc HDRS = myclass.h PROG = myprog # You should not need to change anything below this line. OBJS = $(SRCS:.cc=.o) CXX = g++ CXXFLAGS = -Wall -g -I/home/libs/dataStr/ftsoftds/include LIBS = -L/home/libs/dataStr/ftsoftds/lib -lezdraw -L/usr/X11R6/lib -lXaw -lXmu -lXt -lX11 DEPFILE = .depends PRINTER = JSC276 all : $(PROG) $(PROG) : $(OBJS) $(CXX) $(CXXFLAGS) $(OBJS) -o $(PROG) $(LIBS) depend : $(CXX) $(CXXFLAGS) -MM $(SRCS) > $(DEPFILE) print : a2ps -A virtual $(HDRS) $(SRCS) | lpr -P $(PRINTER) clean : rm -f $(PROG) $(OBJS) $(DEPFILE) core sinclude $(DEPFILE)When you execute
make depend
, it will compute a series of rules (stored in
the hidden file .depends
) which will be included in
the make file which cover building the object files from the
sources, taking into account any header file dependencies. I also
included targets print
and clean
in this example; doing
make print
will send a nicely formatted listing of your source
programs to the laser printer in 276, while make clean
will
remove all of the files that may have been generated in previous
compiles, so that you can do a clean compile of all of the parts of
the program (or so you can reduce disk usage when you no longer need
to run the program).