谷动谷力

 找回密码
 立即注册
查看: 3241|回复: 5
打印 上一主题 下一主题
收起左侧

C语言基础教程-- 编译智能化之Makefile应用

[复制链接]
跳转到指定楼层
楼主
发表于 2018-8-7 23:51:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 sunsili 于 2024-4-3 18:01 编辑

C语言基础教程-- 编译智能化之Makefile应用




引言

我们写好的代码需要编译,是不是每次都要输入
  1. gcc -o hello.exe hello.c
复制代码

一切为了偷懒

古人云:”勤劳能致富“。
余昧,思之:”不然,古时农民多是勤劳之人,然之非富也。余以为懒为社会发展之源也。“

现在文件少,还好写,文件多了,这个样写,写完成这个语句都要天亮了,那我们怎么办呢?聪明的前人,就发明了Makefile, 写代码按一定规则编译,输入
  1. make
复制代码
即可

我们试着新建文文档,输入
  1. gcc -o hello.exe hello.c
复制代码
保存为Makefile,注意没有后缀

打开命令提示符,到源码目录,输入
  1. make
复制代码
再输入 
  1. hello.exe
复制代码
和我们要得到结果是一样的。

再更改一下Makefile
  1. tag = hello.exe
  2. obj = hello.o
  3. src += hello.c
  4. cc = gcc

  5. all: $(obj)
  6.            $(cc) -o $(tag) $(obj)
  7. run: $(tag)
  8.            $(tag)
  9. %.o: %.c
  10.            $(cc) -c $(CFLAGS) [        DISCUZ_CODE_198        ]lt; -o $@

  11. clean:
  12.            rm -f *.o
复制代码
注释:
  目标:依赖
<Tab键> (编译命令或Linux命令)

  1. obj = hello.o
  2. hello:$(obj)  //引用变量$(变量名)
  3.     gcc -o hello $(obj)
  4. %.o : %.c       //通配符 所有*.o 依赖于 *.c  *.c编译得到*.0
  5.     gcc -c [        DISCUZ_CODE_55        ]lt;  //表示第一个依赖
  6.     gcc -c $@  //所有目标
  7.     gcc -c $^  //所有依赖
复制代码

伪目标:依赖
  1. clean:  //清理中间文件
  2.     rm hello.o
复制代码

现在不理解,没关系,照做就好了。
以后再理解

输入
  1. make
复制代码
编译 

输入 
  1. make run
复制代码
还可以运行


******原创文章,转载请说明出处******

本帖被以下淘专辑推荐:

回复

使用道具 举报

沙发
发表于 2023-8-12 09:46:04 | 只看该作者

伪目标


最早先的一个例子中,我们提到过一个“clean”的目标,这是一个“伪目标”,

   clean:

           rm *.o temp

正像我们前面例子中的“clean”一样,即然我们生成了许多文件编译文件,我们也应该提供一个清除它们的“目标”以备完整地重编译而用。 (以“make clean”来使用该目标)

因为,我们并不生成“clean”这个文件。“伪目标”并不是一个文件,只是一个标签,由于“伪目标”不是文件,所以make无法生成它的依赖关系和决定它是否要执行。我们只有通过显示地指明这个“目标”才能让其生效。当然,“伪目标”的取名不能和文件名重名,不然其就失去了“伪目标”的意义了。

当然,为了避免和文件重名的这种情况,我们可以使用一个特殊的标记“.PHONY”来显示地指明一个目标是“伪目标”,向make说明,不管是否有这个文件,这个目标就是“伪目标”。

   .PHONY : clean

只要有这个声明,不管是否有“clean”文件,要运行“clean”这个目标,只有“make clean”这样。于是整个过程可以这样写:

    .PHONY: clean

   clean:

           rm -f *.o

伪目标一般没有依赖的文件。但是,我们也可以为伪目标指定所依赖的文件。伪目标同样可以作为“默认目标”,只要将其放在第一个。一个示例就是,如果你的Makefile需要一口气生成若干个可执行文件,但你只想简单地敲一个make完事,并且,所有的目标文件都写在一个Makefile中,那么你可以使用“伪目标”这个特性:

   all : prog1 prog2 prog3

   .PHONY : all

   prog1 : prog1.o utils.o

           cc -o prog1 prog1.o utils.o

   prog2 : prog2.o

           cc -o prog2 prog2.o

   prog3 : prog3.o sort.o utils.o

           cc -o prog3 prog3.o sort.o utils.o

我们知道,Makefile中的第一个目标会被作为其默认目标。我们声明了一个“all”的伪目标,其依赖于其它三个目标。由于伪目标的特性是,总是被执行的,所以其依赖的那三个目标就总是不如“all”这个目标新。所以,其它三个目标的规则总是会被决议。也就达到了我们一口气生成多个目标的目的。“.PHONY : all”声明了“all”这个目标为“伪目标”。

随便提一句,从上面的例子我们可以看出,目标也可以成为依赖。所以,伪目标同样也可成为依赖。看下面的例子:

   .PHONY: cleanall cleanobj cleandiff

   cleanall : cleanobj cleandiff

           rm program

   cleanobj :

           rm *.o

   cleandiff :

           rm *.diff

“makeclean”将清除所有要被清除的文件。“cleanobj”和“cleandiff”这两个伪目标有点像“子程序”的意思。我们可以输入“makecleanall”和“make cleanobj”和“makecleandiff”命令来达到清除不同种类文件的目的


回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|深圳市光明谷科技有限公司|光明谷商城|Sunshine Silicon Corpporation ( 粤ICP备14060730号|Sitemap

GMT+8, 2024-4-26 13:45 , Processed in 0.089550 second(s), 40 queries .

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表