Makefile 简单总结

准备

要看懂Makefile 首先得知道gcc怎么用吧?根据gcc –h的的内容可以看出,编译过各分为4个步骤:

  1. 预处理(preprocess) ,使用-E 选项,替换宏定义和头文件,默认输出到标准输出,不生成文件。
  2. 编译(compile),使用-S选项,生成汇编文件。
  3. 汇编(assemble),使用-c选项,成生目标文件。
  4. 连接(link),不添加选项,生成可执行文件。

实际上gcc会调不同的处理程序来完成这些任务,但这里不用管它。除了这些,还有一些常用的选项:

选项—————-说明
-o指定目标的名称,上面4个步骤中,除了1,都有默认的名称。如果想修改名称,就可以使用这个选项,包 括指定预处理的目标
-g给目标文件加上调试信息,只有这样才能被GDB调试。如果是-ggdb的话,将尽可能的生成gdb的可以使用的调试信息
-v显示编译器的版本信息
-I (大写的i)添加头文件的搜索路径
-L添加库文件的路径,也可以修改环境变量LD_LIBRARY_PATH
-l(小写的L)在链接动态库文件时,除了指定路径,还需要指定其名字,编译器查找动态库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so或者.a来确定库的名称,默认优先选择.so,加-static时,只链接.a
-static禁止使用共享连接
-shared生成共享目标文件。通常用在建立共享库时
-w不生成任何警告信息
-Wall生成所有警告信息
-werror把所有的告警信息转化为错误信息,并在告警发生时终止编译过程
-D添加宏定义
-pthread链接 POSIX thread 库,相对于-lpthread,增加了_REENTRANT宏定义。推荐使用-pthread

符号

main: main.c util.c defs.h
    gcc -o $@ $^

$@ 代表目标文件main
$^ 代表所有的依赖文件main.c util.c defs.h
$< 代表第一个依赖文件main.c

函数

#这两种方法都能得到指定目录下的所有.c文件
SOURCES = $(shell ls *.c  ./sub/*.c)
SOURCES = $(wildcard *.c ./sub/*.c)

#去掉路径信息
FILES = $(notdir $(SOURCES))

#更改后缀(只是为了得到一组文件名,不会更改原文件)
PROGRAMS = $(FILES :.c=) #去掉后缀
OBJ=$(FILES :.c=.o) #更改
#或者使用patsubst函数
OBJ=$(patsubst *.c *.o $(FILES))

简要说明

CFLAGS=-g
#定义变量
objects = main.o command.o
#第一个目标为最后生成的目标
edit : $(objects)
    cc -o $@ $^ #cc是unix中常用编译器,linux下指向gcc.

main.o : main.c defs.h
    cc -c main.c
command.o : command.c defs.h command.h
    cc -c command.c

#.PHONY表示,clean是个伪目标文件,可以理解为是一个动作,一般用来清除make生成的文件。也可以是其它名字,通过make xxx来执行。
.PHONY clean
clean :
    -rm edit $(objects) #减号表示忽略错误

make能自动推导和.o文件相同文件名的.c文件。于是可以简化成这样子:

objects = main.o command.o
edit : $(objects)
    cc -o edit $(objects)
main.o : defs.h
command.o :defs.h command.h
.PHONY clean
clean :
    -rm edit $(objects)

其中main.o 和 command.o都依赖了defs.h, 可以写成这样(不推荐这种写法,易混乱):

objects = main.o command.o
edit : $(objects)
    cc -o edit $(objects)
main.o command.o : defs.h
command.o :command.h
.PHONY clean
clean :
    -rm edit $(objects)

单目录下通用的Makefile

#for c
EXE=main
CC=gcc
SRC=$(wildcard *.c)
OBJ=$(SRC:.c=.o)
DEP=$(patsubst %.c,.%.d,$(SRC))
CFLAGS=-g
$(EXE):$(OBJ)
    $(CC) $^ -o $@

$(DEP):.%.d:%.c
    @set -e;\
    rm -f $@;\
    $(CC) -M $< > $@.$$$$;\
    sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@;\
    rm -f .*.d*

-include $(DEP)

clean:
    @rm $(EXE) $(OBJ) $(DEP) -f

#for c++
EXE=main
CC=g++
SRC=$(wildcard *.cpp)
OBJ=$(SRC:.cpp=.o)
DEP=$(patsubst %.cpp,.%.d,$(SRC))
CFLAGS=-g
$(EXE):$(OBJ)
    $(CC) $^ -o $@

$(DEP):.%.d:%.cpp
    @set -e;\
    rm -f $@;\
    $(CC) -MM $< > $@.$$$$;\
    sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@;\
    rm -f .*.d*

-include $(DEP)

clean:
    @rm $(EXE) $(OBJ) $(DEP) -f

其它细节

  1. make 支持的默认文件名:”GNUmakefile”、”makefile”、”Makefile”, 可以用make -f filename指定makefile.
  2. include foo.mk 包含其它makefile文件
  3. 默认会include 环境变量MAKEFILES 中的makefile,不建议设置这个变量。

参考链接

一个简单的通用Makefile实现
自动处理依赖
Makefile的函数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值