makefile备忘

结构描述

目标 … : 依赖 …
命令1
命令2
. . .

标记符

CFLAGS

$^ 表示所有的依赖文件
$@ 表示生成的目标文件
$< 代表第一个依赖文件

  • 调试信息选项:-g
  • 优化选项:-O
  • 编译警告选项:-Wall
  • 指定包含目录选项:-I
  • 指定库目录选项:-L
  • 指定库文件选项:-l
gcc -lSoTest -L./ main.c -o main
  • fPIC: 产生位置无关的代码
  • shared: 共享
gcc -shared -fPIC SoTest.c -o libSoTest.so

wildcard

1、wildcard : 扩展通配符
2、notdir : 去除路径
3、patsubst :替换通配符
例子:
建立一个测试目录,在测试目录下建立一个名为sub的子目录
$ mkdir test
$ cd test
$ mkdir sub
在test下,建立a.c和b.c2个文件,在sub目录下,建立sa.c和sb.c2 个文件
建立一个简单的Makefile

src=$(wildcard *.c ./sub/*.c)
dir=$(notdir $(src))
obj=$(patsubst %.c,%.o,$(dir) )
all:
@echo $(src)
@echo $(dir)
@echo $(obj)
@echo "end"

执行结果分析:
第一行输出:
a.c b.c ./sub/sa.c ./sub/sb.c
wildcard把 指定目录 ./ 和 ./sub/ 下的所有后缀是c的文件全部展开。
第二行输出:
a.c b.c sa.c sb.c
notdir把展开的文件去除掉路径信息
第三行输出:
a.o b.o sa.o sb.o
$(patsubst %.c,%.o,$(dir) )中,patsubst把$(dir)中的变量符合后缀是.c的全部替换成.o,
任何输出。
或者可以使用

obj=$(dir:%.c=%.o)

效果也是一样的。
这里用到makefile里的替换引用规则,即用您指定的变量替换另一个变量。
它的标准格式是

$(var:a=b)${var:a=b}

它的含义是把变量var中的每一个值结尾用b替换掉a
SRC = $(wildcard *.c)
等于指定编译当前目录下所有.c文件,如果还有子目录,比如子目录为inc,则再增加一个wildcard函数,象这样:
SRC = $(wildcard *.c) $(wildcard inc/*.c)
也可以指定汇编源程序:
ASRC = $(wildcard *.S)

变量赋值

1、"="延迟赋值 是最普通的等号在Makefile中容易搞错赋值等号使用 “=”进行赋值变量的值是整个Makefile中最后被指定的值。

VIR_A = A
VIR_B = $(VIR_A) B
VIR_A = AA

经过上面的赋值后最后VIR_B的值是AA B而不是A B在make时会把整个Makefile展开来决定变量的值
  2、":="立即赋值 表示直接赋值赋予当前位置的值。

VIR_A := A
VIR_B := $(VIR_A) B
VIR_A := AA

最后BIR_B的值是A B即根据当前位置进行赋值。因此相当于“=”“=”才是真正意义上的直接赋值
  3、"?="空赋值 表示如果该变量没有被赋值赋值予等号后面的值。

VIR ?= new_value

如果VIR在之前没有被赋值那么VIR的值就为new_value。

VIR := old_value
VIR ?= new_value

这种情况下VIR的值就是old_value
  4、"+="追加赋值 和平时写代码的理解是一样的表示将符号后面的值添加到前面的变量上

指定头文件路径

一般都是通过"-I"大写i来指定假设头文件在
/home/develop/include
则可以通过-I指定

-I/home/develop/include

将该目录添加到头文件搜索路径中
在Makefile中则可以这样写

CFLAGS=-I/home/develop/include

然后在编译的时候引用CFLAGS即可如下

yourapp:*.c
    gcc $(CFLAGS) -o yourapp

指定库文件路径

与上面指定头文件类似只不过使用的是"-L"来指定

LDFLAGS=-L/usr/lib -L/path/to/your/lib

告诉链接器要链接哪些库文件使用"-l"小写L如下

LIBS = -lpthread -liconv

你可能感兴趣的:(linux,c++,c语言)