makefile 簡單實例

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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章