• makefile中的特殊符号及关键字


    1.常见自动变量和含义

    • * :表示目标文件的名称,不包含目标文件的扩展名。
    • + :表示所有的依赖文件,这些依赖文件之间以空格分开,按照出现的先后为顺序,其中可能包含重复的依赖文件。
    • < :表示依赖项中第一个依赖文件的名称
    • ? : 依赖项中,所有目标文件时间戳晚的文件(表示修改过),依赖文件间以空格分开
    • @ :目标项中目标文件的名称
    • ^ :依赖项中,所有不重复的依赖文件,以空格分开。

    2.预定义变量 

     Makefile中常用的变量及含义

    AR 生成静态库库文件的程序名称 ar
    AS 汇编编译器的名称 as
    CC C语言编译器的名称 cc
    CPP C语言预编译器的名称 $(CC) -E
    CXX C++语言编译器的名称 g++
    FC FORTRAN语言编译器的名称 f77
    RM 删除文件程序的名称 rm -f
    ARFLAGS 生成静态库库文件程序的选项 无默认值
    ASFLAGS 汇编语言编译器的编译选项 无默认值
    CFLAGS C语言编译器的编译选项 无默认值
    CPPFLAGS C语言预编译器的编译选项 无默认值
    CXXFLAGS C++语言编译器的编译选项 无默认值
    FFLAGS FORTRAN语言编译器的编译选项 无默认值

    3.设置搜索路径

      指定需要搜索的目录, make 会自动找到指定文件的目录并添加到文件上。

    VPATH = path1:path2:...

    4.递归make

    对于规模比较大的程序,需要多个人在多个目录下进行开发。如果只用一个 Makefile 来维护就会比较麻烦,因此可以在每个目录下建立自己的 Makefile ,然后在总控 Makefile 中调用子目录的 Makefile 文件。

    目录结构如下:

    .
    ├── add
    │   ├── add_float.c
    │   ├── add.h
    │   ├── add_int.c
    │   └── Makefile
    ├── main.c
    ├── Makefile
    └── sub
        ├── Makefile
        ├── sub_float.c
        ├── sub.h
        └── sub_int.c

    1.递归调用的方式

    add:
        cd add && $(MAKE)

    它等价于

    add:
        $(MAKE) -C add

    2.总控Makefile

    CC = gcc
    CFLAGS = -O2
    TARGET = cacu
    export OBJSDIR = $(shell pwd)/objs
    
    $(TARGET):$(OBJSDIR) main.o
        $(MAKE) -C add
        $(MAKE) -C sub
        $(CC) -o $(TARGET) $(OBJSDIR)/*.o
    
    $(OBJSDIR):
        mkdir -p $@
    
    main.o:%.o:%.c
        $(CC) -c $< -o $(OBJSDIR)/$@ $(CFLAGS) -Iadd -Isub
    
    clean:
        -$(RM) $(TARGET)
        -$(RM) $(OBJSDIR)/*.o

    如果总控 Makefile 中的一些变量需要传递给下层的 Makefile,可以使用 export 命令。如:

    export OBJSDIR = ./objs

    3.子目录Makefile的编写

    Add 目录下的 Makefile 如下:

    OBJS = add_int.o add_float.o
    all:$(OBJS)
    
    $(OBJS):%.o:%.c
        $(CC) -c $< -o $(OBJSDIR)/$@ $(CFLAGS)
    
    clean:
        $(RM) $(OBJS)

    Sub 目录下的 Makefile 如下:

    OBJS = sub_int.o sub_float.o
    all:$(OBJS)
    
    $(OBJS):%.o:%.c
        $(CC) -c $< -o $(OBJSDIR)/$@ $(CFLAGS)
    
    clean:
        $(RM) $(OBJS)

    Makefile 中的函数

    1.获取匹配模式的文件名wildcard

    这个函数的功能是查找当前目录下所有符合模式 PATTERN 的文件名,其返回值是以空格分割的、当前目录下的所有符合模式 PATTERN 的文件名列表。其原型如下:

    $(wildcard PATTERN)

    例如,如下模式返回当前目录下所有扩展名位 .c 的文件列表。

    $(wildcard *.c)

    2.模式替换函数patsubst

    这个函数的功能是查找字符串 text 中按照空格分开的单词,将符合模式 pattern 的字符串替换成 replacement。 Pattern 中的模式可以使用通配符, % 代表 0 个到 n 个字符,当 pattern 和 replacement 中都有 % 时,符合条件的字符将被 replacement 中的替换。函数的返回值是替换后的新字符串。其原型如下:

    $(patsubst pattern, replacement, text)

    例如,需要将 C 文件替换为 .o 的目标文件可以使用如下模式:

    $(patsubst %.c, %.o, add.c)

    上面的模式将 add.c 字符串作为输入,当扩展名为 .c 时符合模式 %.c ,其中 % 在这里代表 add,替换为 add.o,并作为输出字符串。

    $(patsubst %.c, %.o, $(wildcard *.c))

    输出的字符串将当前扩展名为 .c 的文件替换成 .o 的文件列表。

    3.循环函数foreach

    这个函数的原型为:

    $(foreach VAR, LIST, TEXT)

    函数的功能为 foreach 将 LIST 字符串中一个空格分割的单词,先传给临时变量 VAR ,然后执行 TEXT 表达式, TEXT 表达式处理结束后输出。其返回值是空格分割表达式 TEXT 的计算结果。

    例如,对于存在 add 和 sub 的两个目录,设置 DIRS 为 "add sub ./" 包含目录 add、sub 和当前目录。表达式 $(wildcard $(dir)/*.c) ,可以取出目录 add 和 sub 及当前目录中的所有扩展名为 .c 的C语言源文件:

    DIRS = sub add ./
    FILES = $(foreach dir, $(DIRS), $(wildcard $(dir)/*.c))
    利用上面几个函数对原有的 Makefile 文件进行重新编写,使新的 Makefile 可以自动更新各个目录下的C语言源文件:

    CC = gcc
    CFLAGS = -O2 -Iadd -Isub
    TARGET = cacu
    DIRS = sub add .
    FILES = $(foreach dir, $(DIRS), $(wildcard $(dir)/*.c))
    OBJS = $(patsubst %.c, %.o, $(FILES))
    $(TARGET):$(OBJS)
    $(CC) -o $(TARGET) $(OBJS)
    
    clean:
    -$(RM) $(TARGET)
    -$(RM) $(OBJS)

    以上内容来源于:

    http://www.cnblogs.com/OpenShiFt/

    感谢分享!

     1 #该文件用于当前目录下的c文件均为一个单独的程序
     2 #后续可修改把目标文件通过参数指定
     3 cc = gcc
     4 #all:$(subst .c,.o,$(wildcard *.c))
     5 PROGS = client server
     6 all: $(PROGS)
     7 
     8 #%o:%.c
     9 #    gcc -o $@ $<
    10 %: %.c 
    11     $(cc) $(CFLAGS) $@.c -o $@ $(LDFLAGS) $(LDLIBS)
    12 
    13 clean:
    14     rm -f $(PROGS) $(TEMPFILES) *.o 

    以上的内容基本可以阅读大部分makefile了。

    更多关于makefiel函数的内容,下面的博文写的更全面。

    makefile中常用函数 - CSDN博客  https://blog.csdn.net/yangxuan0261/article/details/52060582

  • 相关阅读:
    iOS NSNotificationCenter 使用姿势详解
    iOS 数据源切换混乱问题
    iOS 内存管理的一点小问题
    iOS多线程GCD简介(二)
    iOS多线程GCD简介(一)
    iOS Touch Id 开发
    多线程之NSOperation简介
    开始Swift学习之路
    iOS自动布局学习(UIView+AutoLayout)
    善用#waring,#pragma mark 标记
  • 原文地址:https://www.cnblogs.com/mofei004/p/9639491.html
Copyright © 2020-2023  润新知