序章


Linuxサーバーにソースコードからソフトウェアをインストールした経験がある場合は、おそらくmakeユーティリティに出くわしたことでしょう。 このツールは、主にプログラムのコンパイルと構築を自動化するために使用されます。 これにより、アプリケーションの作成者は、その特定のプロジェクトを構築するために必要な手順を簡単にレイアウトできます。

makeはソフトウェアのコンパイルを自動化するために作成されましたが、ツールは、コマンドラインから実行できるほとんどすべてのタスクを自動化するために使用できる十分な柔軟性を備えて設計されています。 このガイドでは、makeを再利用して、順番に発生する反復タスクを自動化する方法について説明します。

これはUbuntu12.04VPSでデモンストレーションしますが、ほとんどすべてのLinuxサーバーで同様に動作するはずです。

Makeをインストールします


makeを使い始める前に、それをインストールする必要があります。

名前でインストールできますが、通常、ソフトウェアのコンパイルに役立つ他のツールと一緒にインストールされます。 これらはすべて、一般的に非常に便利なので、すべてインストールします。 makeとこれらの他のプログラムを含む「build-essential」と呼ばれるパッケージがあります。

sudo apt-get update
sudo apt-get install build-essential

これで、通常の容量でもmakeを利用できるツールができました。

Makefileを理解する


makeコマンドが命令を受け取る主な方法は、Makefileを使用することです。

マニュアルページから、makeがGNUmakefileという名前のファイルを検索し、次にmakefile、次にMakefileを検索することがわかります。 GNUmakefileはGNU固有のコマンド用であり、makefileはそれほど目立たないため、Makefileを使用することをお勧めします。

Makefileはディレクトリ固有です。つまり、makeは、これらのファイルを見つけるために呼び出されたディレクトリを検索します。 そのため、実行するタスクのルート、または作成するスクリプトを呼び出すのが最も理にかなっている場所にMakefileを配置する必要があります。

Makefile内では、特定の形式に従います。 Makeは、ターゲット、ソース、およびコマンドの概念を次のように使用します。

target: source
    command

makeは扱いにくいため、これの配置と形式は非常に重要です。 ここでは、これらの各コンポーネントの形式と意味について説明します。

目標


ターゲットは、コマンドのグループを参照するためのユーザー指定の名前です。 プログラミング言語の単純な関数に似ていると考えてください。

ターゲットは左側の列に配置され、連続した単語(スペースなし)であり、コロン(:)で終わります。

makeを呼び出すときは、次のように入力してターゲットを指定できます。

target_nameを作成します

次に、MakeはMakefileをチェックし、そのターゲットに関連付けられたコマンドを実行します。

ソース


ソースは、ファイルまたは他のターゲットへの参照です。 これらは、関連付けられているターゲットの前提条件または依存関係を表します。

たとえば、次のようなmakeファイルのセクションを作成できます。

target1: target2
    target1_command

target2:
    target2_command

この例では、次のようにtarget1を呼び出すことができます。

make target1

次に、MakeはMakefileに移動し、「target1」ターゲットを検索します。 次に、指定されたソースがあるかどうかを確認します。

「target2」のソース依存関係を見つけて、一時的にそのターゲットにジャンプします。

そこから、target2にソースがリストされているかどうかを確認します。 そうではないので、「target2_command」の実行に進みます。 この時点で、makeは「target2」コマンドリストの最後に到達し、制御を「target1」ターゲットに戻します。 次に、「target1_command」を実行して終了します。

ソースは、ファイルまたはターゲット自体のいずれかです。 Makeは、ファイルのタイムスタンプを使用して、ファイルが最後の呼び出し以降に変更されているかどうかを確認します。 ソースファイルに変更が加えられた場合、そのターゲットが再実行されます。 それ以外の場合は、依存関係が満たされているとマークされ、次のソース、またはそれが唯一のソースである場合はコマンドに進みます。

一般的な考え方は、ソースを追加することで、現在のターゲットの前に実行する必要のある依存関係のシーケンシャルセットを構築できるというものです。 ターゲットの後に、スペースで区切って複数のソースを指定できます。 手の込んだ一連のタスクを指定する方法を理解し始めることができます。

コマンド


makeコマンドにこのような柔軟性を与えるのは、構文のコマンド部分が非常にオープンであるということです。 ターゲットの下で実行したい任意のコマンドを指定できます。 コマンドはいくつでも追加できます。

コマンドは、ターゲット宣言の後の行で指定されます。 それらは1つのtab文字でインデントされます。 makeの一部のバージョンは、コマンドセクションをインデントする方法に柔軟性がありますが、一般に、makeが意図を認識できるように、単一のタブを使用する必要があります。

Makeは、ターゲット定義の下にあるすべてのインデントされた行を個別のコマンドと見なします。 インデントされた行とコマンドは、いくつでも追加できます。 Makeはそれらを一度に1つずつ通過します。

コマンドの前に配置して、makeにそれらを異なる方法で処理するように指示できるものがいくつかあります。

  • :コマンドの前のダッシュは、エラーが発生した場合にnotを中止するようにmakeに指示します。 たとえば、ファイルが存在する場合はコマンドを実行し、存在しない場合は何もしない場合に便利です。

  • @ :「@」記号を使用してコマンドをリードすると、コマンド呼び出し自体は標準出力に出力されません。 これは主に、makeが生成する出力をクリーンアップするためだけに使用されます。

追加機能


いくつかの追加機能は、Makefileでより複雑なルールチェーンを作成するのに役立ちます。

変数


Makeは、makefileで置換するための単純なプレースホルダーとして動作する変数(またはマクロ)を認識します。 これらはファイルの先頭で宣言するのが最善です。

各変数の名前は完全に大文字になっています。 名前に続いて、等号が右側の値に名前を割り当てます。 たとえば、インストールディレクトリを/usr/binとして定義する場合は、ファイルの先頭に次のように追加できます。

INSTALLDIR=/usr/bin

ファイルの後半で、次の構文を使用してこの場所を参照できます。

$(INSTALLDIR)

改行をエスケープする


私たちができるもう1つの便利なことは、コマンドが複数の行にまたがることを許可することです。

コマンドセクション内で任意のコマンドまたはシェル機能を使用できます。 これには、行を「」で終了して改行文字をエスケープすることが含まれます。

target: source
    command1 arg1 arg2 arg3 arg4 \
    arg5 arg6

if-thenステートメントなど、シェルのよりプログラム的な機能のいくつかを利用する場合、これはより重要になります。

target: source
    if [ "condition_1" == "condition_2" ];\
    then\
        command to execute;\
        another command;\
    else\
        alternative command;\
    fi

これにより、このブロックが1行のコマンドであるかのように実行されます。 実際、これを1行で書くこともできますが、このように分解すると読みやすさが大幅に向上します。

行末文字をエスケープする場合は、「」の後に余分なスペースやタブがないことを確認してください。そうしないと、エラーが発生します。

ファイルサフィックスルール


ファイル処理を行う場合に使用できる追加機能は、ファイルのサフィックスです。 これらは、拡張子に基づいてファイルを処理する方法を提供する一般的なルールです。

たとえば、ディレクトリ内のすべての.jpgファイルを処理し、ImageMagickスイートを使用してそれらを.pngファイルに変換する場合、Makefileに次のようなものを含めることができます。

.SUFFIXES: .jpg .png

.jpg.png:
    @echo converting $< to [email protected]
    convert $< [email protected]

ここで確認する必要があることがいくつかあります。

最初の部分は.SUFFIXES:宣言です。 これは、ファイルのサフィックスで使用するすべてのサフィックスについてmakeに通知します。 「.c」ファイルや「.o」ファイルなど、ソースコードのコンパイルで頻繁に使用されるいくつかのサフィックスは、デフォルトで含まれているため、この宣言でラベル付けする必要はありません。

次の部分は、実際のサフィックスルールの宣言です。 これは基本的に次の形式を取ります。

 original_extensiontarget_extension

これは実際のターゲットではありませんが、2番目の拡張子を持つファイルの呼び出しと一致し、最初の拡張子のファイルからそれらを構築します。

この場合、ディレクトリに「file.jpg」がある場合は、次のようにmakeを呼び出して、「file.png」というファイルを作成できます。

make file.png

Makeは、.SUFFIXES宣言でpngファイルを確認し、「。png」ファイルを作成するためのルールを確認します。 次に、ディレクトリ内で「.png」が「.jpg」に置き換えられたターゲットファイルを検索します。 その後、次のコマンドを実行します。

サフィックスルールは、まだ導入されていないいくつかの変数を使用します。 これらは、プロセスの現在の部分に基づいて、さまざまな情報を置き換えるのに役立ちます。

  • $?:この変数には、ターゲットよりも新しい現在のターゲットの依存関係のリストが含まれています。 これらは、このターゲットの下でコマンドを実行する前に再実行する必要があるターゲットになります。

  • $ @ :この変数は現在のターゲットの名前です。 これにより、このルールがパターンによって一致した場合でも、作成しようとしているファイルを参照できます。

  • $ < :これは現在の依存関係の名前です。 サフィックスルールの場合、これはターゲットの作成に使用されるファイルの名前です。 この例では、これには「file.jpg」が含まれます。

  • $ * :このファイルは、一致する拡張子が削除された現在の依存関係の名前です。 これは、ターゲットファイルとソースファイルの間の中間段階であると考えてください。

変換メイクファイルを作成する


画像操作を行うMakefileを作成し、ファイルをファイルサーバーにアップロードして、Webサイトで表示できるようにします。

フォローしたい場合は、始める前に、ImageMagick変換ツールをダウンロードしてください。 これらは画像を操作するための簡単なコマンドラインツールであり、スクリプトでそれらを利用します。

sudo apt-get update
sudo apt-get install imagemagick

現在のディレクトリに、Makefileというファイルを作成します。

nano Makefile

このファイル内で、コンバージョンターゲットの実装を開始します。

すべてのJPGファイルをPNGに変換する


私たちのサーバーは、.png画像のみを提供するように設定されています。 このため、アップロードする前に.jpgファイルを.pngに変換する必要があります。

上で学んだように、サフィックスルールはこれを行うための優れた方法です。 まず、.SUFFIX宣言から始めます。この宣言には、変換する形式がリストされています。

.SUFFIXES: .jpg .png

その後、.jpgファイルを.pngファイルに変更するルールを作成できます。 これは、ImageMagickスイートのconvertコマンドを使用して実行できます。 convertコマンドは単純で、その構文は次のとおりです。

from_fileから_fileに変換

このコマンドを実装するには、開始する形式と終了する形式を指定するサフィックスルールが必要です。

.SUFFIXES: .jpg .png

.jpg.png:           ## This is the suffix rule declaration

一致するルールができたので、実際の変換ステップを実装する必要があります。

ここではどのファイル名が一致するか正確にはわからないため、学習した変数を使用する必要があります。 具体的には、元のファイルとして$<を参照し、変換先のファイルとして[email protected]を参照する必要があります。 これをconvertコマンドについて知っていることと組み合わせると、次のルールが得られます。

.SUFFIXES: .jpg .png

.jpg.png:
    convert $< [email protected]

echoステートメントで何が起こっているのかを明示的に伝えることができるように、いくつかの機能を追加しましょう。 新しいコマンドの前に「@」記号を含め、実行時に実際のコマンドが出力されないようにするために、すでに持っているコマンドを含めます。

.SUFFIXES:.jpg .png

.jpg.png: @エコー ImageMagickを使用して$<を[email protected]に変換… @変換 $ <$ @ @エコー $ @への変換に成功しました!