Makefile 構文の理解: 一般的な問題と解決策 (「演算子が見つからない」および「エントリ ポイントが見つからない」を含む)

Makefile Gou Wenno Li Jie Yi Ban Dena Wen Tito Jie Jue Ce Yan Suan Ziga Jiantsukaranai Oyobi Entori Pointoga Jiantsukaranai Wo Hanmu



コード ファイルに価値を持たせるためのコンテンツとして 1 行以上のコードが含まれているのと同じように、基本的な Makefile は変数、ルール、ターゲットを使用して構築されます。それ以外にも、問題なく完全なメイクファイルを作成するために必要な要素があります。このガイドでは、メイクファイルの基本的な構文とメイクファイル作成時の一般的な問題について説明し、それらの問題を解決するソリューションを提供します。

Makefile の基本構文を理解する

メイクファイルの作成を始めるために、メイクファイルのコード例を通じてメイクファイルの基本プロパティを説明します。実行可能ファイルを取得するには、メイクファイルのコンテンツに次の構文プロパティを含める必要があります。







変数 s: メイクファイルで使用するために必要なオブジェクトを格納する基本データ。これらの変数は、コンパイラ、フラグ、ソース ファイル、オブジェクト ファイル、およびターゲット ファイルを指定するために使用されます。次のサンプル Makefile 内には、CXX (C++ コンパイラを設定するため)、CXXFLAGSc (コンパイラ フラグ)、TARGET (ターゲット実行可能ファイル名を設定するため)、SRCS (ソース コード ファイルを設定するため) の合計 5 つの変数があります。 、OBJS (ソース コード ファイルを介して生成されたオブジェクト ファイルを含めるため)。



対象: ソースから構築される予想される出力。ターゲット ファイルまたは任意のシンボリック名を指定できます。「all」は「TARGET」変数を介して構築されるデフォルトのターゲットであり、「$TARGET」は「OBJS」変数に依存し、「clean」ターゲットはターゲットを削除し、作業ディレクトリからオブジェクト ファイルを抽出します。



ルールとビルドコマンド: ソース ファイルまたは依存関係からターゲットを作成するために実行される基本的な命令のセット。たとえば、ルール「%.o: %.cpp」は、拡張子「cpp」を持つファイルが拡張子「o」を持つオブジェクト ファイルの作成に使用され、両方のファイルに同じ名前が含まれていることを示します。一方、ビルドコマンドは、 $(CXX) $(CXXFLAGS) -o $(TARGET) $(OBJS) オブジェクト ファイルと新しいターゲット ファイルをリンクするために利用されます。同様にビルドコマンドでも $(CXX) $(CXXFLAGS) -c $< -o $@ ソースファイルをオブジェクトファイルにコンパイルします。





依存関係: メイクファイルを作成するときは、依存関係が常に存在します。たとえば、「all」ターゲットは「TARGET」変数に依存しますが、「TARGET」は「OBJS」変数に依存します。同時に、「OBJS」変数は「SRCS」変数を介してソース ファイルに依存します。

コメント: 通常、長期間にわたってファイルを使用する場合に備えて、人間が理解できる指示を使用してコード行の目的を説明します。次の Makefile では、「#」記号で始まるコメントを利用して各行を説明しています。



CXX = g++
CXXFLAGS = -std =c++ 十一 -壁
ターゲット = 新規
SRCS = main.cpp
OBJS = $ ( SRCS:.cpp=.o )
すべて: $ ( 目標 )
$ ( 目標 ) : $ ( オブジェクト )
$ ( CXX ) $ ( CXXフラグ ) -O $ ( 目標 ) $ ( オブジェクト )
% .O: % .cpp
$ ( CXX ) $ ( CXXフラグ ) -c $ < -O $ @
クリーン:
rm -f $ ( 目標 ) $ ( オブジェクト )

一般的な問題と解決策

Makefile を作成するときは、最終的に目的の出力を得るためにあらゆる細かい点を考慮する必要があります。メイクファイルの作成中に、ユーザーが頻繁に遭遇するいくつかの一般的な問題があります。このセクションでは、これらの問題について説明し、次のように考えられる解決策を提案します。

1: 変数を使用しない

コンパイラ、ターゲット、ソース ファイルなどを設定する必要があるため、メイクファイルでの変数の使用は必須です。発生する可能性のある最も一般的な問題は、メイクファイルで変数を使用しないことです。したがって、前のサンプル Makefile の CXX、CXXFLAGSc(コンパイラ フラグ)、TARGET、SRCS、OBJS などの重要な変数を必ず利用してください。

2: 区切り文字が見つからない問題

Makefile を作成する際には、タブの代わりにスペースを使用すると、「make」命令の実行中に「区切り文字の欠落」の問題が発生するため、インデントの規則を注意深く検討する必要があります。たとえば、13 行目のルールの先頭にスペースを追加し、タブを削除します。

$ ( 目標 ) : $ ( オブジェクト )
$ ( CXX ) $ ( CXXフラグ ) -O $ ( 目標 ) $ ( オブジェクト )

「make」クエリを実行すると、13 行目で「セパレータがありません」エラーが発生し、ファイルの実行が停止します。この問題を回避するには、スペースの代わりに必ず「タブ」を使用してください。

作る

この問題を回避するには、次の図に示すように、スペースではなく「タブ」を使用してください。

$ ( 目標 ) : $ ( オブジェクト )
$ ( CXX ) $ ( CXXフラグ ) -O $ ( 目標 ) $ ( オブジェクト )

3: 「エントリポイントが見つかりません」問題

このエラーは主にソース ファイルが原因で発生し、ソース コード ファイルで「main()」関数を使用しなかった場合などのメイクファイルが原因ではありません。たとえば、main() 関数定義を単純なユーザー定義関数宣言に置き換えます。

#include
イントショー ( ) {
文字v;
std::cout << 「値を入力してください:」 ;
std::cin >> で;
std::cout << << std::endl;
戻る 0 ;
}

Windows のコマンドプロンプトで make 命令を実行すると、「WinMain への未定義の参照」が発生します。これは、コンパイラが C++ ファイルの実行を開始するためのエントリ ポイントを見つけられないためです。これを解決するには、「show」を「main」に置き換えます。

4: 間違った拡張子の使用

場合によっては、ユーザーが意図せずに、メイクファイルで使用されるソース ファイルに対して間違った拡張子を使用してしまうことがあります。間違った拡張子を使用すると、実行時エラーが発生します。つまり、ターゲットを作成するルールがありません。 C++ ファイルの実行可能ファイルとオブジェクト ファイルをビルドするための Makefile を作成します。 7 行目では、拡張子「c」が付いたソース ファイルを指定します。

CXX := g++
CXXFLAGS := -std =c++ 十一 -壁
ターゲット = 新しい
SRCS = main.c
OBJS = $ ( SRCS:.cpp=.o )
すべて: $ ( 目標 )
$ ( 目標 ) : $ ( オブジェクト )

「make」命令を実行すると、「ターゲット 'main.c' を作成するルールがありません」というエラーが発生します。この問題を回避するには、必ず正しいソース ファイル拡張子を使用してください。

作る

5: 依存関係が欠落している

Makefile を作成する際、目的の出力を得るには、ソース ファイルのすべての依存関係を含める必要があります。たとえば、C++ コード ファイルは、依存関係として「myheader.h」ファイルを使用します。したがって、C++ コード ファイル内で次のように記述します。

#include
#include “myheader.h”
イントショー ( ) {
文字v;
std::cout << 「値を入力してください:」 ;
std::cin >> で;
std::cout << << std::endl;
戻る 0 ;
}

Makefile 内では、9 行目に記述されているビルド ルール内の「myheader.h」ファイルの使用を意図的に無視しています。

% .O: % .cpp
$ ( CXX ) $ ( CXXフラグ ) -c $ < -O $ @

ここで、「make」命令を使用しているときに、「'all' に対して何も実行できません」というエラーが発生します。

作る

% .O: % .cpp myheader.h
$ ( CXX ) $ ( CXXフラグ ) -c $ < -O $ @

上記の問題を回避してソース コードを正常に実行するには、次に示すように、メイクファイルの 9 行目に「myheader.h」ファイル名を指定します。

結論

このガイドでは、変数、ビルド コマンド、ルールなどの必要な内容を使用して makefile の構文を徹底的に説明しました。構文をより明確に説明するために、コード例が含まれています。最後に、メイクファイルの作成中にユーザーが遭遇する可能性のあるいくつかの定期的な問題とその解決策について説明しました。