1. [http://www.ruanyifeng.com/blog/2015/02/make.html](http://www.ruanyifeng.com/blog/2015/02/make.html)<br /> GNU Make是一种流行的、常用的用于构建C语言软件的程序。用于构建Linux内核和其他常用的GNU/Linux程序和软件库。
  2. 大多数嵌入式软件开发人员在职业生涯中的某个时候都会使用GNU Make,要么使用它来编译小型库,要么构建整个项目。尽管有很多很多的选项可以替代Make,但是由于它的特性集和广泛的支持,它仍然通常被选择为新软件的构建系统。

什么是GNU Make?

  1. GNU Make是一个可以自动运行shell命令并帮助执行重复任务的程序。它通常用于将文件转换成其他形式,例如`将源代码文件编译成程序或库`

它通过跟踪先决条件和执行命令层次结构来生成目标来实现这一点。

尽管GNU Make手册很长,但我建议阅读一下,因为它是我找到的最好的参考:www.gnu.org/software/ma…

何时选择Make

  1. Make适用于构建小型C/ c++项目或库,这些项目或库将包含在另一个项目的构建系统中。大多数构建系统都有办法集成基于make的子项目。

对于较大的项目,您会发现更现代的构建系统更易于使用。

在以下情况下,我建议使用非Make的构建系统:
当正在构建的目标(或文件)数量为(或最终将为)数百时。 需要一个“配置”步骤,它设置和保存变量、目标定义和环境配置。 该项目将保持内部或私有,将不需要由终端用户构建。 您会发现调试是一项令人沮丧的工作。 您需要构建的是跨平台的,可以在macOS、Linux和Windows上构建。 在这些情况下,您可能会发现使用CMake、Bazel、Meson或其他现代构建系统是一种更愉快的体验。

调用Make

  1. 运行make将从当前目录加载一个名为Makefile的文件,并尝试更新默认目标(稍后会详细介绍目标),Make将依次搜索名为GNUmakefilemakefilemakefile的文件。<br /> 你可以使用-f/——file参数指定一个特定的makefile:<br /> $ make -f foo.mk

makefile

  1. # makefile
  2. FOO = 1
  3. BAR = $(FOO) # 将FOO变量指针赋值给BAR
  4. FOO = 2
  5. # $(info…)函数用于打印表达式,在调试makefile时非常方便!*’
  6. # 未显式、隐式或未自动设置的变量将计算为空字符串
  7. # 输出内容 "BAR=2"
  8. $(info BAR=$(BAR))
  9. FOO = 1
  10. BAR := $(FOO)
  11. FOO = 2
  12. # 输出内容 BAR=1
  13. $(info BAR=$(BAR))
  14. # 设置一个临时的环境变量用于测试
  15. # export TEXT_ENV=ABC
  16. # echo $TEXT_ENV
  17. $(info TEXT_ENV variable = $(TEXT_ENV))
  18. # 如果你使用?=赋值语法,Make只会在变量没有值的情况下赋值
  19. YOLO ?= "hello there!"
  20. # 执行此语句
  21. # make
  22. # 输出内容 YOLO variable = "hello there!"
  23. # 执行此语句
  24. # YOLO="abc" make
  25. # 输出内容 YOLO variable = "abc"
  26. $(info YOLO variable = $(YOLO))
  27. # 注意打印这个错误,Make打印“No targets”错误,因为我们的makefile没有列出目标!
  28. # make: *** No targets. Stop.
  29. TEXT += -efg
  30. # 执行此语句
  31. # TEXT='abc' make
  32. # 输出内容 TEXT variable = abc -efg
  33. $(info TEXT variable = $(TEXT))
  34. # 隐式变量
  35. # 这些都是由Make预先定义的(除非用同名的任何其他变量类型重写)。一些常见的例子:
  36. # $(CC) - the C compiler (gcc)
  37. # $(AR) - archive program (ar)
  38. # $(CFLAGS) - flags for the C compiler
  39. # Full list here:
  40. # 内置变量
  41. # $(CC) 指向当前使用的编译器,$(MAKE) 指向当前使用的Make工具
  42. # https://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html
  43. $(info CC variable = $(CC)) # 有默认值
  44. $(info AR variable = $(AR)) # 有默认值
  45. $(info CFLAGS variable = $(CFLAGS)) # 可能有默认值
  46. # <target> : <prerequisites>
  47. # [tab] <commands>
  48. # .PHONY 声明不指向文件 如果当前目录中,正好有一个文件叫做test,那么这个命令不会执行。
  49. # 因为Make发现clean文件已经存在,就认为没有必要重新构建了,就不会执行指定的rm命令。
  50. .PHONY: test
  51. test:
  52. # 注意命令这里,命令前面必须使用tab键,而不能是空格
  53. echo $@
  54. @echo $$PORT # 输出环境变量

假定当前目录下有 f1.c 和 f2.c 两个源码文件,需要将它们编译为对应的对象文件。
%.o: %.c
等同于下面的写法。
f1.o: f1.c
f2.o: f2.c