Makefile模板之生成動態庫

選項說明:

-Wall 選項 :可以打印出編譯時所有的錯誤或者警告信息。變量沒有初始化,類型不匹配,沒有使用的變量或者類型轉換錯誤等警告提示。

-fPIC 選項:適用於動態連接,作用於編譯階段,告訴編譯器產生與位置無關代碼(Position-Independent Code), 則產生的代碼中,沒有絕對地址,全部使用相對地址,故而代碼可以被加載器加載到內存的任意 位置,都可以正確的執行。這正是共享庫所要求的,共享庫被加載時,在內存的位置不是固定的。

-fpermissive選項:用這個選項,可以兼容一些老的語法,但是一些語法錯誤也會被忽略。該選項需慎重使用,因爲會降低對於代碼檢查的嚴格性。

-DDEBUG :相當於定義了宏DEBUG,代碼中可以用#ifdef DEBUG來控制調試輸出信息等。可以用-D加名字定義一些用到的宏定義。

-I 選項:(i的大寫)編譯選項(準確的是說是預處理選項CFLAGS或者CPPFLAGS中指定),用來指定預處理時查找頭文件的範圍的。

-L選項 :鏈接選項(LDFLAGS中指定),用來告訴鏈接器到哪個路徑下面去找動態鏈接庫。
-l 選項: (L的小寫)鏈接選項(LDFLAGS中指定),用來指定鏈接額外的庫(譬如我們用到了uuid,就用-luuid,鏈接器就會去鏈接libuuid.so)
-shared :創建動態鏈接庫使用的選項。

自定變量:

$@:表示規則中的目標文件集。在模式規則中,如果有多個目標,那麼, $@ 就是匹配於目標中模式定義的集合。

$% :僅當目標是函數庫文件時,表示規則中的目標成員名。例如,如果一個目標是 foo.a(bar.o),那麼, $% 就是 bar.o , $@ 就是 foo.a 。如果目標不是函數庫文件(Unix 下是 .a , Windows下是 .lib ),那麼,其值爲空

$< :依賴目標中的第一個目標名字。如果依賴目標是以模式(即 % )定義的,那麼 $< 將是符合模式的一系列的文件集。注意,其是一個一個取出來的。

$? :所有比目標新的依賴目標的集合。以空格分隔。

$^ :所有的依賴目標的集合。以空格分隔。如果在依賴目標中有多個重複的,那個這個變量會去除重複的依賴目標,只保留一份。

$+ :所有依賴目標的集合,不去除重複的依賴目標。


# flags
CC		= gcc
CXX		= g++

CXXFLAGS = -Wall -fPIC -std=c++11 -fpermissive
LDFLAGS = -shared

# args
RELEASE = 0 #控制release還是debug版本 0代表debug版本 ,1代表release版本
BITS = 64  #64還是32位

# [args] 程序位數. 32代表32位程序, 64代表64位程序, 其他默認. make BITS=32.
ifeq ($(BITS),32)
    CXXFLAGS += -m32
     #需用到的一些第三方庫的路徑
	LIB_PATH = ../lib 
	DVR_LIB_PATH = ../../../DeviceSdk/ViskingNVR/netsdk/
else
    CXXFLAGS += -m64
    #需用到的一些第三方庫的路徑
	LIB_PATH = ../lib/x64 
	DVR_LIB_PATH = ../../../DeviceSdk/ViskingNVR/linux_NetSdk_x64/NetSdk/lib/
endif

OUTPUT = $(LIB_PATH)/libVisking.so  #最終生成的動態庫

# [args] 生成模式. 1代表debug模式, 0代表release模式. make RELEASE=0.
#-O0: 不做任何優化,這是默認的編譯選項
#-O2: O2優化增加了編譯時間的基礎上,提高了生成代碼的執行效率。
#-O3:包含了O2所有的優化的基礎上,增加了更多的優化。
#-ggdb 爲GDB 生成專用的更爲豐富的調試信息,但是,此時就不能用其他的調試器來進行調試了
#-DNDEBUG 定義NDEBUG宏定義
ifeq ($(RELEASE),0)
    # release
    CXXFLAGS += -ggdb -O0 -gdwarf-2
else
    # debug
    CXXFLAGS += -O3 -DNDEBUG
endif

# files 用的一些頭文件的路徑
INCLUDES = -I./
INCLUDES += -I./../../
INCLUDES += -I../../../include

ifeq ($(BITS),32)
    INCLUDES += -I../../../DeviceSdk/ViskingNVR/netsdk/
else
   INCLUDES += -I../../../DeviceSdk/ViskingNVR/linux_NetSdk_x64/NetSdk/
endif

ifeq ($(RELEASE),0)
    # release
	LIB_DIR = -L$(LIB_PATH)
	LIB_DIR += -L$(DVR_LIB_PATH)
	LIBS += -lvsksdk   #鏈接用到的動態庫libvsksdk.so
else
    # debug
 	LIB_DIR = -L$(LIB_PATH)
	LIB_DIR += -L$(DVR_LIB_PATH) 
	LIBS += -lvsksdk    #鏈接用到的動態庫libvsksdk.so
endif

#SRCS := $(wildcard *.cpp) 表示獲取當前目錄下的c文件集,放在變量SRCS中
#OBJS := $(SRCS:%.cpp=%.o) 表示將對應的c文件名轉爲o文件後放在下面的OBJS變量中
SRCS = $(wildcard ./*.cpp)
OBJS := $(SRCS:%.cpp=%.o)

#例如 用到h264的第三方庫
H264SRCS := $(wildcard ../../../thirdparty/H264BSAnalysis/*.cpp)
H264OBJS := $(H264SRCS:%.cpp=%.o)

.phony : all $(OUTPUT) $(OBJS)

all: $(OUTPUT)
	@echo "========end"
$(OUTPUT) :  $(OBJS) $(H264OBJS) 
	$(CXX) $(CXXFLAGS) $(LDFLAGS) $(LIB_DIR) $(LIBS) $(OBJS) $(H264OBJS) -o $(OUTPUT)

$(OBJS):%.o:%.cpp
	@echo "=================VISKING"
	$(CXX) $(CXXFLAGS) -c $< -o $@ $(INCLUDES)

$(H264OBJS):%.o:%.cpp
	@echo "=================H264"
	$(CXX) $(CXXFLAGS) -c $< -o $@ $(INCLUDES)

clean :
	rm -rf $(OBJS) $(OUTPUT)

linux終端輸入make,最終生成libVisking.so動態庫文件。

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