Eclipse CDT Hello Worldエンジニアリングmakefile分析


1.工程書類分析
eclipseを使用してHello Worldプロジェクトを新規作成します.プロジェクト名がhelloであると仮定すると、eclipseはプロジェクトディレクトリの下にhelloというフォルダを新規作成します.
hello/
    .cproject
    .project
    src/
        hello.c
先にこの工事をbuildして、それからCleanこの工事、生成した目標コードをクリアして、この時helloフォルダの下はeclipseが工事のために生成したmakefileファイルだけあって、そのファイルの構造は:
hello/
    .cproject
    .project
    Debug/
        src/
            subdir.mk
        makefile
        objects.mk
        sources.mk
    src/
        hello.c
2. sources.mkファイル
このファイルにはmakefileファイルで使用される様々な変数が定義されています.最も主要なのはSUBDIRS変数です.これは、プロジェクト内のすべてのソースファイルを含むサブディレクトリを示しています.その内容は次のとおりです.
################################################################################ 
# Automatically-generated file. Do not edit! 
################################################################################ 

O_SRCS := 
C_SRCS := 
S_UPPER_SRCS := 
OBJ_SRCS := 
ASM_SRCS := 
OBJS := 
C_DEPS := 
EXECUTABLES := 

# Every subdirectory with source files must be described here 
SUBDIRS := \ 
src \

3 objects.mkファイル
################################################################################ 
# Automatically-generated file. Do not edit! 
################################################################################ 

USER_OBJS := 

LIBS := 

4 src/subdir.mkファイル
このファイルはsrcディレクトリの下のすべてに対して使用する.cファイル修正C_SRCS、OBJS、C_DEPS変数は、フォルダの下のすべてを定義する.cファイルのコンパイルルール.ここのsrc/.o: ../src/%.cは、srcフォルダのそれぞれについてです.cファイルは、makefileが存在するフォルダ(すなわちDebug)にsrcフォルダと同名のものを生成する.oファイル.
Eclipse cdtは、ソースファイルを含むすべてのフォルダの下でこのようなsubdirを生成する.mkファイル、すべてのデバッグで保存します.oのフォルダ構造と格納.cファイルはまったく同じです.
################################################################################ 
# Automatically-generated file. Do not edit! 
################################################################################ 

# Add inputs and outputs from these tool invocations to the build variables 
C_SRCS += \ 
../src/hello.c 

OBJS += \ 
./src/hello.o 

C_DEPS += \ 
./src/hello.d 


# Each subdirectory must supply rules for building sources it contributes 
src/%.o: ../src/%.c 
	@echo 'Building file: $<' 
	@echo 'Invoking: GCC C Compiler' 
	gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<" 
	@echo 'Finished building: $<' 
	@echo ' '

5 makefileファイル
makefileファイルincludeには、上記のいくつかのファイルが含まれています.以下はmakefileファイルの内容です.
################################################################################ 
# Automatically-generated file. Do not edit! 
################################################################################ 

-include ../makefile.init 

RM := rm -rf 

# All of the sources participating in the build are defined here 
-include sources.mk 
-include src/subdir.mk 
-include subdir.mk 
-include objects.mk 

ifneq ($(MAKECMDGOALS),clean) 
ifneq ($(strip $(C_DEPS)),) 
-include $(C_DEPS) 
endif 
endif 

-include ../makefile.defs 

# Add inputs and outputs from these tool invocations to the build variables 

# All Target 
all: hello 

# Tool invocations 
hello: $(OBJS) $(USER_OBJS) 
	@echo 'Building target: $@' 
	@echo 'Invoking: GCC C Linker' 
	gcc  -o "hello" $(OBJS) $(USER_OBJS) $(LIBS) 
	@echo 'Finished building target: $@' 
	@echo ' ' 

# Other Targets 
clean: 
	-$(RM) $(OBJS)$(C_DEPS)$(EXECUTABLES) hello 
	-@echo ' ' 

.PHONY: all clean dependents 
.SECONDARY: 

-include ../makefile.targets

ここでは、コマンドラインパラメータによって指定されたターゲットリストが記録され、パラメータによって究極のターゲットが指定されていない場合にこの変数が空であるMAKECMDGOALS変数について説明する必要があります.この変数は特殊な場合(判断など)にのみ使用されますが、Makefileでは再定義しないほうがいいです.一方、strip関数は、文字列内の文字単語の前、真ん中、後ろに位置する[TAB]などの非表示文字を含む文字列のスペースを削除するために使用できます.削除された結果、元の複数のスペースの代わりに1つのスペースが使用されます.
だからこのmakefileのmakeターゲットはcleanではなく、C_DEPSに有効文字が含まれている場合のみ-include$(C_DEPS)
この工事では、C_DEPSは./src/hello.d、だからmake allの时このファイルを含んで、しかしsrcの下でファイルを変更していませんか?makeを実行すると、srcの下にhelloが多くなったことがわかりました.dファイル、内容は:
src/hello.d src/hello.o: ../src/hello.c 

どうやって来ましたか?内容はなぜそうなのか.これはsrcフォルダのsubdirを理解する必要があります.mkのこのコマンドは次のとおりです.
gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<"

-fmessage-length=0:デフォルトでは、GNUツールチェーンのコンパイル中にコンソールから出力される1行の情報は改行されません.これにより、出力情報が長すぎると(コンパイルエラー時の情報など)、完全な出力情報が表示されなくなります.-fmessage-length=0を加えると、コンソールの幅に応じて出力情報が自動的に改行され、全出力情報が表示されます. 
-MF FILE:-Mまたは-MMとともに使用し、依存関係がどのファイルに書き込まれるかを指定します.-MFオプションがない場合は、デフォルトで前処理出力に書き込まれます.-MDまたは-MDとともに使用する場合、-MMFで指定したファイルはデフォルトの依存出力ファイルを上書きします.
-M:出力元ファイルの依存関係です.-Eと-wのオプションが隠されています.
-MM:-Mと似ていますが、システムヘッダファイルは無視されます.
-MD:-Eオプションが非表示の場合を除き、-M-MF fileと同等です.
-MD:-MDと似ていますが、システムヘッダファイルは無視されます.
-MP:依存するヘッダファイルにダミーターゲットを追加します.ヘッダファイルを削除した後、makefileが更新されていない場合、エラーが表示されます.一般的な出力は次のとおりです.
        test.o: test.c test.h 
        test.h:
-MT:依存ルールターゲットを変更し、このHelloエンジニアリングmakefileで-MT"$(@:%.o=%.d)"を削除すると、出力hello.dファイルの内容は:
src/hello.d src/hello.o: ../src/hello.c 

以上の分析から、make allを初めて実行したときにhelloが含まれていないことが分かった.dファイルはまだ存在しないからdも今回の実行によって生成された.後でmake allを再度実行するとhello.dコンテンツはmakefileに含まれ、makeは依存関係に応じて選択的にコンパイルおよびリンク操作を行う.
6  make all
コマンドラインの下にDebugディレクトリに入り、make allコマンドを実行すると、次の出力が表示されます.
Building file: ../src/hello.c
Invoking: GCC C Compiler
gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/hello.d" -MT"src/hello.d" -o "src/hello.o" "../src/hello.c"
Finished building: ../src/hello.c
 
Building target: hello
Invoking: GCC C Linker
gcc  -o "hello"  ./src/hello.o   
Finished building target: hello

上記の段落はソースファイルのコンパイルであり、ルールはsrc/subdirである.mkで定義する;ターゲットファイルを宣言します.ルールはmakefileファイルで直接定義されます.
7その他
上で分析した内容のほかに、makefileファイルには次の項目があります.
-include ../makefile.init
-include ../makefile.defs
.PHONY: dependents
-include ../makefile.targets