7

Makefile的简单编写

 2 years ago
source link: https://kiprey.github.io/2020/06/MakefileIntroduce/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
  • 在Unix下的代码编译中,Makefile指定了一系列代码编译的规则。
  • 在编写好Makefile后,只需执行make便可轻松编译

Makefile以下述的规则编写:

# 目标文件:依赖文件
# (tab)编译命令

# 目标文件:main
# 依赖文件:main.o add.o mul.o sub.o div.o
# 编译命令:g++ -o main add.o mul.o sub.o div.o main.o
main:main.o add.o mul.o sub.o div.o
g++ -o main add.o mul.o sub.o div.o main.o

3. 变量、符号与函数

a. 变量的使用

  • 变量无需声明,可直接使用
  • 若其他位置需要该变量时,则必须以$(Variable)的形式引用
VIR_A = A
VIR_B = $(VIR_A) B
    • = : 最容易出错 的赋值等号

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

      最后VIR_B的值是AA B,而不是A B
      在make时,会把整个makefile展开,最后决定变量的值

    • ?= : 如果没有被赋值过,则赋值等号后面的操作

    • += : 追加(append)

    • := : 正常 的赋值

  • 特殊符号:

    • % : 通配符

    • %0 : 执行时的第一个参数

    • $@ : 目标文件

    • $< : 第一个依赖文件

    • $^ : 所有的依赖文件

    • $$ : 与$等价

    • a.out: a.c b.c
      @echo '$$@='$@ # $@=a.out
      @echo '$$<='$< # $<=a.c
      @echo '$$^='$^ # $^=a.c b.c

c. 内置函数

注:函数调用中不能在参数中添加空格,因为空格也会被视为参数的一部分

  • addprefix

    • 格式:$(addprefix prefix,<names...>)
    • 功能:为文件序列添加前缀
    Variable := $(addprefix src/,foo bar)
    # Variable ==> src/foo src/bar
  • addsuffix

    • 格式:$(addsuffix addsuffix,<names...>)
    • 功能:为文件序列添加后缀
    Variable := $(addsuffix .c,foo bar)
    # Variable ==> foo.c bar.c
  • basename

    • 格式:$(basename <names...>)
    • 功能:从文件名序列中取出各个文件名的前缀部分(除去扩展名后的剩余部分)
    Variable := $(basename src/foo.c src-1.0/bar.c hacks)
    # Variable ==> src/foo src-1.0/bar hacks
  • notdir

    • 格式:$(notdir <names...>)
    • 功能:文件名列表中去除所有的目录信息,只保留文件名
    # 去除所有的目录信息,返回的文件名列表将只有文件名
    SRC = $(notdir wildcard)
  • shell

    • 功能:执行shell命令<myCommand>并返回输出结果
    • 格式:$(shell <myCommand>)

    注:每行的shell都是一个单独的进程

    CXXFLAGS := $(shell llvm-config --cxxflags)
  • subst

    • 功能:把字符串<text>中的<from>字符串替换成<to>
    • 格式:$(subst <from>,<to>,<text>)
    # 注:无需引号
    Origin := There is a big tree
    Result := $(subst a,the, $(Origin))
    # Result ==> There is the big tree
  • wildcard

    在Makefile规则中,通配符会被自动展开。但在变量的定义和函数引用时,通配符将失效。

    • 功能:函数引用时使通配符有效
    • 格式:$(wildcard <PATTERN...>)
    # 生成一个以空格间隔的后缀为.c的文件名列表
    Variable := $(wildcard *.c)

4. 简单的例子

命令行输入make <targetFile>即可对特定目标文件进行编译。

例:make all、make main、make clean(clean比较特殊)

#获取.cpp文件
SrcFiles=$(wildcard *.cpp)
#使用替换函数获取.o文件
ObjFiles=$(patsubst %.cpp,%.o,$(SrcFiles))
#生成的可执行文件
all:main
#目标文件依赖于.o文件
main:$(ObjFiles)
g++ -o $@ -I ../include $(SrcFiles)
#.o文件依赖于.cpp文件,通配使用,一条就够
%.o:%.cpp
g++ -c -I ../include $<

.PHONY:clean all

clean:
rm -f *.o
rm -f main

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK