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文件,所有Debug下存放.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 变量,make 在执行时设置的一个特殊变量,该变量记录了命令行参数指定的目标列表,没有通过参数指定终极目标时此变量为空。该变量仅限于用在特殊场合(比如判断),在 Makefile 中最好不要对它进行重新定义。
而strip 函数可以用来去掉字符串中的空格(包括 [TAB] 等不可显示字符),这些空格的位置可以位于字符串中字符单词的前面,中间以及后面。去掉的结果是用一个空格代替多个原来的多个空格。

所以这个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工具链编译过程中,控制台输出的一行信息是不换行的,这样,当输出信息过长时(如编译错误时的信息),会导致你无法看到完整的输出信息,加入-fmessage-length=0后,输出信息会根据控制台的宽度自动换行,这样就能看全输出信息了。 

-MF FILE:与-M或-MM一起使用,指定依赖关系写到什么文件中,如果没有-MF选项,则默认写到预处理输出中。当与-MD或-MMD一起使用时,-MF指定的文件会覆盖默认依赖输出文件。

-M:输出源文件的依赖关系,其中隐含了-E和-w选项。

-MM:与-M类似,但忽略系统头文件。

-MD:除了未隐含-E选项外,等价于-M -MF file。

-MMD:与-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文件,因为那时它还不存在,hello.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


————————————————
版权声明:本文为CSDN博主「heron804」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/heron804/article/details/7467074

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值