工程中編寫自己的makefile---2 實例

1        實例來學習使用方法

需要準備的工程目錄結構如下

.

├── add

│   ├──add_float.c

│   ├──add.h

│   └──add_int.c

├── main.c

└── sub

    ├── sub_float.c

    ├── sub.h

    └── sub_int.c

文件編譯爲可執行文件xxxx

1.1             命令行編譯程序

[root@9527 5]# gcc -c add/add_int.c -o add_int.o -ggdb

[root@9527 5]# gcc -c sub/sub_int.c -o sub_int.o -ggdb

[root@9527 5]# gcc -c add/add_float.c -o add_float.o -ggdb

[root@9527 5]# gcc -c sub/sub_float.c -o sub_float.o -ggdb

[root@9527 5]# gcc -c main.c -o main.o -Iadd -Isub -ggdb

[root@9527 5]# gcc -o xxxx main.o sub_int.o sub_float.oadd_int.o add_float.o -ggd

[root@9527 5]# ./xxxx

float x-y IS:0.000000

int a+b IS:22

int a-b IS:-2

float x+y IS:11.110000

float x-y IS:0.000000

float x-y IS:-8.642000

-ggdb使 GCC 爲 GDB 生成專用的更爲豐富的調試信息,但是,此時就不能用其他的調試器來進行調試了 (如 ddx)

1.2             使用make進行項目管理

編寫Makefile,把上面的指令按makefile格式寫下即可

xxxx:sub_int.o sub_float.o add_int.o add_float.o main.o

    @gcc -o xxxx main.osub_int.o sub_float.o add_int.o add_float.o -ggdb

 

add_float.o:add/add_float.c

    @gcc -c add/add_float.c-o add_float.o -ggdb

 

add_int.o:add/add_int.c

    @gcc -c add/add_int.c-o add_int.o -ggdb

 

sub_float.o:sub/sub_float.c

    @gcc -c sub/sub_float.c-o sub_float.o -ggdb

 

sub_int.o:sub/sub_int.c

    @gcc -c sub/sub_int.c-o sub_int.o -ggdb

 

main.o:main.c

    @gcc gcc -c main.c -omain.o -Iadd -Isub -ggdb

 

.PHONY:clean

clean:

    @rm -f *.o xxxx

 

1.3             使用用戶自定義變量的Makefile

在Makefile文件中,用戶可以自定義變量,方便用戶修改參數。使用變量後,原本冗長的文件可以化簡

CC := gcc

RM := rm -f

 

OBJS := sub/sub_int.o sub/sub_float.o add/add_int.oadd/add_float.o main.o

TARGET := xxxx

CFLAGS := -Iadd -Isub -O2

 

$(TARGET):$(OBJS)

    @$(CC) -o $(TARGET)$(OBJS) $(CFLAGS)

 

$(OBJS):%.o:%.c

    $(CC) -c $< -o $@$(CFLAGS)

 

.PHONY:clean

clean:

    @rm -f $(OBJS)$(TARGET)

1.4             設置搜索路徑

在大的系統中,通常存在很多目錄,手動添加目錄的方法不僅十分笨拙而且容易造成錯誤。Make 的目錄搜索功能提供了一個解決此問題的方法,指定需要搜索的目錄(依賴文件目標文件), make 會自動找到指定文件的目錄並添加到文件上, VPATH 變量可以實現此目的。

VPATH 變量的使用方法如下:

CC := gcc

RM := rm -f

VPATH := sub:add:.

 

OBJDIR := objs

OBJS := sub_int.o sub_float.o add_int.o add_float.o main.o

TARGET := xxxx

CFLAGS := -Iadd -Isub -O2

 

$(TARGET):$(OBJDIR) $(OBJS)

    @$(CC) -o $(TARGET)$(OBJDIR)/*.o $(CFLAGS)

 

$(OBJDIR):

    @mkdir -p ./$@

 

$(OBJS):%.o:%.c

    $(CC) -c $< -o$(OBJDIR)/$@ $(CFLAGS)

 

.PHONY:clean

clean:

@rm -f $(OBJDIR)/*.o$(TARGET)

 

1.5             自動推導規則

使用命令 make 編譯擴展名爲 .c 的 C 語言文件的時候,源文件的編譯規則不用明確地給出。這是因爲 make 進行編譯的時候會使用一個默認的編譯規則,按照默認規則完成對 .c 文件的編譯,生成對應的 .o 文件。它執行命令 cc -c 來編譯 .c 源文件。在 Makefile 中只需要給出需要重建的目標文件(一個 .o 文件),make 會自動爲這個.o 文件尋找合適的依賴文件(對應的 .c 文件),並且使用默認的命令來構建這個目標文件。

對於上邊的例子,默認規則是使用命令cc -cmain.c -o main.o來創建文件 main.o 。對一個目標文件是“文件名.o“,依賴文件是”文件名.c“的規則,可以省略其編譯規則的命令行,由 make 命令決定如何使用編譯命令和選項。此默認規則稱爲 make 的隱含規則。

這樣,在書寫 Makefile 時,就可以省略掉描述 .c 文件和 .o 依賴關係的規則,而只需要給出那些特定的規則描述(.o 目標所需要的 .h 文件)。因此上面的例子可以使用更加簡單的方式書寫, Makefile 文件的內容如下:

CC := gcc

RM := rm -f

VPATH := sub:add:.

 

OBJS := sub_int.o sub_float.o add_int.o add_float.o main.o

TARGET := xxxx

CFLAGS := -Iadd -Isub -O2

 

$(TARGET):$(OBJS)

    @$(CC) -o $(TARGET)$(OBJS) $(CFLAGS)

 

.PHONY:clean

clean:

    @rm -f $(OBJS)$(TARGET)

1.6             遞歸 make

對於規模比較大的程序,需要多個人在多個目錄下進行開發。如果只用一個 Makefile 來維護就會比較麻煩,因此可以在每個目錄下建立自己的 Makefile,然後在總控 Makefile 中調用子目錄的Makefile 文件。

 

目錄結構如下

.

├── add

│   ├──add_float.c

│   ├──add.h

│   ├──add_int.c

│   └──Makefile

├── main.c

├── Makefile

└── sub

    ├── Makefile

    ├── sub_float.c

    ├── sub.h

└── sub_int.c

 

1.6.1        總控Makefile

export OBJSDIR := $(shell pwd)/objs

 

CC := gcc

RM := rm -f

 

OBJS := main.o

TARGET := xxxx

CFLAGS := -Iadd -Isub -O2

 

$(TARGET):$(OBJSDIR) $(OBJS)

    $(MAKE) -C add

    $(MAKE) -C sub

    @$(CC) -o $(TARGET)$(OBJSDIR)/*.o $(CFLAGS)

 

$(OBJSDIR):

    @mkdir -p $@

 

$(OBJS):%o:%c

    @$(CC) -c $< -o$(OBJSDIR)/$@ $(CFLAGS)

 

.PHONY:clean

clean:

    @rm -f $(OBJSDIR)/*.o$(TARGET)

 

1.6.2        add下makefile

CFLAGS := -O2

CC := gcc 

RM := rm -f

 

OBJS := add_float.o add_int.o

 

all:$(OBJS)

 

$(OBJS):%.o:%.c

    $(CC) -c $< -o$(OBJSDIR)/$@ $(CFLAGS)

1.6.3        sub下makefile

CFLAGS := -O2

CC := gcc 

RM := rm -f

 

OBJS := sub_float.o sub_int.o

 

all:$(OBJS)

 

$(OBJS):%.o:%.c

    $(CC) -c $< -o$(OBJSDIR)/$@ $(CFLAGS)

 

 

 

1.7             使用函數編寫makefile

CC := gcc

RM := rm -f

CFLAGS := -Iadd -Isub -O2

 

TARGET := xxxx

DIRS := add sub .

#獲取所有的.c文件,包括其相對路徑

FILES := $(foreach dirs, $(DIRS), $(wildcard $(dirs)/*.c))

OBJS := $(patsubst %.c, %.o, $(FILES))

 

$(TARGET):$(OBJS)

    @$(CC) -o $(TARGET)$(OBJS) $(CFLAGS)

 

.PHONY:clean

clean:

    @rm -f $(OBJS)$(TARGET)

 

 

 

發佈了51 篇原創文章 · 獲贊 106 · 訪問量 33萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章