Makefile

简介:

  makefile可以理解为是一门脚本语言,按照我们设定的步骤一步步运行指令。在linux开发过程中没有像Windows那样的图形化一键编译的功能,在linux上的c语言程序开发使用的是gcc编译工具完成源码文件到二进制文件的转变。当工程比较大的时候,工程里有很多源文件、头文件、第三方库等等,如果我们还是用gcc命令来编译的话会显得很麻烦,也容易出错。
  这时候我们可以使用makefile工具来帮助我们完成工程代码的编译,直接使用make命令即可完成全自动编译过程。在书写makefile过程中一定要遵循它的规则,否则会出现错误的情况。

基本规则:

目标 : 依赖
[tab]命令

例如main.c源文件生成main二进制可执行文件:

main : main.o
	gcc main.o -o main
	
main.o :main.c
	gcc -c main.c -o main.o
clear:
	rm *.o main

基本模板

简单c代码工程如下:

文件夹描述
inc存放工程头文件
lib存放动态、静态库文件
src源文件

Makefile文件与inc、lib、src文件夹同一目录下:
在这里插入图片描述

Makefile 文件内容:

CC = gcc
SRC = $(wildcard src/*.c)
OBJ = $(patsubst %.c, %.o, $(SRC))
TARGET = main
INC_PATH = -I inc/

#links
$(TARGET) : $(OBJ)
        $(CC) $(OBJ) -o $(TARGET)

#compile
%.o : %.c
        $(CC) -c $< -o $@ $(INC_PATH)

.PHONY:clean
clean:
        @echo "Remove linked and compiled files......"
        @rm -rf $(OBJ) $(TARGET)

简单解释一下:

  变量CC是为了指定编译器,SRC是指定源码文件路径,OBJ是指定 .o 依赖文件,TARGET是指定生成的目标文件名,INC_PATH 是指定头文件路径

wildcard和patsubst 都来自makefile内置的函数,wildcard是通过匹配符将所有的 .c 文件存放到变量$(SRC)中,patsubst 是将所有的 .c 文件改为后缀 .o 文件

%.o 和 %.c 通用匹配,比如main.o的依赖文件就是main.c,add.o的依赖文件就是add.c
   $<  :代表第一个依赖文件
   $@ :代表目标文件

最后是clean,用于删除编译过程中生成的中间文件和可执行文件。

动态库和静态库的生成

静态库:
  静态库可以由一个或多个 .c 源文件构成,他人使用时只需要提供 .a 静态库文件和 .h 头文件即可。静态库在链接过程中就已经引用到二进制可执行文件中去了,文件比较大,不易更新。

原理:
  1、先生成 .o 文件:  gcc -c add.c -o add.o
  2、生成静态库:    ar rcs add.a add.o

# static lib
static_OBJ     = src/add.o
static_TARGET  = lib/static/libadd.a
INC_PATH       = -I inc/

# static
$(static_TARGET):$(static_OBJ)
	ar rcs $(static_TARGET) $(static_OBJ)

#compile
%.o : %.c
	$(CC) -c $< -o $@ $(INC_PATH)
	
.PHONY:clean
clean:
	@echo "Remove linked and compiled files......"
	@rm -rf $(static_OBJ) $(static_TARGET)

动态库:
  动态库也可以由一个或多个 .c 源文件构成,使用时只需要提供 .so和 .h 文件。动态库是在二进制可执行文件运行时才会链接,不使用不会链接。优点是文件小、移植性强。

原理:
   gcc src/mul.c -fPIC -shared -I inc/ -o lib/shared/libmul.so
makefile不过是分成了两步来完成

# shared lib
shared_OBJ     = src/mul.o
shared_TARGET  = lib/shared/libmul.so
CC			   = gcc
INC_PATH       = -I inc/

# shared
$(shared_TARGET):$(shared_OBJ)
	$(CC) $(shared_OBJ) -fPIC -shared -o $(shared_TARGET)

#compile
%.o : %.c
	$(CC) -c $< -o $@ $(INC_PATH)

.PHONY:clean
clean:
	@echo "Remove linked and compiled files......"
	@rm -rf $(shared_OBJ) $(shared_TARGET)

链接动静态库

动态库和静态库的链接:

静态库:
   gcc main.c -ladd -L lib/static -o main
   add是静态库名,-L 指定静态库地址
动态库:
   gcc main.c -lmul -L lib/shared -Wl,-rpath=lib/shared -o main
   mul是动态库名,-L 指定动态库地址, -Wl,-rpath= 指定运行时链接地址

CC = gcc
SRC = $(wildcard src/*.c)
OBJ = $(patsubst %.c, %.o, $(SRC))
TARGET = main
INC_PATH = -I inc/

LIB_NAMES = -ladd -lmul
LIB_PATH = -L lib/static -L lib/shared 
LIB_SO_PATH = -Wl,-rpath=lib/shared

#links
$(TARGET) : $(OBJ)
	$(CC) $(OBJ) $(LIB_NAMES) $(LIB_PATH) $(LIB_SO_PATH) -o $(TARGET)

#compile
%.o : %.c
	$(CC) -c $< -o $@ $(INC_PATH)

.PHONY:clean
clean:
	@echo "Remove linked and compiled files......"
	@rm -rf $(OBJ) $(TARGET)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值