makefile从无到有

摘要:
viewplain~/code/makefile$makemake:***没有指明目标并且找不到makefile。创建makefile文件显然,我们要建个名为“makefile”的文件。加入target错误“无目标”告诉我们需要在makefile里添加一些东西:viewplain#注释file:makefiletarget:再执行“make”命令:viewplain~/code/makefile$makemake:没有什么可以做的为`target'。我们执行一下试试:viewplain~/code/makefile$./tommyTommy:5我们的makefile写完了!!!好吧,之前的makefile实在是太简单,以至于没什么实际的用途。Target在前面的makefile里,有一个叫"target"的东西。修改下makefile:viewplain#注释file:makefiletommy:gcc-otommymain.c#注意,最前面是tab,不是空格!

Makefile这玩意在上学时就应该学,可是一直沉浸于IDE的诱惑,所谓“死于安乐”,直到现在一把年纪才开始接触这种基础东西。

创建C程序

先写个c程序,保存在main.c里:

  1. //////////////////
  2. //file:main.c
  3. //////////////////
  4. #include<stdio.h>
  5. intmain()
  6. {
  7. intc=0;
  8. printf("Tommy:%d\n",c+5);
  9. return0;
  10. }


看看我这时的目录结构

  1. ~/code/makefile$ls
  2. main.c


这时敲个“make”命令试试?

  1. ~/code/makefile$make
  2. make:***没有指明目标并且找不到makefile。停止。

创建makefile文件

显然,我们要建个名为“makefile”的文件。先建一个空的名为makefile的文件:

  1. ~/code/makefile$touchmakefile
  2. tommy@tommy-zheng-ThinkPad-T61:~/code/makefile$ls
  3. main.cmakefile

这时再试试“make”命令:

  1. ~/code/makefile$make
  2. make:***无目标。停止。


加入target
错误“无目标”告诉我们需要在makefile里添加一些东西:

  1. #注释file:makefile
  2. target:

再执行“make”命令:

  1. ~/code/makefile$make
  2. make:没有什么可以做的为`target'。

可以看到前面“无目标”的错误已经解决了。

加入命令

继续往makefile里添加东西:

  1. #注释file:makefile
  2. target:
  3. gcc-otommymain.c#注意,最前面是tab,不是空格!

好了,执行make命令:

  1. ~/code/makefile$make
  2. gcc-otommymain.c
  3. ~/code/makefile$ls
  4. main.cmakefiletommy

main.c被编译了,一个可执行文件“tommy”产生了。我们执行一下试试:

  1. ~/code/makefile$./tommy
  2. Tommy:5


得意我们的makefile写完了!!!

好吧,之前的makefile实在是太简单,以至于没什么实际的用途。现在再深入研究下。

Target
在前面的makefile里,有一个叫"target"的东西。其实它可以是任何名字,而且一个makefile里可以有多个target。比如下面的makefile:

  1. #注释file:makefile
  2. tommy:
  3. gcc-otommymain.c#注意,最前面是tab,不是空格!
  4. dosomething:
  5. echojustforfun.

给make命令一个参数:

  1. ~/code/makefile$makedosomething
  2. echojustforfun.
  3. justforfun.

可以看到,make可以用来执行任何一个target底下的命令,而这种命令并不局限于gcc这种编译的命令。每个target用冒号隔开。如果make命令没有指定哪个target,那第一个target下的命令会被执行。

Dependencies

make命令一次只能处理一个target,但如果我想一次处理多个target怎么办?这时可以为一个target在冒号后面指定它所依赖的target。修改下makefile:

  1. #注释file:makefile
  2. tommy:
  3. gcc-otommymain.c#注意,最前面是tab,不是空格!
  4. dosomething:dofirstdosecond#先执行另两个target的命令
  5. echojustforfun.
  6. dofirst:
  7. echofirst.
  8. dosecond:
  9. echosecond.
  10. donothing:
  11. echonothing.

make一下看看:

  1. ~/code/makefile$makedosomething
  2. echofirst.
  3. first.
  4. echosecond.
  5. second.
  6. echojustforfun.
  7. justforfun.

可以看到,dofirst和dosecond在dosomething之前都被make了,但tommy和donothing都没有执行。

编译多个C文件

现在增加两个文件f.h和f.c,同时改一下main.c:

  1. ////////////////
  2. //file:f.h
  3. ////////////////
  4. intadd(int,int);
  5. ////////////////
  6. //file:f.c
  7. ////////////////
  8. intadd(inta,intb)
  9. {
  10. returna+b;
  11. }
  12. //////////////////
  13. //file:main.c
  14. //////////////////
  15. #include<stdio.h>
  16. #include"f.h"
  17. intmain()
  18. {
  19. printf("Tommy-add:%d\n",add(2,4));
  20. return0;
  21. }

看看我的目录结构:

  1. ~/code/makefile$ls
  2. f.cf.hmain.cmakefile

基于前面的“Dependencies”得到的结论,我们可以改写makefile,来让main函数调用f函数:

  1. #file:makefile
  2. tommy:main.of.o
  3. gcc-otommymain.of.o
  4. main.o:
  5. gcc-cmain.c-omain.o
  6. f.o:
  7. gcc-cf.c-of.o

看下生成的结果:

  1. ~/code/makefile$make
  2. gcc-cmain.c-omain.o
  3. gcc-cf.c-of.o
  4. gcc-otommymain.of.o
  5. ~/code/makefile$ls
  6. f.cf.hf.omain.cmain.omakefiletommy
  7. ~/code/makefile$./tommy
  8. Tommy-add:6

可以看到我们的生成了我们想要的东西。

clean与install
经常可以看到“make clean”和“make install”的命令。我们也可以提供它们:

  1. #file:makefile
  2. tommy:main.of.o
  3. gcc-otommymain.of.o
  4. main.o:
  5. gcc-cmain.c-omain.o
  6. f.o:
  7. gcc-cf.c-of.o
  8. clean:
  9. rm*.o
  10. install:
  11. mvtommy/usr/local



最后再研究下makefile里的宏。其实就是定义一个变量,之后再使用它:

  1. #file:makefile
  2. INSTALL_PATH=/usr/local
  3. TEMP_FILES=*.o
  4. tommy:main.of.o
  5. gcc-otommy\
  6. main.of.o#这里演示反斜杠用于换行,注意反斜杠后没有空格,行首是tab而非空格
  7. main.o:
  8. gcc-cmain.c-omain.o
  9. f.o:
  10. gcc-cf.c-of.o
  11. clean:
  12. rm$(TEMP_FILES)
  13. install:
  14. mvtommy$(INSTALL_PATH)

免责声明:文章转载自《makefile从无到有》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇jira从windows迁移到linuxC#中web项目使用log4net日志下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

CentOS 7 之几个新特性(转)

上篇我们讲到默认没有ifconfig是centos7的新特性,所以我特意上网搜索了一下其新特性,找到一篇文章,现转过来。 centos最小好化安装没有ifconfig命令 刚安装了centos7.0,最小化安装,发现没有ifconfig命令,虚拟机里面的网卡显示ens32,这是centos7.0的特点,要使用ifconfig命令,在/etc/sysconf...

《Linux内核Makefile分析》之 auto.conf, auto.conf.cmd, autoconf.h【转】

转自:http://blog.sina.com.cn/s/blog_87c063060101l25y.html 转载:http://blog.csdn.net/lcw_202/article/details/6661364 在编译构建性目标时(如 make vmlinux),顶层 Makefile 的 $(dot-config) 变量值为 1 。 在顶层...

iphone升级到ipad Upgrade Current Target for iPad为灰色的解决方法

Upgrade Current Target for iPad为灰色的解决方法 当前iPad风潮之下,我们会将已经开发完成或者下载到的合适的iPhone源码移植到iPad上,这样可以省去重新开发的时间。但有时项目移植的时候会出现Upgrade Current Target for iPad为灰色不能升级的时候,下面我们来完整的看下移植方法及灰色的处理方法...

BeanUtil拷贝

拷贝vo对象 一些查询到的数据很多是不需要的,可以创建vo对象,对需要的对象属性进行拷贝 maven依赖 <dependency>   <groupId>org.projectlombok</groupId>   <artifactId>lombok</artifactId>   <vers...

Cmake实战指南

0 综述 我觉的Cmake比较核心的一些东西就是 怎么去组织一个项目的编译框架 最终输出目标有哪些(可执行程序,动态库,静态库等等) 怎么为指定的输出目标指定编译参数(需要哪些源文件,需要哪些编译参数) 怎么为指定的输出目标指定链接参数(需要哪些外部库,需要哪些链接参数) 如果存在多个独立输出目标是否有执行先后顺序(比如项目有自动配置工具,用来自动生...

mybatis源码分析(5)-----拦截器的实现原理(动态代理+责任链)

写在前面   MyBatsi 的拦截器模式是基于代理的代理模式。并且myBatis 的插件开发也是以拦截器的形式集成到myBatis 当中。   MyBatis 的拦截器已经插件是在org.apache.ibatis.plugin包下面。   MyBatis拦截器可以拦截的类,Executor(执行器),ParameterHandler(参数处理器),R...