zoukankan      html  css  js  c++  java
  • GNU make 与 Makefile

    前言

    make 是一个工具程序,通过读取 Makefile 文件,实现自动化软件构建。虽然现代软件开发中,集成开发环境已经取代了 make,但在 Unix 环境中,make 仍然被广泛用来协助软件开发。make 不仅仅用来编译 C/C++ 程序,还可以用来实现任何输入文件和结果文件的转化。

    Makefile 语法

    Makefile 文件由一组规则构成,每个规则有如下形式:

    targets : prerequisities
    	recipe
    	recipe
    	recipe
    
    • targets:目标是文件名或操作名(也称为“伪目标”,phony target)。目标通常是一个,多个目标之间用空格分隔。
    • prerequisities:前置条件定义了构建目标文件的依赖。多个依赖文件(也可以是伪目标)用空格分隔。只要有一个前置文件不存在,或者有过更新(前置文件的最后修改时间比目标的时间戳新),目标就需要重新构建。如果前置条件不存在,会执行 make <prerequisities>。
    • recipe:每一行配方的起首是 tab 键,而不是空格。

    如果存在 targets 同名的文件,make <targets> 不会执行。这时需要加上 .PHONY,伪目标会在每次编译时重新执行一遍。

    .PHONY: clean
    clean:
    	rm *.o temp
    

    如果 make 执行时没有指定目标,则默认执行 Makefile 中的第一个目标

    注释

    # 在 Makefile 中表示注释。

    变量

    可以在 Makefile 中使用变量。引用变量的方法是:$(变量名)

    files = file1 file2
    some_file: $(files)
    	echo "Look at this variable: " $(files)
    

    赋值运算符可以是:=,=:,?=,

    • = 只有在命令使用到该变量时,才执行赋值操作。在此之前,变量会原封不动地记录赋值语句右边的表达式。
    • =: 赋值语句立刻执行。如果该赋值语句右边表达式中含有变量,则该变量只有定义在赋值语句之前才会被应用。
    • ?= 赋值前会检查变量是否已经被赋值。如果已赋值则不执行此次赋值,否则执行

    指令

    include

    include 指令会使 make 程序停在当前 makefile 文件读取位置,而先去读取指定文件,再继续读。
    -include 同 include,但文件不存在时不会报错

    include Makefile.common
    

    控制流指令

    使用条件判断,可以让make根据运行时的不同情况选择不同的执行分支。下面的例子,判断 $(CC) 变量是否 gcc ,如果是的话,则使用GNU函数编译目标。

    libs_for_gcc = -lgnu
    normal_libs =
    
    ifeq ($(CC),gcc)
        libs=$(libs_for_gcc)
    else
        libs=$(normal_libs)
    endif
    
    foo: $(objects)
        $(CC) -o foo $(objects) $(libs)
    

    ifeq 如果相等
    ifneq 如果不相等

    配方

    显示命令

    make 默认会把要执行的命令在执行前输出到屏幕上。但如果在命令行前用 @,则不会打印。比如下面的例子,只打印 >> writing assets,而不会打印 echo。

    .PHONY: assets
    assets:
    	@echo ">> writing assets"
    

    函数

    字符操作函数

    # firstword 打印第一个单词
    $(firstword foo bar)
    
    # word <N> 打印第 N 个单词
    $(word 2, foo bar baz)
    
    # wildcard <FILENAMES> 打印所有匹配的文件名,用空格隔开
    $(wildcard *.md)
    

    shell 函数

    shell 函数执行 shell 后面跟着的参数,并把执行结果作为返回。

    go = $(shell go version)
    
    .PHONY: all
    all:
    	echo $(go)
    

    参考文档

    [1] 阮一峰:Make 命令教程
    [2] GNU Make Manual
    [3] 跟我一起写 Makefile

  • 相关阅读:
    C#多线程的简单理解
    CSS中图片水平垂直居中方法小结
    浅析JavaScript的prototype
    记kkpager分页控件的使用
    面试必问的 volatile
    观察者模式——从JDK到Spring
    Java 内存模型都不会,就敢在简历上写熟悉并发编程吗
    工厂模式,就这一篇搞定
    JVM解毒——类加载子系统
    JVM解毒——JVM与Java体系结构
  • 原文地址:https://www.cnblogs.com/huanggze/p/11914235.html
Copyright © 2011-2022 走看看