• Aucun résultat trouvé

Single Source File to Executable

Dans le document For Mary (Page 129-138)

The following is the source code of a simple C++ program stored in a file named helloworld.cpp:

/* helloworld.cpp */

#include <iostream>

int main(int argc,char *argv[]) {

std::cout << "hello, world\n";

return(0);

}

This program usescout, defined in the header fileiostream, to write a simple string to the standard output. This program can be compiled into an executable with the following command:

$ g++ helloworld.cpp

The g++ compiler recognizes the file by the suffix on its name as being a C++ source file. The default action is to compile the source into an object file, link the object file with the necessary routines from the librarylibstdc++, and produce an executable program file. The object file is then deleted. No output file name was specified on the command line, so the default name a.out is used. The program can be run as follows:

$ a.out hello, world

It is more common to specify the name of the executable file with the-ocommand.

The following command will produce an executable namedhelloworld:

$ g++ helloworld.cpp -o helloworld

USINGTHECOMPILERCOLLECTION

Entering the program name on the command line will execute it:

$ helloworld hello, world

Theg++program is a special version ofgccthat sets the default language to C++, causing it to automatically link using the standard C++ library instead of defaulting to the standard C library. By following the source file naming convention and specifying the name of the library, it is possible to compile and link C++ programs usinggcc, as in the following example:

$ gcc helloworld.cpp -lstdc++ -o helloworld

The-l(ell) option alters the name following it by tacking on the prefixliband the suffix.a, making the library namedlibstdc++.a. It then looks for the library in the standard places. The compilation process and the output file fromgccis identical tog++.

On most systems, the installation of GCC installs a program namedc++. If installed, the program is identical withg++and can be used the same way, as in the following example:

$ c++ helloworld.cpp -o helloworld Suffix File Contains

.a Static object library (archive file).

.C, .c++, .cc, .cp, .cpp, .cxx

C++ source code that is to be preprocessed.

.h C or C++ header file.

.ii C++ source code that is not to be preprocessed. This type of file is produced as an intermediate step in compilation.

.o An object file in a format appropriate to be supplied to the linker.

This type of file is produced as an intermediate step in compilation.

.s Assembly language source code. This type of file is produced as an intermediate step in compilation.

<none> The standard C++ system header files have no suffix.

Table 5-1. File Name Suffixes in C++ Programming

Multiple Source Files to Executable

If more than one source file is listed on theg++command, they are all compiled and linked together into a single executable. The following is a header file, namedspeak.h, containing a class definition that contains only one function:

/* speak.h */

#include <iostream>

class Speak {

public:

void sayHello(const char *);

};

The following is a listing of the filespeak.cpp, which contains the body of the sayHello()function:

/* speak.cpp */

#include "speak.h"

void Speak::sayHello(const char *str) {

std::cout << "Hello " << str << "\n";

}

The filehellospeak.cppcontains a program that uses theSpeakclass:

/* hellospeak.cpp */

#include "speak.h"

int main(int argc,char *argv[]) {

Speak speak;

speak.sayHello("world");

return(0);

}

A single command can be used to compile and link both of these source files into a single executable:

$ g++ hellospeak.cpp speak.cpp -o hellospeak

USINGTHECOMPILERCOLLECTION

Source File to Object File

The-coption can be used to compile the source code but suppress the linker and output an object file instead. The default name is the same as the base name of the source file with the suffix changed to.o. For example, the following command will compile the source filehellospeak.cppand produce the object filehellospeak.o:

$ g++ -c hellospeak.cpp

Theg++command also recognizes the .o files as input files to be fed to the linker.

The following sequence of commands will compile the two source files into object files and then link the two object files into a single executable:

$ g++ -c hellospeak.cpp

$ g++ -c speak.cpp

$ g++ hellospeak.o speak.o -o hellospeak

The-ooption is not just for naming executables. It can also be used to name the other files output by the compiler. For example, the following series of commands produces the same executable as the previous series, except the intermediate object files have different names:

$ g++ -c hellospeak.cpp -o hspk1.o

$ g++ -c speak.cpp -o hspk2.o

$ g++ hspk1.o hspk2.o -o hellospeak

Preprocessing

Specifying the-Eoption instructsg++to pass the source code through the preprocessor and take no further action. The following command preprocesses thehelloworld.cpp source code and writes the results to standard output:

$ g++ -E helloworld.cpp

The source code forhelloworld.cpp, listed earlier in this chapter, is only six lines long and does nothing other than display a line of text, but the preprocessed version is over 1,200 lines long. This is largely because theiostreamheader file is included, and it includes several other header files as well as defines several large classes that deal with input and output.

The GCC suffix for preprocessed C++ code is.ii, which can be produced by using the-ooption, as follows:

$ gcc -E helloworld.cpp -o helloworld.ii

Generating Assembly Language

The-Soption instructs the compiler to compile the program into assembly language, output the assembly language source, and then stop. The following command produces the assembly language file named helloworld.s from the C++ source file:

$ g++ -S helloworld.cpp

The assembly language generated depends on the target platform of the compiler, but if you examine it, you will see not only the executable code and data storage declarations but also the tables of addresses necessary for inheritance and linkage in a C++ program.

Creating a Static Library

A static library is an archive file containing a collection of object files produced by the compiler. The members of the library can contain regular functions, class definitions, and objects that are instances of class definitions. Anything, in fact, that can be stored in a.oobject file can also be stored in a library.

The following example creates two object modules and uses them to create a static library. A header file contains the information necessary for a program to use the function, class definition, and object stored in the library.

The header filesay.hcontains the prototype of the functionsayHello()and the definition of a class namedSay:

/* say.h */

#include <iostream>

void sayhello(void);

class Say { private:

char *string;

public:

Say(char *str) {

string = str;

}

void sayThis(const char *str) {

USINGTHECOMPILERCOLLECTION std::cout << str << " from a static library\n";

}

void sayString(void);

};

The following source file is namedsay.cppand is the source of one of the two object files to be inserted into the library. It contains the definition of the body of the sayString()function of theSayclass. It also contains the declaration oflibrarysay, which is an instance of theSayclass:

/* say.cpp */

#include "say.h"

void Say::sayString() {

std::cout << string << "\n";

}

Say librarysay("Library instance of Say");

The source filesayhello.cppis the source code of the second module that is to be included in the library. It contains the definition of the functionsayhello(), which follows:

/* sayhello.cpp */

#include "say.h"

void sayhello() {

std::cout << "hello from a static library\n";

}

The following sequence of commands compiles the two source files into object files, and thearcommand stores them into a library:

$ g++ -c sayhello.cpp

$ g++ -c say.cpp

$ ar -r libsay.a sayhello.o say.o

Thearutility used with the-roption will create a new library namedlibsay.a and insert the listed object files into it. Used this way,arwill create a new library if one does not exist or, if the library does exist, it will replace any existing object modules with the new version.

The following is the mainline of a program namedsaymain.cppthat uses the code stored inlibsay.a:

/* saymain.cpp */

#include "say.h"

int main(int argc,char *argv[]) {

extern Say librarysay;

Say localsay = Say("Local instance of Say");

sayhello();

librarysay.sayThis("howdy");

librarysay.sayString();

localsay.sayString();

return(0);

}

This program is compiled and linked with the following command, whereg++

resolves any references made insaymain.cppby looking in the librarylibsay.a:

$ g++ saymain.cpp libsay.a -o saymain

The external reference tolibrarysayis a reference to the object declared insay.cppand stored in the library. Bothlibrarysay.sayThis()and librarysay.sayString()are calls to the methods of the object in the library.

Also,sayhello()is a call to the function insayhello.o, which is also stored in the library. When the program is run, it produces the following output:

hello from a static library howdy from a static library Library instance of Say Local instance of Say

Creating a Shared Library

A shared library is an archive that contains a collection of object files, but the object files must use relative addressing so the code can be loaded anywhere in memory and run from there without an extensive relocation process. This allows the code to be loaded from the shared library while the program is running instead of being directly attached to the executable by a linker.

The following header file, namedaverage.h, defines the class to be stored in the shared library:

USINGTHECOMPILERCOLLECTION

The source file to be compiled and stored in the shared library contains the bodies of the functions defined in the class:

/* average.cpp */

The following two commands first compile the source into an object file and then use it to create a library:

$ g++ -c -fpic average.cpp

$ gcc -shared average.o -o average.so

The first command uses the-coption so that the compiler will produce the object fileaverage.owithout trying to link it into an executable. The option-fpic(position independent code) instructs the compiler to produce code suitable for inclusion in a shared library—code that calculates its internal addresses in relation to the point the code is loaded into memory. The second command uses the-sharedoption to cause the creation of a shared library that, by being specified on the-ooption, is named average.so. The second command could just has well have beeng++in place ofgcc because there is nothing specific to C++ about creating a shared library. Creating a shared library containing more than one object module is simply a matter of listing all the object files on the same command line.

The two previous commands can be combined into a single command that compiles the source into object files and uses them to create a shared library:

$ g++ -fpic -shared average.cpp -o average.so

The following program uses the class definition stored in the shared library to instantiate an object that is used to keep a running total of four values and return their average:

/* showaverage.cpp */

#include <iostream>

#include "average.h"

int main(int argc,char *argv[]) {

Average avg;

avg.insertValue(30.2);

avg.insertValue(88.8);

avg.insertValue(3.002);

avg.insertValue(11.0);

std::cout << "Average=" << avg.getAverage() << "\n";

return(0);

}

The following command compiles and links the program with the shared library, producing an executable named showaverage:

$ g++ showaverage.cpp average.so -o showaverage

To run this program, the shared library must be installed in a directory that will be found at execution time, as described in Chapter 12.

Dans le document For Mary (Page 129-138)