Copiling Cpp

15323 ワード

自動回転http://wiki.ubuntu.org.cn/index.php?title=Compiling_Cpp&variant=zh-hans
C++プログラミング中の関連ファイルの拡張子
a.
スタティックライブラリ(archive)
C.c.cc.cp.cpp.cxx.c++
C++ソースコード(コンパイル前処理が必要)
h.h
CまたはC++ソースコードヘッダファイル
.ii
C++ソースコード(コンパイル前処理不要)
.o
オブジェクトファイル
.s
アセンブリ言語コード
.そして
ダイナミックライブラリ
<none>
標準C++システムヘッダファイル
[編集]単一ソースファイル生成実行可能プログラム
以下はファイルhellowworld.cppに保存する簡単なC++プログラムのコードです。
/* helloworld.cpp */
#include <iostream>
int main(int argc,char *argv[])
{
    std::cout << "hello, world" << std::endl;
    return(0);
}
プログラムはヘッダファイルiostreamに定義されたcoutを使って、シンプルな文字列を標準出力に書き込みます。コードは以下のコマンドで実行可能ファイルにコンパイルできます。
$ g++ helloworld.cpp
コンパイラg++は、コマンドラインで指定されたファイルの拡張子名を確認することにより、C++ソースコードファイルとして認識することができます。コンパイラのデフォルトの動作:ソースコードファイルをコンパイルしてオブジェクトファイルを生成し、リンク先ファイルとlibstdc++ライブラリの関数を使って実行可能なプログラムを得る。その後、オブジェクトファイルを削除します。コマンドラインに実行可能なプログラムのファイル名が指定されていませんので、コンパイラは標準のa.outを使用します。プログラムはこのように実行できます。
$ ./a.out
hello, world
より一般的なやり方は-oオプションで実行可能プログラムのファイル名を指定します。以下のコマンドは、ハロルドという実行可能ファイルを生成します。
$ g++ helloworld.cpp -o helloworld
コマンドラインにプログラム名を入力して実行させます。
$ ./helloworld
hello, world
プログラムg++は、gccのデフォルト言語をC++の特殊バージョンとして設定し、リンクする時はC++標準ライブラリを自動的に使用します。ソースコードの命名規範に従って対応ライブラリの名前を指定し、リンクC++プログラムをgccでコンパイルすることができます。
$ gcc helloworld.cpp -lstdc++ -o helloworld
オプション-l(ell)は、プレフィックスlibとサフィックスを追加することにより、aはそれに従う名前をライブラリの名前libstdc+++aに変換します。その後、それは標準ライブラリのパスでライブラリを検索します。gccのコンパイルプロセスと出力ファイルはg++と全く同じです。
ほとんどのシステムでは、GCCインストール時にc++というプログラムがインストールされます。インストールされている場合は、g++と同じです。
$ c++ helloworld.cpp -o helloworld
[編集]複数のソースファイル生成実行可能プログラム
複数のソースファイルがg++コマンドで指定されている場合、それらはコンパイルされ、実行可能なファイルにリンクされます。次はspeak.hというヘッダファイルです。これは一つの関数だけを含むクラスの定義を含みます。
/* speak.h */
#include <iostream>
class Speak
{
    public:
        void sayHello(const char *);
};
以下のリストはファイルのspeak.cppの内容です。sayHello()関数を含む関数です。
/* speak.cpp */
#include "speak.h"
void Speak::sayHello(const char *str)
{
    std::cout << "Hello " << str << "
"
; }
ファイルhello speak.cpp内はSpeak類を使用するプログラムです。
/* hellospeak.cpp */
#include "speak.h"
int main(int argc,char *argv[])
{
    Speak speak;
    speak.sayHello("world");
    return(0);
}
次のコマンドは上記二つのソースファイルを単一の実行可能なプログラムにコンパイルします。
$ g++ hellospeak.cpp speak.cpp -o hellospeak
PS:ここではなぜ命令で「speak.h」とは言わなかったのですか?このファイルは「speak.cpp」の中に含まれています。
[編集]ソースファイル生成対象ファイル
オプション-cは、コンパイラにソースコードをコンパイルするように伝えますが、リンクを実行しないでください。出力結果は対象ファイルです。ファイルのデフォルト名はソースファイル名と同じです。接尾番号を.oに変更します。たとえば、下記のコマンドは、ソースファイルのhellopeak.cppをコンパイルし、対象ファイルのハローspeak.o.oを生成します。
$ g++ -c hellospeak.cpp
  
コマンドg++も識別できます。oファイルは入力ファイルとしてリンク器に伝えられます。下記のコマンドはソースファイルを対象としてコンパイルし、単一の実行可能プログラムにリンクします。
$ g++ -c hellospeak.cpp 
$ g++ -c speak.cpp 
$ g++ hellospeak.o speak.o -o hellospeak
オプション-oは実行可能ファイルの名前だけではなく、コンパイラが出力する他のファイルの名前も付けられます。例えば、中間のオブジェクトファイルに名前が異なる場合を除き、下記のコマンドは上記と全く同じ実行可能ファイルを生成します。
$ g++ -c hellospeak.cpp -o hspk1.o 
$ g++ -c speak.cpp -o hspk2.o 
$ g++ hspk1.o hspk2.o -o hellospeak
[編集]プリプロセッサをコンパイルする
オプション-Eは、g++ソースコードをコンパイルしてプリプロセッサを処理した後、他の動作を実行しません。以下のコマンドは、ソースファイルのhellowworld.cppを前処理し、結果を標準出力に表示します。
$ g++ -E helloworld.cpp
本文の前に挙げたhellowworld.cppのソースコードは六行だけで、しかもこのプログラムは一行の文字以外は何もしないと表示していますが、前処理後のバージョンは1200行を超えます。これは主に頭ファイルiostreamが含まれています。また他のヘッダファイルが含まれています。この他に、いくつかの処理入力と出力の種類の定義があります。。
前処理されたファイルのGCCサフィックスは.iiであり、これは-oオプションによって生成され得る。例えば:
$ gcc -E helloworld.cpp -o helloworld.ii
[編集]アセンブラコードを生成する
オプション-S指示コンパイラはプログラムをアセンブリ言語にコンパイルし、アセンブリ言語コードを出力して終了します。以下のコマンドはC+ソースファイルからアセンブリ言語ファイルhellowworld.sを生成します。
$ g++ -S helloworld.cpp
生成されたアセンブリ言語はコンパイラのターゲットプラットフォームに依存します。
[編集]スタティックライブラリの作成
スタティックライブラリはコンパイラによって生成された一連のオブジェクトファイルの集合です。一つのプログラムをリンクするときはライブラリのオブジェクトファイルとディレクトリのオブジェクトファイルとが同じです。ライブラリのメンバーは一般関数、クラス定義、クラスのオブジェクトインスタンスなどを含みます。スタティックライブラリのもう一つの名前はアーカイブファイル(archive)といいます。このようなアーカイブファイルを管理するツールはarといいます。
以下の例では、まず2つのオブジェクトモジュールを作成し、その後、静的ライブラリを生成します。
ヘッダファイルsay.hは、関数sayHello()のプロトタイプと種類Sayの定義を含む:
/* say.h */
#include <iostream>
void sayhello(void);
class Say {
    private:
        char *string;
    public:
        Say(char *str)
        {
            string = str;
        }
        void sayThis(const char *str)
        {
            std::cout << str << " from a static library
"
; } void sayString(void); };
以下はファイルsay.cppです。私たちがスタティックライブラリに参加する2つのオブジェクトファイルの一つのソースコードです。これはSay種類のsayString関数の定義体を含みます。種類Sayの一例のLibraryの声明も含まれます。
/* say.cpp */
#include "say.h"
void Say::sayString()
{
    std::cout << string << "
"
; }   Say librarysay("Library instance of Say");
ソースファイルsayhello.cppは私たちがスタティックライブラリに参加する第二のオブジェクトファイルのソースコードです。関数sayhello()の定義を含みます。
/* sayhello.cpp */
#include "say.h"
void sayhello()
{
    std::cout << "hello from a static library
"
; }
下の命令手順はソースファイルを対象ファイルにコンパイルし、arに命令して倉庫に保存します。
$ g++ -c sayhello.cpp
$ g++ -c say.cpp
$ ar -r libsay.a sayhello.o say.o
プログラムar配合パラメータ-rは、新しいライブラリlibsay.aを作成し、コマンドラインにリストされているオブジェクトファイルを挿入します。この方法では、ライブラリが存在しない場合、パラメータ-rは新しいライブラリを作成します。ライブラリが存在する場合は、新しいモジュールを元のモジュールに置き換えます。
以下はメインプログラムsaymail.cppで、ライブラリlibsay.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);
}
このプログラムは下記のコマンドでコンパイルとリンクができます。
$ g++ saymain.cpp libsay.a -o saymain
プログラムを実行すると、以下の出力が発生します。
hello from a static library
howdy from a static library
Library instance of Say
Local instance of Say