文章目录
1 makefile 基本结构
[变量定义和初始化] # 可选
目标: [依赖项]
指令
目标: [依赖项]
指令
... ...
注:指令可以是编译指令或其它可以在命令行运行的指令。定义变量后就可以在“目标-依赖-指令”中访问 $(var_name)
2 Makefile 实例
2.1 项目文件
文件结构:
- 入口文件:main.c
- 函数文件:addint.c, addfloat.c
文件内容:
main.c
#include <stdio.h>
extern int addint(int, int);
extern float addfloat(float, float);
int main(int argc, char** argv)
{
char** p;
int a = 100, b = 200;
float c = 222.2, d = 33.3;
printf("a+b=%d\n", addint(a,b));
printf("c+d=%f\n", addfloat(c,d));
printf("Your input strings are %d\n", argc);
printf("the content is: \n");
for (p=argv; p!=argv+argc; p++)
{
printf("%s\n", *p);
}
return 0;}
addint.c
int addint(int a, int b)
{
return a+b;
}
addfloat.c
int addfloat(float a, float b)
{
return a+b;}
2.2 makefile 编写(不生成库)
VPATH=.
TARGET=test
$(TARGET): main.o addint.o addfloat.o
gcc $^ -o$@
%.o: %.c
gcc -c $^ -o$@
.PHONY: clean
clean:
rm -rf *.o $(TARGET)
2.3 makefile 编写(生成动态库)
VPATH=.
TARGET=test
SLIB=libadd.so
$(TARGET): main.o $(SLIB)
gcc $< -o$@ -ladd -L.
$(SLIB): addfloat.o addint.o
gcc -fPIC -shared -o$@ $^
%.o: %.c
gcc -c $^ -o$@
.PHONY: clean
clean:
rm -rf *.o $(TARGET) $(SLIB)
2.4 makefile 编写(生成静态库)
VPATH=.
ALIB=libadd.a
$(TARGET): main.o $(ALIB)
gcc $^ -o$@
$(ALIB): addfloat.o addint.o
ar -rcs $@ $^
%.o: %.c
gcc -c $^ -o$@
.PHONY: clean
clean:
rm -rf *.o $(TARGET) $(ALIB)
3 复杂项目 makefile 编写
当项目文件很复杂时,不会把所有的文件都放在根目录下面,而是划分子目录分别存放。比如:
- src
- include
- obj
- bin
- my_lib
- src
- include
- obj
- lib
其中,my_lib 目录中的文件用于生成库,最终的程序以动态库或静态库链接的方式进行链接,将生成的程序放在 bin下。
# app项目的文件目录
INC_DIR=include
SRC_DIR=src
OBJ_DIR=obj
BIN_DIR=bin
# lib项目的文件目录
LIB_DIR=my_lib/lib # 生成的库的库路径
INC_DIR_2=my_lib/include
OBJ_DIR_2=my_lib/obj
SRC_DIR_2=my_lib/src
SRC=$(wildcard $(SRC_DIR)/*.c) # 获取app项目*.c文件集
OBJ=$(patsubst %.c, $(OBJ_DIR)/%.o, $(notdir $(SRC))) # 生成对应的目标文件集
SRC_2=$(wildcard $(SRC_DIR_2)/*.c)
OBJ_2=$(patsubst %.c, $(OBJ_DIR_2)/%.o, $(notdir $(SRC_2)))
ALIB=$(LIB_DIR)/libadd.a
SLIB=$(LIB_DIR)/libadd.so
#用于查看变量的值
# test: $(SRC)
# @echo $(SRC)
# @echo $(OBJ)
# @echo $(BIN_TARGET)
# @echo $(ALIB)
# @echo $(SLIB)
# @echo $(SRC_2)
# @echo $(OBJ_2)
TARGET=main
BIN_TARGET=$(BIN_DIR)/$(TARGET)
CFLAGS=-I$(INC_DIR) -I$(INC_DIR_2) -fPIC
all: $(OBJ_DIR) $(BIN_DIR) $(LIB_DIR) $(BIN_TARGET)
$(BIN_TARGET):$(OBJ) $(ALIB) $(SLIB)
gcc $(CFLAGS) $< -o$@ -ladd -L$(LIB_DIR)
$(OBJ_DIR)/%.o:$(SRC_DIR)/%.c
gcc $(CFLAGS) -c $< -o$@
$(OBJ_DIR_2)/%.o:$(SRC_DIR_2)/%.c
gcc $(CFLAGS) -c $< -o$@
$(ALIB): $(OBJ_2)
ar -rcs $@ $^
$(SLIB): $(OBJ_2)
gcc $(CFLAGS) -shared -o$@ $^
$(OBJ_DIR):
mkdir -p $(OBJ_DIR)
$(BIN_DIR):
mkdir -p $(BIN_DIR)
$(LIB_DIR):
mkdir -p $(LIB_DIR)
mkdir -p $(OBJ_DIR_2)
.PHONY: clean
clean:
rm -rf $(BIN_TARGET) $(OBJ) $(OBJ_2) $(ALIB) $(SLIB)