Makefile 简单使用教程

需求为以下的结构写一个Makefile

project
└───include
│   │   test1.h
│   │   test2.h
└───src
│   │   test1.cpp
│   │   test2.cpp
└───obj 
│   │   存放目标文件
└───Makefile
  1. 按照 Makefile 规则规规矩矩的写:
    all: test

    test: obj/test1.o obj/test2.o
      g++ -o test obj/test1.o obj/test2.o

    obj/test1.o: src/test1.cpp
      g++ -I ./ -c src/test1.cpp -o obj/test1.o

    obj/test2.o: src/test2.cpp
      g++ -I ./ -c src/test2.cpp -o obj/test2.o

  2. GCC中 -I、-L、-l 选项的作用
    在makefile中经常会看到这些选项,gcc默认会在程序当前目录、path路径中查找所需要的材料:

    1. -I (注意是大写的i) 给gcc添加自定义的头文件的路径
    2. -L 给gcc添加额外的搜索库的路径
    3. -l(小写的L) 给gcc 指定具体的库
  3. 通过Makefile的表示符改写:
    $@ 表示目标文件
    $^ 表示所有的依赖文件
    $< 表示第一个依赖文件
    改写如下:
    all: test

    test: obj/test1.o obj/test2.o
      g++ $^ -o $@

    obj/test1.o: src/test1.cpp
      g++ -I ./ -c $< -o $@

    obj/test2.o: src/test2.cpp
      g++ -I ./ -c $< -o $@

  4. 加入Makefile的通配符:

    $(addprefix , <name1 name2 …>) 功能:把加到name序列中的每一个元素前面。
    $(wildcard <pattern1 pattern2 …>) 功能:展开pattern中的通配符
    $(notdir <path1 path2 …>) 功能:去除路径名
    $(patsubst , , ) 功能: 替换通配符(pattern substitute)

    改写如下:
    CXX=g++
    CFLAGS = -I ./
    SRCDIR = ./src/
    OBJDIR=./obj/

    SOURCE := $(wildcard $(SRCDIR )*.cpp)
    FILES:= $(notdir $(SOURCE))
    OBJS := $(addprefix $(OBJDIR), $(patsubst %cpp, %o, $(FILES)))

    TARGETS := test

    1: all: clean obj $(TARGETS)

    2: $(TARGETS): $(OBJS)
        $(CXX) $^ -o $@

    3: $(OBJDIR)%.o: $(SRCDIR )%.cpp
        $(CXX) $(CFLAGS) -c $< -o $@

    4: obj:
        mkdir -p $(OBJDIR)

    5: clean:
        rm -rf $(OBJDIR)

    注解:
    1. all 当运行make(没有指定动作)的时候,会决定需要执行那些操作。这里面的定义了三个行为(clean、obj、test)
    2. $(TARGETS): $(OBJS) 表示的是目标文件需要的那些依赖,因为文件比较多,所以可以配合3一起使用, 当在找不到.o的文件的时候,就会向后寻找,%是一个通配符,找到3的时候就会执行g++指令,最后生成出来需要的.o文件。
    3. 配合2生成对应的.o文件
    4. 创建obj文件夹,将所有的.o文件放入
    5. 清理编译的中间文件。

gcc / g++执行编译的基本步骤主要有四步:
  第一步,由后缀为.c/.cpp的源程序生成后缀为.i的预处理文件,预处理文件本质也是c/cpp源程序,只是进行了头文件展开和宏替换;
    命令:g++ test.cpp -E -o test.i
  第二步,由后缀为.i的预处理文件生成后缀为.s的汇编文件,这一步是将源程序转化为汇编指令;
    命令:g++ -S test.cpp -o test.s
  第三步,由后缀为.s的汇编文件生成后缀为.o的机器代码,即二进制文件,但是这时候还不可以执行;
    命令:g++ -c test.cpp -o test.o
  第四步,把后缀为.o的机器代码链接生成可执行文件(默认后缀为.out);
    命令:g++ test.o -o test
  简单表示:①test.cpp(第一步)—>②test.i(第二步)—③test.s(第三步)—>④test.o(第四步)—>⑤test.out。
    命令:g++ test.cpp -o test
上面的每一条命令都包含前面的命令的功能(均可以单独使用).

参考:

  1. https://www.jianshu.com/p/4f524d837716
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值