工程管理器 make (來自GNU計劃)
在運用Make工程管理器時我們會發現最重要的部分就是編寫Makefile,在提到make時候我們更多也更加習慣地提到Makefile。我們在做一個工程時會編寫很多的源文件,如果用gcc編譯的話編譯速率太慢效率太低,這時候全自動的Make工程管理器就能帶來很大的便利。
Make為什麼被稱為全自動化的編譯器?
1)、按規則編譯使用方便:通過命令”make”即可啟動編譯,Make工程管理器就根據規則文件Makefile來編譯
2)、按時間戳編譯調試效率高:Make會自動檢查每個源文件的時間戳的時間,如果發現時間更新就編譯該文件,如果時間戳沒變就不再編譯該文件
Makefile
組成部分:
目標文件:依賴文件
<Tab>編譯規則命令行
編寫程序模擬一個實現加減乘除功能的計算器並用Make工程管理器實現多個源文件的調試
功能塊源文件組成:add.csub.c mul.c div.c main.c
功能目錄組成:add submul div test scripts Makefile
tree型目錄
|-- Makefile
|-- add
| |-- Makefile
| `-- src
| |-- add.c
| `-- add.o
|-- cal
|-- div
| |-- Makefile
| `-- src
| |-- div.c
| `-- div.o
|-- mul
| |-- Makefile
| `-- src
| |-- mul.c
| `-- mul.o
|-- scripts
| `--Makefile
|-- sub
| |-- Makefile
| `-- src
| |-- sub.c
| `-- sub.o
`-- test
|-- Makefile
`-- src
|-- main.c
`-- main.o
scripts /Makefile(在腳本功能目錄下的Makefile主要進行一些變量賦值,在編寫時編者需要了解基本的賦值語句,在這裡以#開頭均為注解)
CC := gcc
CFLAGS := -Wall -O3
Libs = -lpthread
Target := cal
#目標文件名
Source := $(wildcard src/*.c)
#將所有src 目錄下.c文件存放到Source變量中去
Objs := $(patsubst %.c,%.o,$(Source))
#將Source中.c文件編譯成.o文件並存放到Objs變量中
Modules += add sub mul div test
#將所有的功能目錄存放到Modules變量中
AllObjs := $(addsuffix /src/*.o,$(Modules))
#依次將Modules中存放的目錄下的src目錄下的.o文件存放到AllObjs中
總控Makefile (在總控Makefile中主要執行進入各個子目錄中讀取Makefile並進行make編譯的嵌套功能)
include scripts/Makefile
modules_make = $(MAKE) -C $(1);
#嵌套執行,讀取子目錄的Makefile並執行make命令
modules_clean = $(MAKE) clean -C $(1);
#進入子目錄並進行clean操作
.PHONY: all mm mc clean
all: $(Target)
mm:
@$(foreach n,$(Modules),$(call modules_make,$(n)))
#先將Modules中存放的目錄循環依次傳送到變量n中,然後再將n中內容依次復制給參數modules_make中的變量$(1),$(2)
mc:
@$(foreach n,$(Modules),$(call modules_clean,$(n)))
#先將Modules中存放的目錄循環依次傳送到變量n中,然後再將n中內容依次復制給參數modules_clean中的變量$(1),$(2)
$(Target) : mm
$(CC)$(CFLAGS) -o $(Target) $(AllObjs) $(Libs) # 編譯成可執行文件gcc –Wall–o3 –o cal add.o sub.o mul.o div.o main.o -lpthread
@echo $(Target) make done! #打印 cal make done!
clean : mc
rm-rf $(Target)
#清除目標文件中的.o文件
@echo clean done! #打印 clean done!
功能塊Makefile (在各個獨立的子功能塊編寫Makefile文件)
include ../scripts/Makefile
all:$(Objs) #gcc –c ./src /.c文件 –o .o文件
clean:
rm-rf $(Objs)
#刪除各目錄下目錄src中的.o文件