1 makefile框架:
include ./other/Makefile #包含其它makefile CC=g++ CFLAGS := -Wall -g $(INC_FLAGS) -D$(HIARCH) -DHICHIP=$(HICHIP) -DSENSOR_TYPE=$(SENSOR_TYPE) \ -D$(HIDBG) -D$(HI_FPGA) -D$(ISP_VERSION) LIBS = $(REL_LIB)/lib_hiae.a LIBS += $(REL_LIB)/lib_hiawb.a LIBS += $(REL_LIB)/lib_hiaf.a INCLUDES=-Iinclude -Iinclude/ffmpeg INCLUDES += -I/usr/local/include/opencv SRC := $(wildcard *.c) OBJ := $(SRC:%.c=%.o) TARGET := $(OBJ:%.o=%) .PHONY : clean all #僞命令 all: $(TARGET) $(TARGET):%:%.o $(CC) $(CFLAGS) -lpthread -o $@ $^ $(LIBS) $(INCLUDES) clean : @rm -f $(TARGET) @rm -f $(OBJ) rm -f $(TARGET) rm -f $(OBJ) -rm -f $(TARGET) -rm -f $(OBJ)2 動態、靜態鏈接庫
//hello.c
#include<stdio.h> void hello() { printf("hello world/n"); }
//test.c
#include<stdio.h> int main() { printf("call hello()"); hello(); }
動態鏈接庫:
gcc -shared hello.c -o libhello.so //-shared 編譯爲動態庫(後綴一般爲.so)
gcc test.c -lhello -L. -o test //-lhello 調用動態鏈接庫 libhello.so,且將當前路徑.加入鏈接文件的搜索路徑中
執行test可執行文件時,會找不到libhello.so;解決方法:
(方法一)要把該連接庫的路徑加入環境變量LD_LIBRARY_PATH中;
(方法二)或者直接把該庫拷入/lib,/usr/lib/等位置
靜態鏈接庫:
1, gcc -c hello.c //生成hello.o文件
2, ar -r libhello.a hello.o //把目標文件歸檔
程序 ar 配合參數 -r 創建一個新庫 libhello.a 並將命令行中列出的對象文件插入。採用這種方法,如果庫不存在的話,參數 -r 將創建一個新的庫,而如果庫存在的話,將用新的模塊替換原來的模塊。
3. 在程序中鏈接靜態庫
gcc test.c -lhello -L. -static -o hello.static
3 makefile 參數講解:
-Idir:在頭文件的搜索路徑列表中添加dir目錄. (是 i)
-Dmacro:定義宏macro,宏的內容定義爲字符串`1'.
-Dmacro=defn:定義宏macro的內容爲defn.命令行上所有的`-D'選項在`-U'選項之前處理
-llibrary -lpthread:連接名爲library的庫文件.(是L)連接器在標準搜索目錄中尋找這個庫文件,
庫文件的真正名字是`liblibrary.a'.連接器會當做文件名得到準確說明一樣引用這個文件 ;
$@ 代表目標
$^ 代表所有的依賴對象
$< 代表第一個依賴對
Tab鍵之後爲shell命令:Makefile 中書寫shell命令時可以加2種前綴 @ 和 -, 或者不用前綴.3種格式的shell命令區別如下:不用前綴 :: 輸出執行的命令以及命令執行的結果, 出錯的話停止執行前綴 @ :: 只輸出命令執行的結果, 出錯的話停止執行前綴 - :: 命令執行有錯的話, 忽略錯誤, 繼續執行wildcard命令:例子:SRC := $(wildcard *.c)在Makefile規則中,通配符會被自動展開。但在變量的定義和函數引用時,通配符將失效。這種情況下如果需要通配符有效,就需要使用函數“wildcard”,它的用法是:$(wildcard PATTERN...) 。在Makefile中,它被展開爲已經存在的、使用空格分開的、匹配此模式的所有文件列表。
= 和 := 的區別在於, := 只能使用前面定義好的變量, = 可以使用後面定義的變量
+= 變量追加值
查看C文件的依賴關係:$ gcc -MM kvm_main.ckvm_main.o: kvm_main.c iodev.h coalesced_mmio.h async_pf.h <-- 這句就可以加到 Makefile 中作爲編譯 kvm_main.o 的依賴關係
make 命令時執行了誰:GNU make在當前目錄下依次搜索下面3個文件 "GNUmakefile", "makefile", "Makefile",
也可make時指定要運行的makefile文件;$ make -f MyMake target2
makefile 隱含規則:
編譯C時,<n>.o 的目標會自動推導爲 <n>.c
# Makefile 中 main : main.o gcc -o main main.o #會自動變爲: main : main.o gcc -o main main.o main.o: main.c <-- main.o 這個目標是隱含生成的 gcc -c main.c
makefile 自動變量:
$@ 目標集合
$% 當目標是函數庫文件時, 表示其中的目標文件名
$< 第一個依賴目標. 如果依賴目標是多個, 逐個表示依賴目標
$? 比目標新的依賴目標的集合
$^ 所有依賴目標的集合, 會去除重複的依賴目標
$+ 所有依賴目標的集合, 不會去除重複的依賴目標
$* 這個是GNU make特有的, 其它的make不一定支持
用export傳遞參數:
# Makefile 內容 export VALUE1 := export.c <-- 用了 export, 此變量能夠傳遞到 ./other/Makefile 中 VALUE2 := no-export.c <-- 此變量不能傳遞到 ./other/Makefile 中 all: @echo "主 Makefile begin" @cd ./other && make @echo "主 Makefile end" # ./other/Makefile 內容 other-all: @echo "other makefile begin" @echo "VALUE1: " $(VALUE1) @echo "VALUE2: " $(VALUE2) @echo "other makefile end"
makefile判斷語句:
#ifneq、ifeq; ifeq ("aa", "bb") @echo "equal" else @echo "not equal" endif # ifndef和ifdef ifdef SRCS @echo $(SRCS) else @echo "no SRCS" endif