絵のない技術書スマートフォン用の表示で見る絵のない技術書この広告は、90日以上更新していないブログに表示しています。目的C++やCなどコンパイラ型言語を使ってプログラミングをするときは、何度も何度もコンパイルを繰り返します。Linuxボード)を使ってプログラムを作成しているとします。プログラムをホストマシンで組み、クロスコンパイルして実行ファイルをRaspberryPiへと転送します。このとき、作業では次のコマンドを打ち込みます。user@192.168.7.2:/usr/bin/これだけを見ると「たったの2行?」と感じるかもしれませんが、コンパイルして実行するたびにこのコマンドを何度も何度も打ち込むのはとても大変で非効率的です。1回で160文字、10回繰り返すと1600文字、30回繰り返すと4800文字、これだけあれば、ソースコード100行分は優に超える文字数になります。この無駄な時間を減らすためにあるのが、今回のテーマmakeです。間違いを恐れずにmakeを大雑把にいうと、シェルスクリプトのコンパイル特化版です。大規模で分割されたプログラムなどで、必要なものだけコンパイルするため高速化を図れます。答えは次のコマンドが表していますね。makeを使った時に、先ほどと同じ操作をするために打つコマンドです。make「えっ?これだけ?」と思うかもしれません。makeを使うとこれだけで、コンパイルから転送までが済んでしまいます。あんな長ったらしいコマンドとはもうおさらばです。最初からmakeと打つだけでできるわけではありません。makeを使うためには、コンパイルの設定を書き込んだMakefileが必要になります。Makefileはその名の通りmakeのファイルで、コンパイラの情報からオプション・依存関係まで、様々なものを書き込んでおくのですが、これがなかなか慣れない書き方をしなければなりません。今回は、このMakefileを書いて作業の効率を上げる方法を解説していきます。方法では、ここからはMakefileの書き方です。準備まずは、makeをインストールしてください。make今回はArchLinuxでC++を使って解説しますが、LinuxならUbuntuでもFedoraでも基本的な操作は変わりません。次に、普段コンパイルに使用しているコマンドを用意してください。今回は先ほど上げた2行のコマンドとします。オプションなどについては別の回で解説します。書き方まずは、先に完成したMakefileです。$(DEPENDS)20行目までが、変数などの定義、22行目からがコンパイルなどの操作をしています。変数にはファイル名などを"="や":="などの演算子で代入することができます。変数を使用する際には$(変数名)のようにして使用します。変数の役割は以下の通りです。コンパイラの名前("$(CROSS)-g++"が代入される。コンパイル・リンクで生成されるファイル名DEPENDS変数を定義したら、それらを用いてコンパイルなどの操作を行います。操作のためには依存関係を記述します。書き方は以下のようになります。コマンドこのようなブロックのものを複数記述することができます。ターゲット名"のように指定すると、指定したターゲット名を持つブロックが実行されます。upload"を実行すると37行目"upload"ブロックが実行されます。ターゲット名について見ていきましょう。ターゲット名には、基本的にはそのブロックを実行すると生成されるファイル名を記述します。31行目"$(BIN_DIR)"はこのブロックを実行すると、"$(BIN_DIR)"を生成するということがわかります。"clean"などのように、生成するファイル名でないものをターゲット名にすることもできます。このとき"all"は先述のように特別な意味を持ちます。次に、依存ファイルについて見ていきましょう。ターゲット名のコロンを挟んだうしろにあるのが依存ファイルです。スペースつなぎで複数記述することができます。依存ファイル名の部分には、そのブロックを実行するために必要なファイル(依存ファイル)名を記述します。22行目"all"を見てみましょう。このブロックを実行するためには$(BIN_DIR)と$(TARGET)の2つが必要だということがわかります。makeはこの情報を元に、現在$(BIN_DIR)と$(TARGET)の2つがあるかどうかをチェックして、2つともある場合にはそのブロックを実行します。どちらか一方、もしくは両方がなかった場合はどのようになるのでしょうか?makeは依存ファイルが欠けているときは、そのファイルを生成してから現在のブロックを実行します。今回$(BIN_DIR)がなかったとすると、まずは$(BIN_DIR)を生成しようとします。この時に呼び出されるのが、不足ファイルと同じターゲット名を持つブロックです。今回は$(BIN_DIR)ブロックが該当します。これで、無事$(BIN_DIR)が生成されると、元のブロックに戻ってそのブロックを実行します。このようにして、makeは不足ファイルがあるとそのファイルを生成しながらブロックを実行していきます。これのようにしてmakeは動作していきます。流れでは、基本的な書き方を学んだところで、今回のMakefileの大まかな流れを見てみましょう。"make"を実行すると"all"ブロックに入ります。依存関係にある2つのファイルは生成されていないため、"$(BIN_DIR)"ブロックと"$(TARGET)"ブロックが呼び出されます。"$(TARGET)"ブロックでは$(OBJECTS)を依存ファイルとしているため、"$(OBJECTS)/%.o"ブロックが呼び出されます。"$(OBJECTS)/%.o"ブロックでは%.cppを依存ファイルとしていますが、このファイルはすでに作成しているプログラムファイルのため、依存関係が満たされてコマンドが実行されます。これにより、$(OBJECTS)が生成されるため、"$(TARGET)"ブロックが実行されます。これにより、$(TARGET)が生成されるため、"all"ブロックが実行されますが、コマンドがないためここで終了します。"$(OBJECTS/%.o"ブロックでコンパイル・リンクがされたため、実行ファイルが生成されました。これが、このMakefileのおおまかな流れです。おわりに軽いmakeについての説明をさせていただきましたが、いかがでしたでしょうか?わからないことなどがありましたら、ご質問だくさい。