zoukankan      html  css  js  c++  java
  • Makefile学习之路——2

    让你的makefile更专业。

    在上一个Makefile所在目录下通过touch命令创建一个clean文件,执行make clean,将发现make总是提示clean文件是最新的,而不是按我们期望的那样对项目文件进行清楚操作。make这样的行为,是因为它将clean当做文件来处理,在当前目录下找到了clean文件,而且clean目标没有任何先决条件,所以当我们要求make构建clean目标时它会认为clean文件是最新的,从而拒绝我们真正的文件清除操作。出现这种情形,是因为我们对clean目标的定义与make所理解的有出入。目录文件名与makefile的目标名重名在现实项目中是难免的,假目标(phony target)概念的提出正是为了解决这种问题的。

    假目标采用 .PHONY关键字来定义,注意必须是大写字母。运用假目标之后,更改makefile并运行如下:

    1 .PHONY: clean
    2 app:main.o foo.o
    3     gcc -o app main.o foo.o
    4 main.o:main.c
    5     gcc -o main.o -c main.c
    6 foo.o:foo.c
    7     gcc -o foo.o -c foo.c
    8 clean:
    9     rm -rf app main.o foo.o

    采用.PHONY关键字声明一个目标之后,make并不会将其当做一个文件来处理。可以想象,由于假目标并不与文件关联,所以每次构建假目标时它所在规则中的命令一定会被执行。拿这里的clean目标做比方,即使多次执行make clean,make每次都会执行文件清楚操作。

    运用变量提高可维护性:

    编写专业的makefile离不开变量,通过使用变量可以使得makefile更具可维护性。

    运用变量改写第一个makefiel。

     1 .PHONY: clean
     2 
     3 CC = gcc
     4 RM = rm
     5 
     6 EXE =simple
     7 OBJS =main.o foo.o
     8 
     9 $(EXE): $(OBJ)
    10     $(CC) -o $(EXE) $(OBJS)
    11 main.o:main.c
    12     $(CC) -o main.o -c main.c
    13 foo.o:foo.c
    14     $(CC) -o foo.o -c foo.c
    15 clean:
    16     $(RM) -rf $(EXE) $(OBJS)

    定义变量时其值可以为空,即无右值。引用变量需要采用 $(变量名)或 ${变量名} 的形式。

    引入变量之后,如果需要更改编译器,只需要更改赋值变量的地方,其实相当于C语言宏定义的作用,便于更改移植。

    上面的makefile,存在目标名和先决条件名在规则中重复出现,如果目标名或先决条件发生了改变,那么得在相应的命令中跟着更改这个很麻烦,为了省去这种麻烦,我们借助于如下一些自动变量:

    除了这三个自动变量外,在makefile中还可以使用其他的自动变量,后面需要使用到的时候再提及。目前simple项目用这三个变量就足够了。

    用上面的变量测试上面的Makefile,再正式介绍之前,得先介绍另外一个知识点。

    1 .PHONY: all
    2 all:first second third
    3     @echo "$$@ = $@"
    4     @echo "$$^ = $^"
    5     @echo "$$< = $<"
    6 first second third:

    在Makefile中,dollar符(这个字符博客老抽风) 具有特殊的意思,如果采用echo输出dollar,则必须用两个连着的dollar;

    对于bash shell 也有着特殊的意思,需要在  之前加一个反斜杠”“。

    最后一行是一个只有目标的规则,如果除去它会有什么问题呢?读者可以自己试试。 

    注释(makefile中用#表示注释,需要注释多行,在注释行的末尾加上反斜杠"",下一行也会被注释)最后一行之后报错如上图。显示没有规则创建上述目标。因为all的先决条件决定了构建all目标之前必须先构建first ,而first如果不存在,报错也是应该的。

    采用自动变量之后运行结果的Makefile如下所示:

     1 .PHONY: clean
     2 
     3 CC = gcc
     4 RM = rm
     5 
     6 EXE =simple
     7 OBJS =main.o foo.o
     8 
     9 $(EXE): $(OBJS)
    10     $(CC) -o $@ $^
    11 main.o:main.c
    12     $(CC) -o $@ -c $^
    13 foo.o:foo.c
    14     $(CC) -o $@ -c $^
    15 clean:
    16     $(RM) -rf $(EXE) $(OBJS)
  • 相关阅读:
    安全检测点的一些梳理——待长期整理
    Tor真的匿名和安全吗?——如果是http数据,则在出口节点容易被嗅探明文流量,这就是根本问题
    prefixspan是挖掘频繁子序列,子序列不一定是连续的,当心!!!
    spark mllib prefixspan demo
    spark 2.4 java8 hello world
    有效的括号序列——算法面试刷题4(for google),考察stack
    相似的RGB颜色——算法面试刷题3(for google),考察二分
    回文的范围——算法面试刷题2(for google),考察前缀和
    最长绝对文件路径——算法面试刷题1(google),字符串处理,使用tree遍历dfs类似思路
    比较全面的gdb调试命令
  • 原文地址:https://www.cnblogs.com/yangguang-it/p/6628937.html
Copyright © 2011-2022 走看看