# Makefile編寫要點 ###### tags: `C語言` `Computer Science` `程式設計(一)` `tutorials` --- ## Header File + 要編寫程式先將main.c(主程式)編成binary檔案 ``` makefile gcc -c main.c -o main.o ``` 再將函式檔編成binary檔 ``` makefile gcc -c mymax.c -o mymax.o ``` 最後在compiler裏頭匯入 ``` makefile gcc main.o mymax.o -o main ``` + gcc是整合型工具,所以也可以直接將.c檔案gcc執行,它會幫你自動做組譯到編譯,故可以直接利用 ``` makefile gcc main.c mymax.o -o main.c ``` 當然也可以這樣 ``` makefile gcc main.c mymax.c -o main.c ``` >**但在大型程式中就無法判別哪裏出錯** + function的程式碼在mymax.c --> compile成mymax.o,再將mymax.o與main.o匯集成主程式檔,mymax.h只是用到的自訂義函數protorype(標頭檔)。 + header file 需要去避免後面重複定義,因此要加上 ``` makefile #ifndef X included #define X #endif ``` 新版C語言可以直接使用pragma once避免重複定義,如下 ``` makefile #pragma once ``` ## 靜態連結與動態連結 ### 靜態連結寫法 + all後方檢查檔案中是否有mymax.o及main.c ``` Makefile all: mymax.o main.c gcc main.c mymax.o -o main mymax.o: mymax.c gcc -c mymax.c -o mymax.o ``` ### 動態連結寫法 + L代表要搜尋的目錄位置,.代表當前目錄 ``` Makefile all: mymax.o main.c gcc main.c -o main_dyn -L. lmymax mymax.o: mymax.c gcc -c mymax.c -o mymax.o gcc -shared mymax.o -o libmymax.so (編成共享函式庫,so的s代表共享) ``` + 若共享function在當前目錄,在執行時需加上 LD_LIBRARY_PATH = ./ ## 多函式、程式連結 ### 基本、簡易方法 ``` Makefile # use variable to store target objects obj = dep01.o dep02.o dep03.o dep04.o dep05.o entry.o # pass in variable all: $(obj) gcc -o hw$(obj) clean: rm *.o ``` ### 進階寫法 + wildcard 只會搜尋**當下資料夾**符合該pattern的檔案 Ex: $(wildcard*.c) 會list all .c file under current directory + 如何把.c檔案取代成.o檔案 Ex: $(SRC: .c = .o) 會replace .c suffix with .o + automated variable把全部.o檔案link再一起使用$^ 代表all prerequisites, seperated by space + 利用Wildcard與$(SRC)與\$^寫法 ``` Makefile # use variable to store target objects SRC = $(wildcard *.c) # pass in variable all: $(SRC:.c = .o) gcc -o res $^ clean: rm *.o res ``` ### 多層目錄寫法 + 多層資料夾需make時需要注意如下 ```makefile all: cd 目標資料夾a && make # 不可分開寫要不然會造成無限迴圈 cd 目標資料夾b && make # 不可分開寫要不然會造成無限迴圈 cp 複製目標資料夾a路徑 複製目標檔案 gcc -g -o 執行檔名稱 main.c -動態共享庫 -lm -L. -Wl, -rpath, `pwd` clean: -rm main 動態共享庫.so cd 目標資料夾a && make clean # 不可分開寫要不然會造成無限迴圈 cd 目標資料夾b && make clean # 不可分開寫要不然會造成無限迴圈 ```