1. 程式人生 > >makefile 簡單例項

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 $^ [email protected]

%.o: %.c
    gcc -c $^ [email protected]

.PHONY: clean

clean:
    rm -rf *.o $(TARGET)

2.3 makefile 編寫(生成動態庫)

VPATH=.
TARGET=test
SLIB=libadd.so

$(TARGET): main.o $(SLIB)
    gcc $< [email protected] -ladd -L.

$(SLIB): addfloat.o addint.o
    gcc -fPIC -shared [email protected] $^

%.o: %.c
    gcc -c $^ [email protected]

.PHONY: clean
clean:
    rm -rf *.o $(TARGET) $(SLIB)

2.4 makefile 編寫(生成靜態庫)

VPATH=.
ALIB=libadd.a

$(TARGET): main.o $(ALIB)
    gcc $^ [email protected]

$(ALIB): addfloat.o addint.o
    ar -rcs [email protected] $^

%.o: %.c
    gcc -c $^ [email protected]

.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) $< [email protected] -ladd -L$(LIB_DIR)


$(OBJ_DIR)/%.o:$(SRC_DIR)/%.c
    gcc $(CFLAGS) -c $< [email protected]

$(OBJ_DIR_2)/%.o:$(SRC_DIR_2)/%.c
    gcc $(CFLAGS) -c $< [email protected]

$(ALIB): $(OBJ_2)
    ar -rcs [email protected] $^

$(SLIB): $(OBJ_2)
    gcc $(CFLAGS) -shared [email protected] $^

$(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)