コンパイル
単純な「helloworld」アプリケーションを作成するとします。3つのファイルがhello.cpp
hello-writer.cpp
ありhello-writer.h
、その内容は
// hello-writer.h
void WriteHello(void);
// hello-writer.cpp
#include "hello-writer.h"
#include <stdio>
void WriteHello(void){
std::cout<<"Hello World"<<std::endl;
}
// hello.cpp
#include "hello-writer.h"
int main(int argc, char ** argv){
WriteHello();
}
g++
* .cppファイルは、コマンドを使用して、によってオブジェクトファイルに変換されます。
g++ -c hello.cpp -o hello.o
g++ -c hello-writer.cpp -o hello-writer.o
フラグは今の-c
ところリンクをスキップします。すべてのモジュールをリンクするには、を実行する必要があります
g++ hello.o hello-writer.o -o hello
プログラムの作成hello
。外部ライブラリにリンクする必要がある場合は、たとえば-lm
数学ライブラリの場合など、これらをこの行に追加します。libm.a
実際のライブラリファイルはまたはのようlibm.so
になります。リンカーフラグを追加するときに、ファイル名のサフィックスと「lib」部分を無視します。
Makefile
ビルドプロセスを自動化するには、一連のルールで構成されるmakefileを使用し、作成するものとそれを作成するために必要なファイルをリストします。たとえば、にhello.o
依存しhello.cpp
、hello-writer.h
そのルールは
hello.o:hello.cpp hello-writer.h
g++ -c hello.cpp -o hello.o # This line must begin with a tab.
makeマニュアルを読みたい場合は、変数と自動ルールを使用して物事を単純化する方法を説明しています。あなたはただ書くことができるはずです
hello.o:hello.cpp hello-writer.h
ルールは自動的に作成されます。helloの例の完全なmakefileは次のとおりです。
all:hello
hello:hello.o hello-writer.o
g++ hello.o hello-writer.o -o hello
hello.o:hello.cpp hello-writer.h
g++ -c hello.cpp -o hello.o
hello-writer.o:hello-writer.cpp hello-writer.h
g++ -c hello-writer.cpp -o hello-writer.o
インデントされた行はタブで始まる必要があることに注意してください。すべてのルールに実際のファイルが必要なわけではありません。all
ターゲットは「作成」とだけ言っていますhello
。これがmakefileの最初のルールであり、実行時に最初のルールが自動的に作成されるのが一般的ですmake
。
このすべての設定により、コマンドラインに移動して実行できるようになります。
$ make
$ ./hello
Hello World
より高度なMakefileのもの
makefileで定義できる便利な変数もいくつかあります。
- CXX:c++コンパイラ
- CXXFLAGS:コンパイラに渡す追加のフラグ(例:-Iを含むディレクトリを含める)
- LDFLAGS:リンカーに渡す追加のフラグ
- LDLIBS:リンクするライブラリ
- CC:cコンパイラ(リンクにも使用)
- CPPFLAGS:プリプロセッサフラグ
を使用して変数を定義し、を使用=
して変数に追加します+=
。
.cppファイルを.oファイルに変換するデフォルトのルールは次のとおりです。
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $< -o $@
ここ$<
で、は最初の依存関係で$@
あり、は出力ファイルです。変数はで囲むことによって展開されます$()
。このルールはパターンで実行されますhello.o:hello.cpp
同様に、デフォルトのリンカールールは
$(CC) $(LDFLAGS) $^ -o $@ $(LDLIBS)
ここ$^
で、すべての前提条件があります。このルールは、パターンで実行されますhello:hello.o hello-writer.o
。このルールをオーバーライドせずにc++を使用している場合は、cコンパイラを使用することに注意して-lstdc++
くださいLDLIBS
。
LDLIBS+=-lstdc++
makefileで。
最後に、ファイルの依存関係をリストしない場合、.o
makeはそれ自体を見つけることができるため、最小限のmakefileは次のようになります。
LDFLAGS=-lstdc++
all:hello
hello:hello.o hello-writer.o
これは、上の2つのファイルの依存関係を無視するhello-writer.h
ため、ヘッダーが変更された場合、プログラムは再構築されないことに注意してください。興味がある場合は、-MD
この依存関係を自動的に生成する方法について、gccドキュメントのフラグを確認してください。
最終的なmakefile
妥当な最終メイクファイルは次のようになります
// Makefile
CC=gcc
CXX=g++
CXXFLAGS+=-Wall -Wextra -Werror
CXXFLAGS+=-Ipath/to/headers
LDLIBS+=-lstdc++ # You could instead use CC = $(CXX) for the same effect
# (watch out for c code though!)
all:hello # default target
hello:hello.o hello-world.o # linker
hello.o:hello.cpp hello-world.h # compile a module
hello-world.o:hello-world.cpp hello-world.h # compile another module
$(CXX) $(CXXFLAGS) -c $< -o $@ # command to run (same as the default rule)
# expands to g++ -Wall ... -c hello-world.cpp -o hello-world.o