zoukankan      html  css  js  c++  java
  • 5makefile

    makefile编译多个可执行文件
    1: 多个 C 文件编译成不同的目标文件
    2: 多个 C 文件编译成 一个目标文件


    注意:makefile的文件名的三种形式(优先级排序)
    makefile>Makefile>GNUMakefile

    简单说,makefile类似快捷键。
    如:创建主函数文件mian.c 函数文件func.c
    编译二进制:
    gcc -g -Wall -c main.c -o mian.o
    gcc -g -Wall -c func.c -o func.o
    链接并生成可执行文件:
    gcc -Wall main.o func.o -o main
    此时可以看到只用两个文件都如此麻烦,一旦许多文件呢?或对mian.c进行修改后,还要再一次编译

    解决方式:
    创建一个makefile的文件:
    main:main.o func.o
    gcc -g -Wall mainn.o func.o -o main
    main.o:main.c
    gcc -g -Wall -c mainn.c func.o -o main.o
    func.o:func.c
    gcc -g -Wall -c func.c func.o -o func.o

    执行:make
    解析:
    main依赖于main.o func.o,一定要就此句在第一个。因此makefile只编译第一个语句。main.o,func.o将会向下寻找。即使重新修改文件内容,只需再一次make就自动编译
    如果:
    main.o:main.c
    gcc -g -Wall -c mainn.c func.o -o main.o
    main:main.o func.o
    gcc -g -Wall mainn.o func.o -o main
    func.o:func.c
    gcc -g -Wall -c func.c func.o -o func.o
    此时,只编译
    main.o:main.c
    gcc -g -Wall -c mainn.c func.o -o main.o
    后面两个不进行编译。

    make工具
    自动完成编译工作
    1:修改某个文件后,只重新编译修改的文件
    2:修改某个头文件后,重新编译所有包含该头文件的文件

    makefile 描述了整个工程编译,链接的规则
    make工具通过makefile文件来完成、维护编译工作


    makefile基本规则
    Target ... : dependencies ...
    [ Tab ] command
    ...

    Target: 程序生成的文件,或者要指向的动作,如clean
    dependencies:目标文件依赖的文件
    command:make执行的动作(以 TAB字符开始!!!)
    dependencies 中文件更新时候,执行command


    例子:
    main:main.o add.o sub.o
    gcc -Wall -g main.o sub.o add.o -o main
    main.o:main.c
    gcc -Wall -g -c main.c -o main.o
    add.o:add.c add.h
    gcc -Wall -g -c add.c -o add.o
    sub.o:sub.c sub.h
    gcc -Wall -g -c sub.c -o sub.o
    clean:
    rm -f main main.o add.o sub.o

    make ==》按需生成文件
    make ==》修改时间未改变,则不会重新编译
    make ... 生成某个目标(或者伪目标clean),不加则默认生成第一个模板


    显式指定伪目标
    上面的makefile文件,如果目录下存在clean文件
    结果: make clean失效
    解决办法:需要显示指定 clean 是伪目标, 文件开头加上:.PHONY:clean
    .PHONY: 表示这是一个伪目标


    定义变量
    makefile自动化变量
    $@: 规则的目标文件名
    $< : 规则的第一个依赖文件名
    $^ : 规则的所有依赖文件列表

    举例 add.o:add.c add.h
    $@ 为 add.o
    $< 为 add.c
    $^ 为 add.c add.h
    自定义变量
    var=....... ? 使用变量 $(var)

    使用变量的例子:
    .PHONY:clean
    OBJ=main.o add.o sub.o
    main:$(OBJ)
    gcc -Wall -g $^ -o $@
    main.o:main.c
    gcc -Wall -g -c $< -o $@
    add.o:add.c add.h
    gcc -Wall -g -c $< -o $@
    sub.o:sub.c sub.h
    gcc -Wall -g -c $< -o $@
    clean:
    rm -rf $(OBJ)

    改进:
    .PHONY:clean
    BIN=main
    CC=gcc
    CFLAGS=-Wall -g
    OBJ=main.o add.o sub.o
    $(BIN):$(OBJ)
    $(CC) $(CFLAGS) $^ -o $@
    main.o:main.c
    $(CC) $(CFLAGS) -c $< -o $@
    add.o:add.c add.h
    $(CC) $(CFLAGS)-c $< -o $@
    sub.o:sub.c sub.h
    $(CC) $(CFLAGS) -c $< -o $@
    clean:
    rm -rf *.o $(BIN)


    自定义的变量一般使用大写。
    注意:通过 –f 参数,指定需要用到的makefile文件make –f makefile.1 自定义使用的makefile文件


    自动推导
    编译器会自动推导,
    同名的 .c 文件生成同名目标文件
    默认使用隐含方式生成,不想使用自动推导则自行添加生成方式
    cc –c –o xxx.o xxx.c

    模式匹配
    规则 1:
    %.o:%.c
    gcc -Wall -g -c $< -o $@

    规则2:
    .c.o:
    gcc -Wall -g -c $< -o $@
    规则2注意 .c.o之间不能由空格


    编译目录下所有.c 文件
    $(BIN):%:%.o
    所有的 $(BIN) 文件生成规则:
    $(BIN)中没有扩展名的文件依赖于对应扩展名为.o 的文件

    编译多个可执行文件
    makefile 默认生成第一个对象
    要生成对个对象的话,可以使用自定义变量
    .PHONY:clean all
    OBJ=test1 test2
    all:$(OBJ)
    ...
    这里: all 是一个伪目标,makefile 要生成 all, 也就是 test1, test2


    make常用内嵌函数
    函数调用
    $(function arguments)
    $(wildcard 模式)
    当前目录下匹配模式的文件:
    获取所有.c文件
    src = $(wildcard *.c)

    把src的 .c替换为.o
    $(src :%.c=%.o)
    obj = $(src:%.c=%.o)

    shell函数
    执行shell命令: $(shell ls –d */) 获取所有子目录

    例子改进:
    .PHONY:clean all
    SRC=$(wildcard *.c)
    OBJ=$(SRC:%.c=%.o)
    BIN=$(SRC:$.c=%)

    CC=gcc
    CFLAGS=-Wall -g

    all:$(BIN)
    %.o:%.c
    $(CC) $(SFLAGS) $^ -o %@
    clean:
    rm -f $(BIN) $(OBJ)


    多级目录makefile
    SUBDIRS=test1 test2
    .PHONY:default all clean $(SUBDIRS)
    default:all #无参数,则生成all

    all clean: #all 和 clean都依赖下面语句
    $(MAKE) $(SUBDIRS) TARGET=$@ #make test1 test2 ;赋值 TARGET=all
    $(SBUDIRS):
    $(MAKE) -C $@ $(TARGET)
    #make –C test1 all: 调用test1中make,并以all为入参。 make test1/makefile all
    注意-C大写

    C语言版
    makefile万能模板:

    .PHONY:clean all
    SRC=$(wildcard *.c)
    BIN=$(SRC:%.c=%)

    CC=gcc
    CFLAGS=-g -Wall

    all:$(BIN)

    clean:
    rm -rf $(BIN)
    ~

    C++版
    .PHONY:all clean

    SRC=$(wildcard *.c)
    BIN=$(SRC:%.c=%)

    CPPSRC=$(wildcard *.cpp)
    CPPBIN=$(CPPSRC:%.cpp=%)

    CC=gcc
    CXX=g++
    CFLAGS=-g -Wall
    CXXFLAGS=-g -Wall -std=c++11

    all:$(BIN) //$(CPPBIN)

    clean:
    rm -rf $(BIN) //$(CPPBIN)

  • 相关阅读:
    互斥量
    读写锁
    死锁
    pthread
    线程
    守护进程
    信号捕捉
    信号集
    信号
    mmap
  • 原文地址:https://www.cnblogs.com/gd-luojialin/p/9215941.html
Copyright © 2011-2022 走看看