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变量,它指示了工程中所有包含源文件的子目录,其内容如下:

  1. ################################################################################
  2. # Automatically-generated file. Do not edit!
  3. ################################################################################
  4.  
  5. O_SRCS :=
  6. C_SRCS :=
  7. S_UPPER_SRCS :=
  8. OBJ_SRCS :=
  9. ASM_SRCS :=
  10. OBJS :=
  11. C_DEPS :=
  12. EXECUTABLES :=
  13.  
  14. # Every subdirectory with source files must be described here
  15. SUBDIRS := \
  16. src \

3 objects.mk文件

  1. ################################################################################
  2. # Automatically-generated file. Do not edit!
  3. ################################################################################
  4.  
  5. USER_OBJS :=
  6.  
  7. 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文件的完全相同。

  1. ################################################################################
  2. # Automatically-generated file. Do not edit!
  3. ################################################################################
  4.  
  5. # Add inputs and outputs from these tool invocations to the build variables
  6. C_SRCS += \
  7. ../src/hello.c
  8.  
  9. OBJS += \
  10. ./src/hello.o
  11.  
  12. C_DEPS += \
  13. ./src/hello.d
  14.  
  15. # Each subdirectory must supply rules for building sources it contributes
  16. src/%.o: ../src/%.c
  17. @echo 'Building file: $<'
  18. @echo 'Invoking: GCC C Compiler'
  19. gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<"
  20. @echo 'Finished building: $<'
  21. @echo ' '

5 makefile文件

makefile文件include包含了上面介绍的几个文件,下面是makefile文件的内容:

  1. ################################################################################
  2. # Automatically-generated file. Do not edit!
  3. ################################################################################
  4.  
  5. -include ../makefile.init
  6.  
  7. RM := rm -rf
  8.  
  9. # All of the sources participating in the build are defined here
  10. -include sources.mk
  11. -include src/subdir.mk
  12. -include subdir.mk
  13. -include objects.mk
  14.  
  15. ifneq ($(MAKECMDGOALS),clean)
  16. ifneq ($(strip $(C_DEPS)),)
  17. -include $(C_DEPS)
  18. endif
  19. endif
  20.  
  21. -include ../makefile.defs
  22.  
  23. # Add inputs and outputs from these tool invocations to the build variables
  24.  
  25. # All Target
  26. all: hello
  27.  
  28. # Tool invocations
  29. hello: $(OBJS) $(USER_OBJS)
  30. @echo 'Building target: $@'
  31. @echo 'Invoking: GCC C Linker'
  32. gcc -o "hello" $(OBJS) $(USER_OBJS) $(LIBS)
  33. @echo 'Finished building target: $@'
  34. @echo ' '
  35.  
  36. # Other Targets
  37. clean:
  38. -$(RM) $(OBJS)$(C_DEPS)$(EXECUTABLES) hello
  39. -@echo ' '
  40.  
  41. .PHONY: all clean dependents
  42. .SECONDARY:
  43.  
  44. -include ../makefile.targets
  45.  

这里有必要说明以下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文件,内容是:

  1. src/hello.d src/hello.o: ../src/hello.c

它是怎么来的呢?内容为何是这样呢?这就需要搞明白src文件夹里subdir.mk中的这条命令了:

  1. 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文件内容是:

  1. 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命令,将会看到下面输出:

  1. Building file: ../src/hello.c
  2. Invoking: GCC C Compiler
  3. 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"
  4. Finished building: ../src/hello.c
  5.  
  6. Building target: hello
  7. Invoking: GCC C Linker
  8. gcc -o "hello" ./src/hello.o
  9. Finished building target: hello

其中上面一段是对源文件的编译,规则在src/subdir.mk中定义;后面一段声明目标文件,规则直接在makefile文件中定义。

7  其他

除了上面分析的内容,makefile文件还有下面几项:

-include ../makefile.init

-include ../makefile.defs

.PHONY: dependents

-include ../makefile.targets

eclipse for hello world makefile的更多相关文章

  1. import c++ project to eclipse cdt with exiting makefile

    Step 2: You are now ready to build your project. To build your project, select Project > Build Pr ...

  2. 【Eclipse】编译使用Makefile的C工程

    创建MakeFile project新建src文件夹,将文件复制到里面.右击makefile,make targets->create->名称填上allmake targets->b ...

  3. 将含有makefile文件的源码加入Eclipse工程

    转载自https://www.linuxidc.com/Linux/2011-02/32763.htm 很多软件在开发或者分析时需要一个像样的IDE,Eclipse是其中很优秀的一个,至少个人感觉很好 ...

  4. eclipse 利用已有c++代码建工程,并编译执行

    如果你想建一个带Makefile的c++ 工程 1. 新建一个C++空工程,工程类型是makefile project,选择Linux GCC: 2. 将源码连同makefile文件一同作为一个文件系 ...

  5. (转)用Eclipse编译你的ROS程序

    原地址: http://blog.csdn.net/sujun3304/article/details/18572017 好了,理解了系统各个组件的含义后,还是直接进入程序真刀真枪的从实践中学习吧! ...

  6. 在eclipse中的交叉编译

    1.硬件是Arm 9的板子,运行的系统是Ubuntu 12.05 2.电脑虚拟机上安装的系统是Ubuntu 10.04,程序的开发都是在虚拟机上完成,开发IDE是eclipse 3.eclipse 默 ...

  7. How to Install Eclipse C/C++ Development Tool--转

    http://www3.ntu.edu.sg/home/ehchua/programming/howto/EclipseCpp_HowTo.html Eclipse 4.3 (Kepler) for ...

  8. Linux下EclipseCDT工程和TFS的持续集成CI实践

    在Linux下使用TFS自动构建,需要自动执行连接tfs服务器的操作,命令行文件包TEE-CLC-10.1.0.2011121402.zip,下载地址:http://www.microsoft.com ...

  9. Android Studio NDK 学习之接受Java传入的字符串

    本博客是基于Android Studio 1.3 preview版本,且默认你已经安装了Android SDK, Android NDK. 用Android Studio新建一个工程叫Prompt,其 ...

随机推荐

  1. POJ 2486 Apple Tree(树形DP)

    题目链接 树形DP很弱啊,开始看题,觉得貌似挺简单的,然后发现貌似还可以往回走...然后就不知道怎么做了... 看看了题解http://www.cnblogs.com/wuyiqi/archive/2 ...

  2. c# 使用GetOleDbSchemaTable获取access数据库结构

    c# 使用GetOleDbSchemaTable获取access数据库结构 ado.net可以使用GetOleDbSchemaTable方法来获取access数据库的结构,但得到的datatable的 ...

  3. C#引用COM对象,报错:《类型 *** 未定义构造函数, 无法嵌入互操作类型 *** 。请改用适用的接口》的解决办法。

    错误信息: 1.类型“SQLDMO.BackupClass”未定义构造函数 2.无法嵌入互操作类型“SQLDMO.BackupClass”.请改用适用的接口. 代码如下:                ...

  4. JAVA操作COOKIE

    JAVA操作COOKIE 1.设置Cookie Cookie cookie = new Cookie("key", "value"); cookie.setMa ...

  5. MyEclipse 10 之下Web Service 的创建和实现

    (一)Web service服务端开发 1. 新建一个Web service project, 菜单New -> Web Service Project, 2. 新建一个 Java Bean, ...

  6. 序号自增key的使用

    由于在模板中,需要输出序号,但是从数据库中提取的话,保证不了序号的连续性. 在模板中我就使用foreach循环,查手册看到foreach的使用 但是我还是没从手册中学会key的使用.尝试使用 结果,如 ...

  7. Data Plane Development Kit (DPDK): Getting Started

    参考:dpdk getting started 系统: Ubuntu 14.04 内核信息: 执行 uname -a Linux chen-VirtualBox 3.13.0-32-generic # ...

  8. PHP不能创建csv中文名文件

    使用iconv 将utf-8转换成gb2312即可$name = iconv("utf-8","gb2312",'分销商下载课件记录');

  9. Visual Studio开发环境最佳字体及配色

    环境: Visual Studio 2010,(本人使用的windows 7) 字体:Fixedsys, 12pt,下载地址:http://www.fixedsysexcelsior.com 普通文本 ...

  10. 20145317彭垚 《Java程序设计》第五次实验报告

    20145317彭垚实验五 Java网络编程及安全 北京电子科技学院(BESTI)实验报告 课程:Java程序设计 班级:1453 指导教师:娄嘉鹏 实验日期:2016.05.06 18:30-21: ...