zoukankan      html  css  js  c++  java
  • Makefile笔记

    Makefile笔记

    Makefile为make工具提供一系列规则,是Linux下变成的有效生产力工具。make在后面不加参数时,会自动寻找Makefile,后面不加目标文件,默认生成第一条规则定义的文件。

    参考链接

    文件格式

    Makefile的每一条规则的形式如下:

    <target> : <prerequisities>
    [tab] <command>
    

    每条规则说明:构建(build)目标的前置条件是什么,如何构建。其中,“目标”是必需的,“前置条件”和“命令”至少有一个。

    target

    target通常是文件名,指明要构建的对象。

    还有一种用法,使用“伪目标”来执行操作

    .PHONY: clean #声明clean是伪目标
    clean:
    	rm *.o #清除.o文件的操作
    

    prerequisites

    前置条件通常是一组文件名,之间用空格分割。

    指定了“目标”是否重建的判别标准:前置文件有过更新(前置文件的last-modification时间戳比目标文件的时间戳新),目标文件就需要重建。

    如果前置文件没有,会报错停止。

    result.txt: source.txt
    	cp source.txt result.txt
    

    commands

    命令表示如何更新目标文件,由一行或多行的shell命令组成,它是构建“目标”的具体指令,运行结果通常是生成目标文件。

    基本语法

    注释

    和shell一样,注释是用#号

    回声

    正常情况下,make会打印每条命令,然后执行,可以在命令之前加上@可以关闭回声(echoing)

    .PHONY: test
    test:
    	@echo "hello" #@号关闭了回声
    

    只输出hello

    通配符

    Makefile中的通配符与bash一致,主要是?和*

    模式匹配

    使用%方便处理大量同类文件

    %.o : %.c
    #等价于
    #f1.o:f1.c
    #f2.o:f2.c
    #......
    

    变量

    Makefile允许自定义变量

    v1 = Hello World
    v2 = $(v1)
    test:
    	@echo $(v2) #变量要被包裹在$()中
    	@echo $$HOME #调用shell变量时,要多加一个$进行转义
    

    赋值方式有多种

    VARIABLE = value
    # 在执行时扩展,允许递归扩展。
    
    VARIABLE := value
    # 在定义时扩展。
    
    VARIABLE ?= value
    # 只有在该变量为空时才设置值。
    
    VARIABLE += value
    # 将值追加到变量的尾端。
    

    Makefile还有内置变量

    比如,$(CC) 指向当前使用的编译器,$(MAKE) 指向当前使用的Make工具。这主要是为了跨平台的兼容性。

    自动变量

    (1)$@指代当前正在构建的目标

    a.txt:
    	@touch $@ #指代正在构建的a.txt
    #等价于
    #a.txt:
    #	@touch a.txt
    

    (2) $<指代第一个前置条件

    a.txt: b.txt c.txt
        cp $< $@ #这里$<指代b.txt
    #等价于
    #a.txt: b.txt c.txt
    #    cp b.txt a.txt
    

    (3) $?指代比目标更新的所有前置条件,中间用空格隔开。比如,规则为t: p1 p2,其中p2的时间戳比t新,$?就指代p2

    (4) $^ 指代所有前置条件,之间以空格分隔。比如,规则为t: p1 p2,那么$^就指代p1 p2

    (5) $* 指代匹配符%匹配的部分,比如%匹配f1.txt中的f1,$*就表示 f1

    (6) $(@D) 和 $(@F) 分别指向 $@ 的目录名和文件名。

    (7)$(<D) 和$(<F) 分别指向 $< 的目录名和文件名。

    例子

    dest/%.txt: src/%.txt
        @[ -d dest ] || mkdir dest
        cp $< $@
    

    上面代码将src目录下的txt文件,拷贝到 dest 目录下。首先判断dest目录是否存在,如果不存在就新建,然后,$<指代前置文件(src/%.txt),$@指代目标文件(dest/%.txt)。

    判断和循环

    判断训话的语法和bash一致

    #if语句
    ifeq ($(CC),gcc)
      libs="gcc"
    else
      libs="not gcc"
    endif
    testIf:
    	@echo $(libs)
    
    #循环
    LIST = one two three
    #不同行makefile中的shell属于不同进程,在同一行用;分隔可以在同一个shell内执行,
    #""可以连接多行
    all:
    	@for i in $(LIST);  
    	do 
    		echo $$i; 
    	done
    

    Makefile函数

    函数调用格式

    $(function arguments)
    

    常用函数举例

    (1) shell

    可以执行shell命令

    test:
    	@echo $(shell pwd)
    

    (2)wildcard

    可以使用bash的通配符

    test:
    	@echo $(wildcard dir/*.txt)
    

    (3) subst

    文本替换函数

    #格式
    $(subst from,to,text)
    
    comma = ","
    #空变量
    empty =
    #空格需要用空变量作为标识符
    space = $(empty) $(empty)
    foo = "a b c"
    #不能有多余空格
    bar = $(subst $(space),$(comma),$(foo))
    
    test:
    	@echo $(bar)
    

    (4) patsubst

    用于模式匹配的替换

    #格式
    $(patsubst pattern,replacement,text)
    
    #将文件名"x.c.c bar.c",替换成"x.c.o bar.o"
    $(patsubst %.c,%.o,x.c.c bar.c)
    

    (5) OUTPUT

    替换后缀名

    min: $(OUTPUT:.js=.min.js)
    

    编译C语言项目例子

    edit : main.o kbd.o command.o display.o 
        cc -o edit main.o kbd.o command.o display.o
    
    main.o : main.c defs.h
        cc -c main.c
    kbd.o : kbd.c defs.h command.h
        cc -c kbd.c
    command.o : command.c defs.h command.h
        cc -c command.c
    display.o : display.c defs.h
        cc -c display.c
    
    clean :
         rm edit main.o kbd.o command.o display.o
    
    .PHONY: edit clean
    
  • 相关阅读:
    时间与时间戳互换
    原生js鼠标滑动滚轮事件
    php调用whois接口域名查询
    通用php与mysql数据库配置文件
    多个div独立控制其显示/隐藏
    jquery
    定时显示div
    一个清爽的弹出层特效
    自定义百度竞价电话回拨样式总结
    基于h5+ajax实现的手机定位
  • 原文地址:https://www.cnblogs.com/fanghao/p/7637006.html
Copyright © 2011-2022 走看看