Makefile框架

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.c 
  kvm_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












發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章