[Linux 開発 - Makefile ツール]

Linux 開発 - Makefile ツールの使用

1. 背景

  • 通常、プロジェクトには複数のソース ファイルが含まれており、そのうちの 1 つだけを変更した場合、すべてのソース ファイルを再コンパイルしてリンクするのは時間の無駄です。したがって、Makefile ツールを導入することが非常に必要です。Makefile ツールは、ファイルの依存関係に基づいて再コンパイルおよびリンクする必要があるソース ファイルを自動的に検出し、それらに対して対応するアクションを実行します。

2、理解すること

1,make与makefile

  • Makefile は、どのファイルを最初にコンパイルする必要があるか、どのファイルを後でコンパイルする必要があるか、どのファイルを再コンパイルする必要があるかを指定する一連のルールを定義します。また、Makefile はシェル スクリプトのようなものであるため、さらに複雑な関数操作も定義します。オペレーティング システムのコマンドを実行する必要があります。
  • Make ツールの最も重要かつ基本的な機能は、Makefile ファイルを通じてソース プログラム間の関係を記述し、コンパイル作業を自動的に維持することです
  • Makefile ファイルは、特定の構文に従って記述する必要があり、各ソース ファイルをコンパイルして接続して実行可能ファイルを生成する方法を説明し、ソース ファイル間の依存関係を定義する必要があります。
  • Makefile ファイルは、Windows 上のコンパイラを含む多くのコンパイラでコンパイル情報を維持するために使用される一般的な方法です。統合開発環境では、ユーザーは使いやすいインターフェイスを通じてのみ Makefile ファイルを変更します。
  • UNIX システムでは、Makefile ファイルとして Makefile を使用するのが一般的です。別のファイルをメイクファイルとして使用する場合は、同様の make コマンド オプションを使用してメイクファイルを指定できます。
  • プログラムのコンパイルとリンクの方法をプログラムに指示するファイル。Makefile のデフォルト名は文字通り Makefile ですが、コマンド ライン オプション名を指定することもできます。
  • make プログラムは、大規模なプログラムを開発するときに、プログラム全体、変更された部分、および最後にコンパイルされてからコンパイルされたプログラムの部分のみを追跡するのに役立ちます。

2. コンパイルについて

小さな C プログラムをコンパイルするには、少なくとも 1 つのファイル .h ファイルが必要です (該当する場合)。このタスクを実行するコマンドは単に CC file.c ですが、最終的な実行可能プログラムを取得するには次の 3 つの手順があります。

  • コンパイル段階: .c ファイル内のすべての C 言語コードが低レベルのアセンブリ言語に変換され、.s ファイルが作成されます。

  • アセンブリ段階: 前段階で作成されたアセンブリ言語コードは、コンピューターが直接理解できるターゲット コード コード フラグメントに変換されます。オブジェクト コード ファイル .o が終了します。

  • リンク フェーズ: コンパイル プロセスの最終フェーズでは、オブジェクト コードをコード ベースにリンクします。コード ベースには、printf などの特定の「組み込み」関数が含まれています。この段階では、デフォルトで a.out という名前の実行可能プログラムが生成されます。

3. コンパイルの場合:

以下のソースファイルを想定します。

main.cpp
hello.cpp
factorial.cpp
functions.h
  • main.cpp ファイルの内容
#include <iostream.h>

#include "functions.h"

int main(){
    
    
    print_hello();
    cout << endl;
    cout << "The factorial of 5 is " << factorial(5) << endl;
    return 0;
}
  • hello.cpp ファイルの内容
#include <iostream.h>

#include "functions.h"

void print_hello(){
    
    
   cout << "Hello World!";
}
  • Factorial.cpp ファイルの内容
#include "functions.h"

int factorial(int n){
    
    
    if(n!=1){
    
    
	return(n * factorial(n-1));
    }
    else return 1;
}
  • function.h の内容
void print_hello();
int factorial(int n);

次のコマンドを実行して、ファイルをコンパイルして実行可能ファイルを取得する簡単な方法:

CC  main.cpp hello.cpp factorial.cpp -o hello
  • CC: コンパイラ (gcc) を表し、C++ ファイルをコンパイルします。
  • 上記のコマンドはバイナリの Hello を生成します。私たちの場合、ファイルは 4 つしかなく、関数呼び出しのシーケンスはわかっているので、上記のコマンドを手動で記述して最終バイナリを準備することも可能かもしれません。しかし、何千ものソース コード ファイルがある大規模なプロジェクトの場合、バイナリ バージョンを維持するのは困難になります。
  • make コマンドを使用すると、大規模なプログラムまたはプログラムのグループを管理できますより大きなプログラムを書き始めると、より大きなプログラムの再コンパイルの方が、短いプログラムの再コンパイルよりも時間がかかることがわかります。また、通常はプログラムのごく一部 (デバッグ中の単一関数など) のみが検出され、プログラムの残りの部分は変更されません。

3. メイクファイルマクロ

make プログラムでは、変数に似たマクロを使用できます。= Makefile で定義された 1 組のマクロ。例えば:

MACROS=  -me
PSROFF=  groff -Tps
DITROFF= groff -Tdvi
CFLAGS= -O -systype bsd43
LIBS := "-lncurses -lm -lsdl"
LIBS += -lstdc++
MYFACE = ":*)"
PROJ_HOME = /home/moon/projects
$(MACROS)
$(MYFACE) :*)

1. 特殊マクロ ( $@$?$<$*$^)

1、$@$?

ターゲット ルールセットにコマンドを発行する前に、いくつかの特別な事前定義マクロがあります。
- は$@対象ファイルを表します。- ターゲットよりも新しい依存ファイルのリストを
示します$?

したがって、たとえば、次のようなルールを使用できます。

hello: main.cpp hello.cpp factorial.cpp
	$(CC) $(CFLAGS) $? $(LDFLAGS) -o $@

alternatively:

hello: main.cpp hello.cpp factorial.cpp
        $(CC) $(CFLAGS) $@.cpp $(LDFLAGS) -o $@
  • この例では、$@ は hello、?、?、または?または@.cpp は、変更されたすべてのソース ファイルを取得します。

2 $<、、、$*

暗黙的なルールで使用される特別なマクロが 2 つあります。彼らです:

  • $<最初の依存ファイルを表します
  • $*この変数は、ターゲット パターン内の「%」とその前の部分を表します。ファイル .oと同等のファイル%.o
    • $*ターゲットが「dir/a.foo.b」で、ターゲットのモードが「a.%.b」の場合、$*」の値は「dir/a.foo」になります。この変数は、関連するファイル名を作成するのに役立ちます。ターゲットにパターン定義が存在しない場合、「$*」は推定できませんが、make でターゲットファイルのサフィックスが認識されている場合、「$*」はサフィックスを除いた部分になります。例: ターゲットが "foo.c" の場合、".c" は make によって認識されるサフィックス名であるため、$*" " の値は "foo" になります。したがって、暗黙的なルールまたは静的モードでない限り、这个特性是GNU make的,很有可能不兼容于其它版本的make「」の使用を避けるようにしてください。$*ターゲット内のサフィックスが make によって認識されない場合、「$*」は null 値になります。
      共通の暗黙的なルールは、.o (オブジェクト) ファイル、.cpp (ソース ファイル) に対して構築されます。
.o:.cpp
        $(CC) $(CFLAGS) -c $<

alternatively

.o:.cpp
        $(CC) $(CFLAGS) -c $*.cpp

3、$^

$^すべての依存関係を表示します。

LDFLAGS = -lstdc++
hello:main.o factorial.o hello.o
	$(CC) $^ $(LDFLAGS ) -o $@

2. 従来のマクロ

デフォルトのマクロが多数あります (「make -p」と入力するとデフォルトが出力されます)。それらを使用するためのルールのほとんどは明らかです。
これらの事前定義された変数、つまり、暗黙的ルールで使用されるマクロは、プログラム名を持つマクロ (CC など) とパラメータを持つマクロ (CFLAGS など) の 2 つの大きなカテゴリに分類されます。

以下に、組み込みルールとして使用される一般的な変数のいくつかの表を示します: makefile プログラム名。

  • ARアーカイブ維持プログラム。デフォルトの「ar」。
  • ASアセンブリ ファイルをコンパイルするためのプログラム。デフォルトの「as」。
  • C プログラムをコンパイルするためのCCプログラム。デフォルトの「cc」。
  • CO RCS からファイルをチェックアウトするためのプログラム。デフォルトの「co」。
  • CXX C++ プログラムをコンパイルするためのプログラム。デフォルトの「g++」。
  • CPP C プリプロセッサを実行するためのプログラム。結果は標準出力に出力されます。デフォルトは「$(CC) -E」です。
  • Fortran および Ratfor プログラムをコンパイルまたは前処理するためのFCプログラム。デフォルトは「f77」です。
  • GET SCCS からファイルを抽出するプログラム。デフォルトの「get」。
  • LEX Lex 文法をソース コードに変換するために使用するプログラム。デフォルトの「lex」。
  • YACC Yacc 文法をソース コードに変換するために使用するプログラム。デフォルトの「yacc」。
  • LINTソース コードで lint を実行するために使用するプログラム。デフォルトの「lint」。
  • Modula-2 ソース コードのコンパイルに使用するM2Cプログラム。デフォルトの「m2c」。
  • Pascal プログラムをコンパイルするためのPCプログラム。デフォルトの「pc」。
  • MAKEINFO Texinfo ソース ファイルを Info ファイルに変換するプログラム。デフォルトの「makeinfo」。
  • TEX TeX ソースから TeX dvi ファイルを作成するプログラム。デフォルトの「テックス」。
  • TEXI2DVI Texinfo ソースから TeX dvi ファイルを作成するプログラム。デフォルトの「texi2dvi」。
  • WEAVE Web を TeX に変換するプログラム。デフォルトの「織り」。
  • CWEAVE C Web を TeX に変換するプログラム。デフォルトの「cweave」。
  • TANGLE Web を Pascal に翻訳するプログラム。デフォルトの「もつれ」。
  • CTANGLE C Web を C に変換するプログラム。デフォルトの「四角形」。
  • RMファイルを削除するコマンド。デフォルトの `rm -f'。

以下は、その値が上記のプログラムの追加パラメーター リストである変数です。特に指定しない限り、これらすべてのデフォルト値は空の文字列です。

  • ARFLAGSアーカイブ管理プログラムに与えるフラグ。デフォルトの「rv」。
  • ASFLAGSアセンブラに与える追加のフラグ ( .s' or .S' ファイルで明示的に呼び出された場合)。
  • CFLAGS C コンパイラに与える追加のフラグ。
  • CXXFLAGS C コンパイラに与える追加のフラグ。
  • COFLAGS RCS co プログラムに与える追加のフラグ。
  • CPPFLAGS C プリプロセッサとそれを使用するプログラム (C および Fortran コンパイラ) に与える追加のフラグ。
  • FFLAGS Fortran コンパイラに与える追加のフラグ。
  • GFLAGS SCCS get プログラムに与える追加のフラグ。
  • LDFLAGSコンパイラがリンカ `ld' を呼び出すときにコンパイラに与える追加のフラグ。
  • LFLAGS Lex に与える追加のフラグ。
  • YFLAGS Yacc に与える追加のフラグ。
  • PFLAGS Pascal コンパイラに与える追加のフラグ。
  • RFLAGS Ratfor プログラムの Fortran コンパイラに与える追加のフラグ。
  • LINTFLAGS lint に与える追加のフラグ。

注:暗黙的なルールで使用されるすべての変数のチェックを外す-Rか、オプションを選択できます。たとえば、コマンドラインでマクロを定義することもできます。--no-builtin-variables

          make CPP=/home/moon/projects

4. Makefile による依存関係の定義

新版的gcc编译器引入头文件不再需要后缀名,eg:# include<iostream>,不再需要.h后缀。

最終的なバイナリがさまざまなソース コードおよびソース コードのヘッダー ファイルに依存することは非常に一般的です。依存関係はターゲットのソースを示すため重要です。以下の例を参照してください

hello: main.o factorial.o hello.o
	$(CC) main.o factorial.o hello.o -o hello
  • ここでは、オブジェクト ファイル hello に main.o、factorial.o、および hello.o に依存していることを伝えているため、変更があるたびにこれらのオブジェクト ファイルがアクションを実行します。代わりにコンパイル ルール ルールを使用することもでき$(CC) $? -o $@ます$(CC) main.o factorial.o hello.o -o hello

同時に .o ファイルを準備する方法も説明するので、これらの依存関係も次のように定義する必要があります。

main.o: main.cpp functions.h
	$(CC) -c main.cpp

factorial.o: factorial.cpp functions.h
	$(CC) -c factorial.cpp

hello.o: hello.cpp functions.h
	$(CC) -c hello.cpp

依存関係が多い場合は、LDFLAGS で += を使用して接続します。
ここに画像の説明を挿入します

5. Makefile の定義規則

Makefile ターゲット ルールの一般的な構文

    target [target...] : [dependent ....]
    [ command ...]
  • 角括弧内の項目はオプションであり、省略記号は 1 つ以上を指します。各コマンドの前に必要なラベルに注目してください。

以下に示すのは、ターゲットを他の 3 つのファイルから hello にするルールを定義する簡単な例です。

hello: main.o factorial.o hello.o
	$(CC) $? -o $@
  • 注: この例では、すべてのオブジェクトがソース ファイルからファイルを読み取るようにルールを削除する必要があります。

セマンティクスは非常に単純です。「make target」でターゲット ルールが適用されることが判明した場合、依存する新しいターゲットがある場合は、コマンドが一度に 1 つずつ実行されます (マクロ置換後)。依存関係が発生した場合は、それが最初に発生します (再帰が可能になります)。
いずれかのコマンドが失敗ステータスを返した場合、MAKE は終了します。そのため、次のようなルールが表示されます。

clean:hello
        -rm *.o *~ core paper
  • Make は、ダッシュで始まるコマンド ラインによって返されるステータスを無視します。例えば。コア ファイルが存在しない場合、誰が気にするでしょうか。、clean を定義した後、次を実行します: make clean、すべてのファイルをクリーンアップします

Make は置換コマンドの後にマクロ文字列をエコーし​​、何が起こったかをそのまま伝えます。場合によっては、それらをオフにしたい場合もあります。例えば:

install:hello
        @echo You must be root to install
  • @ は、サイレント出力を示すために echo コマンドの前に追加され、情報に関係のないものは出力されません。たとえば、echo は出力されませんが、「インストールするには root である必要があります」と表示されます。
  • 誰もが期待する Makefile の目標のいくつか。常に最初に参照する必要がありますが、ターゲット (または単に実行)、インストール、クリーンを目的としているのが合理的です。
    • make all - すべてをコンパイルして、ローカルでテストできるようにします。以前にインストールしたものはすべて、ルールと一緒に使用できます。例:all:hello install
    • make install - 適切な場所にインストールする必要があるもの。しかし、すべてがシステムにとって適切な場所にインストールされているようです。
    • make clean - 掃除すべきもの。実行可能ファイル、一時ファイル、オブジェクト ファイルなどを削除します。

6. Makefile の暗黙のルール

1. このコマンドは、暗黙のルールとしてソース コード x.cpp を使用して実行可能ファイル x をビルドするすべての場合に使用する必要があります。これは次のように言えます。

.cpp:
        $(CC) $(CFLAGS) $@.cpp $(LDFLAGS) -o $@
  • この暗黙のルールは、make c の場合、xc は xc 呼び出しを実行し、x を出力することを示しています。具体的な目標が言及されていないため、ルールは暗黙的なものとなります。あらゆる状況で使用できます。

2. もう 1 つの一般的な暗黙のルールは、.o (オブジェクト) ファイルと .cpp (ソース ファイル) の構築です。

.o:.cpp
        $(CC) $(CFLAGS) -c $<

alternatively

.o:.cpp
        $(CC) $(CFLAGS) -c $*.cpp

3. $^ はすべての依存関係を示します

#LDFLAGS 表示依赖库
LDFLAGS = -lstdc++ 
hello:main.o factorial.o hello.o
        $(CC) $^ $(LDFLAGS) -o $@
.o:.cpp functions.h
        $(CC) -c $<
clean:
        -rm *.o hello
install:hello
        @echo "You need build hello!"
        echo "no @ used"
all:hello install

7. Makefile のカスタム サフィックス ルール

make 側では、.o ファイルを作成するには、対応する c ファイルである cc-c を使用する必要があることをすでに認識しています。MAKE に組み込まれているこれらのルールは、これを利用して Makefile を短縮できます。Makefile の依存関係行が現在のターゲットが依存している .h ファイルを単に表している場合、MAKE は対応するファイルが指定されていることを認識します。コンパイラの include コマンドも必要ありません。
これにより、Makefile はさらに次のように削減されます。

OBJECTS = main.o hello.o factorial.o
hello: $(OBJECTS)
        cc $(OBJECTS) -o hello
hello.o: functions.h
main.o: functions.h 
factorial.o: functions.h 

1..SUFFIXESカスタムサフィックスを許可する

.SUFFIXESMake は特別なターゲットを使用するため、独自のサフィックスを定義できるように名前が付けられています。たとえば、依存関係は次のとおりです。

.SUFFIXES: .foo .bar
  • これらの特別なサフィックスを使用して独自のルールを作成することを make に伝えます。

作成方法 make は、.c ファイルから .o ファイルを生成する方法をすでに知っています。同様に、ルールは次の方法で定義できます。

.foo:.bar
        tr '[A-Z][a-z]' '[N-Z][A-M][n-z][a-m]' < $< > $@
.c:.o
        $(CC) $(CFLAGS) -c $<
  • 最初のルールでは、.foo ファイルから .bar ファイルを作成できます。(何をするかについては心配しないでください。基本的にファイルをスクランブルします)
  • 2 番目のルール .c ファイルは、デフォルトのルールを使用して .o ファイルを作成します。

2、*ワイルドカードです

*任意の単語を表すために使用され、メイクファイルを大幅に簡素化できます。

LDFLAGS = -lstdc++

all:hello install

hello:*.cpp *.h
        $(CC) $^ $(LDFLAGS) -o $@

clean:
        -rm *.o hello

install:hello
        @echo "You need build hello!"
        echo "no @ used"

8. メイクファイルの説明

さまざまな形式の指示がいくつかあります。プログラムはすべてのコマンドをサポートしているわけではありません。したがって、make がディレクティブをサポートしているかどうかを確認してください。ここでは、GNU make でサポートされているディレクティブのいくつかを調べます。

1. 条件付き命令

条件付き命令:

  • ifeq命令を開始する条件、指定された条件。これには、カンマで区切られ、括弧で囲まれた 2 つのパラメーターが含まれます。2 つのパラメータに対して変数置換が実行され、比較されます。メイクファイル内の IFEQ に続く行は、2 つのパラメータが一致する場合に従います。一致しない場合は無視されます。彼らは平等ですか?
  • ifneq命令を開始する条件、指定された条件。これには、カンマで区切られ、括弧で囲まれた 2 つのパラメーターが含まれます。2 つのパラメータに対して変数置換が実行され、比較されます。makefile ifneq は 2 つの引数が一致しない場合は考慮され、一致しない場合は無視されます。待たない
  • ifdefディレクティブを開始する条件、指定された条件。これには単一のパラメータが含まれます。指定された引数が true の場合、条件は true になります。定義されていますか?
  • ifndefディレクティブを開始する条件、指定された条件。これには単一のパラメータが含まれます。指定された値が false の場合、条件は true になります。未定義ですか?
  • 前の条件が尊重されない場合、 elseディレクティブの結果は次の行になります。上の例では、最初のオプションが使用されている場合、コマンドに接続するための 2 番目のオプションは使用されないことを意味します。これはオプションであり、else if 条件があります。
  • endifディレクティブの終了条件。すべての条件は endif で終わる必要があります。

1. 条件付き命令の構文

他の構文を含まない単純な条件は
次のとおりです。

conditional-directive
text-if-true
[else
text-if-false]
endif
  • true の場合のテキストは、条件が true の場合にメイクファイルの一部とみなされる任意のテキスト行です。条件が false の場合、テキストは置換されません。
  • 角括弧は[]、対応するコンテンツが無視されることを示します

複雑な条件の
構文は次のとおりです。

conditional-directive
text-if-true
else
text-if-false
endif
  • 条件が true の場合は true のテキストが使用され、それ以外の場合は false のテキストが代わりに使用されます。テキストは、エラーの数であれば、任意のテキスト行にすることができます。

条件ディレクティブの構文は、条件が単純であっても複雑であっても同じです。さまざまな条件をテストするための 4 つの異なる命令があります
以下に表を示します。

ifeq (arg1, arg2)
ifeq 'arg1' 'arg2'
ifeq "arg1" "arg2"
ifeq "arg1" 'arg2'
ifeq 'arg1' "arg2" 

上記の条件に反する命令は次のとおりです。

ifneq (arg1, arg2)
ifneq 'arg1' 'arg2'
ifneq "arg1" "arg2"
ifneq "arg1" 'arg2'
ifneq 'arg1' "arg2" 

2. 条件付き命令の例

条件付き命令、クロスプラットフォームコンパイル。

libs_for_gcc = -lgnu
normal_libs =

foo: $(objects)
ifeq ($(CC),gcc)
        $(CC) -o foo $(objects) $(libs_for_gcc)
else
        $(CC) -o foo $(objects) $(normal_libs)
endif

2. ディレクティブを含める

include ディレクティブは、続行する前に現在の makefile の読み取りを一時停止し、1 つ以上の他の makefile を読み取るように make に指示します。ディレクティブはメイクファイル内の 1 行で、次のようになります。

include filenames...

ファイル名にはシェルのファイル名パターンを含めることができます。行の先頭にある余分なスペースは無視できますが、ラベルは許可されません。たとえば、 bash で展開された.mk'文件, a.mk'、b.mk', and c.mk'、$(bar) の 3 つがある場合、次の式になります。

include foo *.mk $(bar)

is equivalent to

include foo a.mk b.mk c.mk bash

MAKE が include ディレクティブを処理するとき、含まれている makefile の読み取りを一時停止し、リストされた各ファイルから順番に読み取ります。このプロセスが完了したら、読み取りディレクティブがメイクファイルの再開に表示されるようにします。

3. オーバーライド命令

変数がすでにコマンド引数として設定されている場合、通常のタスクのメイクファイルではその変数は無視されます。コマンド引数として設定されている場合でも makefile 変数を設定したい場合は、次のような行であるオーバーライド ディレクティブを使用できます。

override variable = value

or

override variable := value

4,=、+=、:=、?=

= 直接代入
:= 以前の代入を無視
+= 追加
?= 以前の定義がない場合、その定義が有効になります

9. Makefile を再コンパイルする

make プログラムはインテリジェントなユーティリティであり、ソース ファイルの変更に基づいて動作します。main.cpp、hello.cpp、factorial.cpp、functions.h の 4 つのファイルがあるとします。ここにある残りのファイルはすべてfunctions.hに依存し、main.cppはhello.cppとfactorical.cppに依存します。そのため、functions.h に変更を加えると、すべてのソース ファイルが再コンパイルされて新しいオブジェクト ファイルが生成されます。ただし、main.cpp に変更が加えられた場合、これは他のフィルタリングに依存しないため、この場合は main.cpp ファイルのみが再コンパイルされ、help.cpp fallial.cpp は再コンパイルされません。

1. 再コンパイルの条件

ファイルのコンパイル中に、MAKE はターゲット ファイルをチェックしてタイムスタンプを比較します。ソース ファイルの更新タイムスタンプがターゲット ファイルよりも新しい場合は、ソース ファイルが変更されているものとして新しいオブジェクト ファイルが生成されます。

2. 再コンパイルを避ける

プロジェクトには数千のファイルが含まれる可能性があります。ソース ファイルを変更したが、それに依存するすべてのファイルを再コンパイルしたくない場合があります。たとえば、他の多くのファイルが依存するヘッダー ファイルまたは宣言にマクロを追加するとします。ヘッダー ファイルを変更すると、すべての関連ファイルを再コンパイルする必要があると想定されますが、再コンパイルする必要はなく、コンパイルを待つ時間を無駄にしない方がよいことに注意してください。

  • -t問題が発生する前にヘッダー ファイルへの変更が予想される場合は、フラグを使用できます。このフラグは、ルールを実行しないように make コマンドに指示しますが、最終変更日を変更することでこれまでのターゲットをマークします。次の手順を実行します:

    • 1. ソース ファイルを再コンパイルする必要がある場合は、コマンド「make」を使用して再コンパイルします。
    • 2. ヘッダー ファイルに変更を加えます。
    • 3. コマンドを使用して-t、すべてのターゲット ファイルを最新のものとして記録します。次回 make を実行するとき、ヘッダー ファイルを変更しても再コンパイルは発生しません。
  • ヘッダー ファイルが変更されている場合、一部のファイルを再コンパイルする必要がありますが、再コンパイルしても手遅れになります。-o代わりに、指定したファイルを としてマークするファイル フラグを使用できますoldこれは、ファイル自体は複製されず、その指示以外は何も複製されないことを意味します。次の手順を実行します:

    • 1. ソース ファイルを再コンパイルするには、独立した特定のヘッダ ファイルを準備する必要がありますmake -o headerfile複数のヘッダー ファイルが関係する場合は、-oヘッダー ファイルごとに個別のオプションを使用します。
    • 2.make -t再コンパイルを避けるために、すべてのターゲット ファイルをタッチします。

3、タッチ

Touch は、間隔が短すぎるためにプロジェクトが更新されないという問題を回避するために、ライブラリを最新の時刻に更新します。
例えば:

touch  xxx.cpp

10. Makefileのその他の機能

1. make を再帰的に使用する

再帰的使用とは、make ファイル内のコマンドとして make を使用することを意味します。この手法は、メイクファイルのさまざまなサブシステムを使用してより大きなシステムを構成する場合に非常に役立ちます。たとえば、独自の makefile を持つサブディレクトリがあり、そのサブディレクトリの makefile で make を実行するとします。これは次のようにして実行できます。

#方式一:先切换目录再去make编译
subsystem:
        cd subdir && $(MAKE)

or, equivalently
#方式二:编译时去寻找切换目录 	
subsystem:
        $(MAKE) -C subdir

make コマンドを使用するだけで、この例の再帰コピーを作成することは可能ですが、それらがどのように機能するのか、なぜ機能するのか、サブトップレベルの make がどのように関与するのかなど、理解すべきことがたくさんあります。

2. サブメイクする通信変数

トップレベルの make 変数の値は、明示的なリクエストによってサブ環境に渡すことができます。これらの変数はサブメイクでデフォルト値として定義されますが、「-e」スイッチが使用されない限り、サブメイクファイルで指定された変数をオーバーライドしません。

変数を渡す、またはエクスポートすると、変数とその値が各コマンドが実行される環境に追加されます。Submake 次に、make は環境変数の値を使用してテーブルを初期化します。

特殊変数 SHELL および MAKEFLAGS は常にエクスポートされます (エクスポートがキャンセルされない限り)。何かを設定すると、MAKEFILES がエクスポートされます。

特定の変数のサブメーカーをエクスポートする場合は、次のようにエクスポート ディレクティブを使用します。

export variable ...

変数がエクスポートされないようにするには、次のように undo エクスポート ディレクティブを使用します。

unexport variable ...

3. MAKEFILES 変数

MAKEFILES、環境事前定義マクロ。環境変数が定義されている場合、他のメイクファイル名がその値を読み取られるとみなされる前に、追加のメイクファイル名のリストを作成します(スペースで区切ります)。これは include ディレクティブとよく似ており、異なるディレクトリでこれらのファイルを検索します。
MAKEFILES の主な目的は、エラーを報告せずに MAKE 再帰呼び出し間で通信することですが、これによりプロジェクトが複雑になりやすくなります。但没有必要,最好不用定义和使用该变量

LDFLAGS=-lstdc++
all:hello install
	@echo "MAKEFILES=$(MAKEFFILES)"

4. ヘッダー ファイルは別のディレクトリにインクルードされます

ヘッダー ファイルを別のディレクトリに置き、別のディレクトリで make を実行する場合は、ヘッダー ファイルへのパスを伝える必要があります。-Iこれは、メイクファイルのオプションを使用して実行できます。function.h ファイルが /home/yidaoyun/header にあり、その他のファイルが /home/yidaoyun/src/ にあると仮定すると、ファイルは次のように記述されます。

INCLUDES = -I "/home/yidaoyun/header"
CC = gcc
LIBS =  -lm
CFLAGS = -g -Wall
OBJ =  main.o factorial.o hello.o

hello: ${
    
    OBJ}
   ${
    
    CC} ${
    
    CFLAGS} ${
    
    INCLUDES} -o $@ ${
    
    OBJS} ${
    
    LIBS}
.o:.cpp
   ${
    
    CC} ${
    
    CFLAGS} ${
    
    INCLUDES} -c $<

5. さらにテキスト変数を追加します

通常、すでに定義されている変数の値にテキストを追加するために使用されます。
make 行には+=次のように が含まれます。

objects += another.o

これは、変数オブジェクトの値を取得し、テキストanother.o(前にスペース 1 つ) を追加します。したがって:

objects = main.o hello.o factorial.o
objects += another.o

オブジェクトを設定します文件main.o hello.o factorial.o another.o
使用法は+=次のようになります。

objects = main.o hello.o factorial.o
objects := $(objects) another.o

6. Makefile での行の継続

Makefile 内の行が長すぎるのが気に入らない場合は、以下に示すように\バックスラッシュを使用できます。但反斜杠后面不能有任何字符(空格,tab建,字母,下划线等)

OBJ =  main.o factorial.o \
	hello.o

is equivalent to

OBJ =  main.o factorial.o hello.o

7. コマンド プロンプトから Makefile を実行します。

「Makefile」という名前の Makefile を準備した場合は、コマンド プロンプトに書き込むだけで Makefile が実行されます。ただし、Makefile に別の名前がある場合は、次のコマンドを使用します。

make -f your-makefile-name

11. メイクファイルの場合

Hello プログラム Makefile をコンパイルする例です。このプログラムには、main.cpp、factorial.cpp、hello.cpp の 3 つのファイルが含まれています。

# Define required macros here
SHELL = /bin/sh

OBJS =  main.o factorial.o hello.o
#CFLAG编译参数,-Wall:开启所有警告,-g:开启调试信息
CFLAG = -Wall -g
CC = gcc
#INCLUDES:依赖文件,没有就空,-I:当前文件
INCLUDES = -I .
#LIBS 依赖库
LIBS = -lstdc++

hello:${
    
    OBJS}
	${
    
    CC} ${
    
    CFLAGS} -o $@ $^ ${
    
    LIBS}

clean:
	-rm -f *.o hello

.o:.cpp
	${
    
    CC} ${
    
    CFLAGS} ${
    
    INCLUDES} -c $<
  • hello プログラムをビルドするには、「make」hello プロジェクトを使用します。「make clean」コマンドを発行すると、現在のディレクトリの makefile にあるすべてのオブジェクトが削除されます。

要約する

1. vim コマンド モードのショートカット キー:
u: 最後の保存前のすべての入力を元に戻します。
control+r: 最後に保存する前のすべての入力を復元します。
dを2回押す:行を削除します。

おすすめ

転載: blog.csdn.net/MOON_YZM/article/details/131098875