Makefile学习分享

文章目录

    • 背景
    • 引人入题
    • 目标
    • 一些前置知识
      • gcc命令的一些技巧
    • 一些内置变量/特殊写法/命令选项
    • 使用变量
      • = 延迟求值
      • := 即时求值
      • ?= 设置默认值
      • += 追加
    • 使用条件判断
    • 使用函数
    • 模式规则
    • 伪目标
    • 周边
    • 参考

背景

最近在部门内做了一个有关Makefile的分享, 不涉及商业隐私, 发出来大家一起学习。
文中有一些需要查看具体文件的,可查看: https://github.com/GerryLon/learn-Makefile

引人入题

有人说, linux下源码安装软件就是"三步走"

./configure

make

make install

真的是这样吗? 为什么?

目标

  • 希望大家都能用上, 提高工作效率!
  • 了解到周边的东西, 开阔视野!

一些前置知识

gcc编译的4个阶段(示例文件位于: gcc-4-stages)

Makefile学习分享_第1张图片

gcc命令的一些技巧

自动找出依赖:

# redis中的Makefile.dep用到了这个技巧
$ gcc -MM main.c 
main.o: main.c

$ gcc -M main.c 
main.o: main.c /usr/include/stdc-predef.h /usr/include/stdio.h \
 /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \
 /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \
 /usr/include/x86_64-linux-gnu/bits/wordsize.h \
 /usr/include/x86_64-linux-gnu/bits/long-double.h \
 /usr/include/x86_64-linux-gnu/gnu/stubs.h \
 /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \
 /usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h \
 /usr/lib/gcc/x86_64-linux-gnu/8/include/stdarg.h \
 /usr/include/x86_64-linux-gnu/bits/types.h \
 /usr/include/x86_64-linux-gnu/bits/typesizes.h \
 /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \
 /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \
 /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \
 /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \
 /usr/include/x86_64-linux-gnu/bits/types/FILE.h \
 /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \
 /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \
 /usr/include/x86_64-linux-gnu/bits/sys_errlist.h

一些内置变量/特殊写法/命令选项

命令开始的空白应该是tab, 而不是空格!!!

$@ 是目标

$< 是第一个源

$^ 是所有的源,因此当只有一个源的时候,和$<是相等的

special-chars-target: spe1 spe2
	@echo "\$$@:" $@
	@echo "\$$^:" $^
	@echo "\$$<:" $<

spe1:
	@echo "spe1 target"

spe2:
	@echo "spe2 target"

# 执行测试
# $ make special-chars-target
# spe1 target
# spe2 target
# $@: special-chars-target
# $^: spe1 spe2
# $<: spe1

@command 这种写法表示不显示执行的命令

-command 这种写法表示不管命令出不出错都认为是成功(退出码为0)的

-n / --just-print 如果 make 执行时,带入 make 参数“-n”或“–just-print”,那么其只是显示命令,
但不会执行命令,这个功能很有利于我们调试我们的 Makefile,看看我们书写的命令是执
行起来是什么样子的或是什么顺序的。

-s / --silent 全面禁止命令的显示。

CC 默认为gcc

RM 默认为rm -f

使用变量

= 延迟求值

# 演示使用变量之 =
Options = -l $(Options_part)
Options_part = -i -a
var:
	@echo $(Options)
	@ls $(Options) /etc | head -5

:= 即时求值

# 演示使用变量之 :=
Options2 := -l $(Options2_part)
Options2_part = -i -a
var2:
	@echo $(Options2)
	@ls $(Options2) /etc | head -5

?= 设置默认值

# 演示使用变量之 ?=
#PREFIX = /opt/soft
PREFIX ?= /usr/local
default-value:
	echo $(PREFIX)

+= 追加

# 追加 +=
append_value = a b
append_value += c d
append-target:
	@echo $(append_value)

使用条件判断

ifeq, ifneq, ifdef, ifndef

使用函数

  • $(subst ,,)

    普通替换

     # 把“feet on the street”中的“ee”替换成“EE”,返回结果是“fEEt on the strEEt”。 
    $(subst ee,EE,feet on the street)
    
  • $(patsubst ,,)

    模式替换

    # 把字串“x.c.c bar.c”符合模式[%.c]的单词替换成[%.o],返回结果是“x.c.o bar.o” 
    $(patsubst %.c,%.o,x.c.c bar.c) 
    
  • $(strip )

    有的语言也叫trim()

    $(strip a b c ) 
    把字串“a b c ”去到开头和结尾的空格,结果是“a b c”。
    
  • $(shell command)

    shell 函数把执行操作系统命令后的输出作为函数返回

    contents := $(shell cat /etc/passwd) 
    
  • $(error ), $(warning )

    error()会产生致命错误,致使make退出. 而warning()只是输出警告.

    调试输出

    error-target:
    	$(error "fatal error...")
    	echo "the end"
    
    warning-target:
    	$(warning "warning msg...")
    	@echo "continue"
    

模式规则

查看目录pattern-demo来说明

模式规则中,至少在规则的目标定义中要包含"%",否则,就是一般的规则。目标中的
“%“定义表示对文件名的匹配,”%“表示长度任意的非空字符串。例如:”%.c"表示以”.c"结
尾的文件名(文件名的长度至少为 3),而"s.%.c"则表示以"s.“开头,”.c"结尾的文件名(文
件名的长度至少为 5)。

%.css: %.less
	$(LESSC) $< $@

上面的例子表示: 将所有的.less文件, 使用lessc命令转换为.css文件

伪目标

一个"假"的目标, 不是一个真实的文件

.PHONY: clean
clean:
	rm -f *.tmp

周边

  • maven /ˈmeɪvn/ 专家; 内行; pom.xml

    Apache Maven is a software project management and comprehension tool.

  • ant build.xml

    Apache Ant is a Java library and command-line tool whose mission is to drive processes described in build files as targets and extension points dependent upon each other.

  • cmake CmakeLists.txt

    CMake is an open-source, cross-platform family of tools designed to build, test and package software.

  • gulp gulpfile.js

    gulp 将开发流程中让人痛苦或耗时的任务自动化,从而减少你所浪费的时间、创造更大价值。

  • webpack weback.config.js

    webpack is a static module bundler for modern JavaScript applications.

More…

参考

  • [The Four Stages of Compiling a C Program](https://www.calleerlandsson.com/the-four-stages-of-compiling-a-c-program/#:~:text=At an overview level%2C the,compilation%2C assembly%2C and linking.)
  • 《跟我一起写Makefile-陈皓》

你可能感兴趣的:(Makefile,项目构建)