Make工具

1 总览

Makefile 是一段 “declarative” 的代码

  • 描述了构建目标之间的依赖关系和更新方法
  • 同时也是和 Shell 结合紧密的编程语言
    • 能够生成各种字符串
    • 支持 “元编程” (#include, #define, …)

以上内容将在下面的例子中加以体现

2 例子

# Code part1 := -> C #define
       NAME   := $(shell basename $(PWD))
export MODULE := Lab1

# Code part2 变量 -> 字面替换
all: $(NAME)-64 $(NAME)-32

# Code part3 include -> C #include
include ../Makefile

2.1 immediate assignment vs. recursive assignment

2.1.1 recursive assignment =

Using = causes the variable to be assigned a value. If the variable already had a value, it is replaced. This value will be expanded when it is used. For example:

HELLO = world
HELLO_WORLD = $(HELLO) world!

# This echoes "world world!"
echo $(HELLO_WORLD)

HELLO = hello

# This echoes "hello world!"
echo $(HELLO_WORLD)
2.1.2 immediate assignment :=

Using := is similar to using =. However, instead of the value being expanded when it is used, it is expanded during the assignment. For example:

HELLO = world
HELLO_WORLD := $(HELLO) world!

# This echoes "world world!"
echo $(HELLO_WORLD)

HELLO = hello

# Still echoes "world world!"
echo $(HELLO_WORLD)

HELLO_WORLD := $(HELLO) world!

# This echoes "hello world!"
echo $(HELLO_WORLD)

2.2 $(shell basename $(PWD))

  1. basename:
    • basename is a shell command that extracts the base name (last component) of a path.
  2. $(shell ...):
    • $(shell ...) is a Make function that allows you to execute shell commands within a Makefile.

2.3 export MODULE := Lab1

  • This line exports the variable MODULE with the value “Lab1.”
  • The export keyword makes the variable available to sub-makes (subdirectories) when they are invoked.
  • It makes MODULE a global constant.
  • Code part1 is equivalent to a C #define statement

2.4 all: $(NAME)-64 $(NAME)-32

  • This line defines a target named all that depends on two other targets: $(NAME)-64 and $(NAME)-32.
  • It is similar to a function call in C, where all is the function, and $(NAME)-64 and $(NAME)-32 are the arguments.
  • 进行了字面替换(Literal Substitution)

2.5 include ../Makefile

  • This line includes the contents of the Makefile in the parent directory.
  • It is equivalent to a C #include statement, allowing the Makefile to include additional rules and definitions from another file.

3 说明

  • Generating Strings(字符串生成) and Metaprogramming(元编程)
    • Makefiles are not just for specifying build rules; they are also a form of programming language. Makefiles can generate various strings dynamically during the build process.
    • Makefiles support a form of “metaprogramming” where you can use constructs like #include and #define to include external files or define macros, respectively.

4 在Makefile复杂时,如何应对

  1. 先观察 make 命令实际执行了什么 (trace)
    • make的主要功能:首先是Makefile描述了一个有向无环图,然后make工具会按照对应的拓扑排序的顺序去构建,同时忽略哪些不需要构建的目标
    • 那么我们可以按照trace去阅读Makefile,即可做到有的放矢,也可以知道Makefile中哪些执行了,哪些没有
  2. 再利用make 提供的两个有用的选项
    • -n or --just-print 只打印命令不运行
    • -B or --always-make 强制 make 所有目标
make -nB \
 | grep -ve '^\(\#\|echo\|mkdir\)' \
 | vim -
  1. 在进入了vim之后,就拥有了丰富的手段,用来调整文本,使得其可读性增加
    • :set nowrap 让一行文本避免折叠,连续一行显示

4.1 grep

  1. -v (or --invert-match):

    • This option inverts the sense of matching, meaning it selects lines that do not match the specified pattern for the example above.
    • For example, grep -v pattern will display lines that do not contain the specified pattern.
  2. -e (or --regexp):

    • This option allows you to specify a pattern or regular expression to search for in the input.
    • You can use multiple -e options to specify multiple patterns, and grep will match lines that contain any of the specified patterns.
  3. grep -ve '^\(\#\|echo\|mkdir\)

    • \ Backslash serves as an escape character.
    • ^ Anchors the pattern to the beginning of a line. It ensures that the pattern only matches lines where the specified sequences occur at the start
    • () Define a grouping in the regular expression. The escaped parentheses (\( and \)) are used to group multiple patterns together.
    • \ Acts as a logical OR in the regular expression. It allows the pattern to match lines that contain any of the alternatives separated by |.
    • This is a regular expression that matches lines starting with ‘#’, ‘echo’, or ‘mkdir’.

4.2 vim

- tells vim to read from standard input.

4.3 总结

在对make实际执行的结果进行grep的选择和vim的规整之后,可以发现(或者说是推测出)Makefile其实并不复杂(详见后续博客),就是一堆 gcc -c (编译) 和一个 gcc (链接) 。原来大部分 Makefile 都是编译选项

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值