日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C/C++通用Makefile

發布時間:2024/9/21 c/c++ 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C/C++通用Makefile 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

??????? 最近的項目又回到了Linux上運行,這就需要在Linux下編譯項目,寫Makefile針對習慣了Windows的程序員來說是一件痛苦的事,如果有一個通用的Makefile該多好啊,本著這樣的目的,我再次研究了一下Makefile,寫出了一個實用的通用Makefile,該Makefile在Windows以及Linux平臺下作了一些簡單測試,未發現問題,如果大家在使用過程中發現有問題可以聯系我。話不多說,直接上代碼:

############################################################################### # # C/C++通用Makefile # # 作者:Witton Bell E_Mail:witton@163.com # # 版本V1.0 (2017/02/23) # 初始版本,可以生成App,Share以及Static庫等等 # 版本V1.1 (2017/02/28) # 添加預預編譯頭的支持,將生成的中間文件放在debug或者release目錄下 # 版本V1.2 (2017/03/12) # 優化以及fixed:修改頭文件后,不會編譯 # # 一個項目只需要在頂層目錄配置一個Makefile,不需要各個目錄單獨配置,簡單方便實用 # 原文鏈接:http://blog.csdn.net/witton/article/details/56670748 # 最新文件下載地址:https://code.csdn.net/snippets/2259925 # # 功能說明: # 1.支持Windows以及Linux下的可執行文件(App)、動態庫(Share)以及靜態庫(Static)的生成 # 2.支持生成Map文件,Bin文件以及十六進制文件 # 3.支持C/C++的預編譯頭,以加快編譯速度,包括同時存在C與C++預編譯頭的情況 # 4.生成的中間以及目標代碼會指定存放在debug或者release目錄下 # 5.支持生成進度顯示 # ################################################################################ 可以修改的區域# 目標文件的名字(必須指定) TARGETNAME := test#目標類型可以是APP, STATIC或者SHARED TARGETTYPE := APP#配置類型可以是Debug或者Release CONFIG ?= Debug# C 預編譯頭文件,支持帶路徑 PCH_H = # C++ 預編譯頭文件,支持帶路徑 PCH_X_H =#源文件目錄列表,可以填多個目錄,如:src1 src2 ../src #如果沒填寫則默認為當前目錄 SRC_ROOT_DIRS :=#排除的目錄列表,需要帶上相對路徑 EXCLUDE_DIRS :=#排除的文件列表,需要帶上相對路徑 EXCLUDE_FILES :=#頭文件所在目錄列表 INCLUDE_DIRS := #庫文件所在目錄列表 LIBRARY_DIRS := #公共庫文件名列表 LIBRARY_NAMES := #公共宏定義 PREPROCESSOR_MACROS :=#各種編譯鏈接參數 #匯編編譯參數 ASFLAGS := -f win64 #ld鏈接參數 LDFLAGS := -Wl,-gc-sections #公共編譯參數,根據情況作修改 COMMONFLAGS := -g -ffunction-sections #額外的庫文件 EXTERNAL_LIBS := #工具集,Windows下最好是填寫絕對路徑,并且路徑中需要使用/分隔 CC := g:/TDM-GCC-64/bin/gcc CXX := g:/TDM-GCC-64/bin/g++ LD := $(CXX) ASM := "G:/Program Files (x86)/nasm/nasm.exe" AR := ar OBJCOPY := objcopy CP := cp MKDIR = mkdir RM = rm -rf ECHO = echo SHELL = /bin/sh#根據配置類型填寫不同的參數 ifeq ($(CONFIG), Debug)PREPROCESSOR_MACROS += DEBUGLIBRARY_NAMES += ADDITIONAL_LINKER_INPUTS := MACOS_FRAMEWORKS := LINUX_PACKAGES := CFLAGS := -O0CXXFLAGS := -O0 elsePREPROCESSOR_MACROS +=LIBRARY_NAMES += ADDITIONAL_LINKER_INPUTS := MACOS_FRAMEWORKS := LINUX_PACKAGES := CFLAGS := -O3CXXFLAGS := -O3 endif#需要編譯的源文件的擴展名列表 SRC_EXTS := .c .cpp .cc .cxx .c++ .s .S .asm#如果是在Linux下編譯,需要打開此開關 #IS_LINUX_PROJECT := 1#如果需要生成Map文件,需要打開此開關 #GENERATE_MAP_FILE := 1#如果生成Bin文件,需要打開此開關 #GENERATE_BIN_FILE := 1#如果生成十六進制文件,需要打開此開關 #GENERATE_IHEX_FILE := 1#是否顯示詳細的命令行 #SHOW_CMD_DETAIL := 1#可修改區域結束,以下區域不建議修改,除非特別了解其含義#======================華麗的分割線=============================#小寫函數 to_lowercase = $(subst A,a,$(subst B,b,$(subst C,c,$(subst D,d,$(subst E,e,$(subst F,f,$(subst G,g,$(subst H,h,$(subst I,i,$(subst J,j,$(subst K,k,$(subst L,l,$(subst M,m,$(subst N,n,$(subst O,o,$(subst P,p,$(subst Q,q,$(subst R,r,$(subst S,s,$(subst T,t,$(subst U,u,$(subst V,v,$(subst W,w,$(subst X,x,$(subst Y,y,$(subst Z,z,$1))))))))))))))))))))))))))BINARYDIR := $(call to_lowercase,$(CONFIG))ifeq ($(BINARYDIR),) error:$(error Invalid configuration, please check your inputs) endif#如果沒配置源文件目錄,則默認為當前目錄 ifeq ($(SRC_ROOT_DIRS),)SRC_ROOT_DIRS = . endifdefine walk $(wildcard $(addprefix $(1)/*, $(SRC_EXTS))) $(foreach e, $(wildcard $(1)/*), $(call walk, $(e))) endef#匹配所有源文件 SOURCEFILES := $(foreach e, $(SRC_ROOT_DIRS), $(call walk, $(e))) #匹配所有需要排除的源文件 EXCLUDE_SOURCE := $(foreach e, $(EXCLUDE_DIRS), $(call walk, $(e))) EXCLUDE_FILES += $(EXCLUDE_SOURCE) EXTERNAL_LIBS_COPIED := $(foreach lib, $(EXTERNAL_LIBS),$(BINARYDIR)/$(notdir $(lib)))#設置C預編譯相關變量 ifneq ($(PCH_H),) PCH = $(PCH_H).gch PCH_FLAGS := -Winvalid-pch -include $(BINARYDIR)/$(PCH_H) PCH_FILE := $(BINARYDIR)/$(PCH) endif#設置C++預編譯相關變量 ifneq ($(PCH_X_H),) PCH_X = $(PCH_X_H).gch PCH_X_FLAGS := -Winvalid-pch -include $(BINARYDIR)/$(PCH_X_H) PCH_X_FILE := $(BINARYDIR)/$(PCH_X) endifSTART_GROUP := -Wl,--start-group END_GROUP := -Wl,--end-group INCLUDE_DIRS += .#處理頭文件目錄 CFLAGS += $(addprefix -I,$(INCLUDE_DIRS)) CXXFLAGS += $(addprefix -I,$(INCLUDE_DIRS))#處理宏定義 CFLAGS += $(addprefix -D,$(PREPROCESSOR_MACROS)) CXXFLAGS += $(addprefix -D,$(PREPROCESSOR_MACROS)) ASFLAGS += $(addprefix -D,$(PREPROCESSOR_MACROS))#處理框架 CFLAGS += $(addprefix -framework ,$(MACOS_FRAMEWORKS)) CXXFLAGS += $(addprefix -framework ,$(MACOS_FRAMEWORKS)) LDFLAGS += $(addprefix -framework ,$(MACOS_FRAMEWORKS))#處理庫目錄 LDFLAGS += $(addprefix -L,$(LIBRARY_DIRS))CFLAGS += $(COMMONFLAGS) CXXFLAGS += $(COMMONFLAGS) LDFLAGS += $(COMMONFLAGS)ifeq ($(GENERATE_MAP_FILE),1) LDFLAGS += -Wl,-Map=$(BINARYDIR)/$(basename $(TARGETNAME)).map endifLIBRARY_LDFLAGS = $(addprefix -l,$(LIBRARY_NAMES))ifeq ($(IS_LINUX_PROJECT),1)ifeq ($(TARGETTYPE),SHARED) TempName = $(addsuffix .so,$(basename $(TARGETNAME))) TARGETNAME := $(TempName) endifRPATH_PREFIX := -Wl,--rpath='$$ORIGIN/../LIBRARY_LDFLAGS += $(EXTERNAL_LIBS)LIBRARY_LDFLAGS += -Wl,--rpath='$$ORIGIN'LIBRARY_LDFLAGS += $(addsuffix ',$(addprefix $(RPATH_PREFIX),$(dir $(EXTERNAL_LIBS))))#如果是Linux下的共享庫(Share)項目,則需要添加-fPIC參數,以實現位置無關代碼ifeq ($(TARGETTYPE),SHARED)CFLAGS += -fPICCXXFLAGS += -fPICASFLAGS += -fPICLIBRARY_LDFLAGS += -Wl,-soname,$(TARGETNAME)endififneq ($(LINUX_PACKAGES),)PACKAGE_CFLAGS := $(foreach pkg,$(LINUX_PACKAGES),$(shell pkg-config --cflags $(pkg)))PACKAGE_LDFLAGS := $(foreach pkg,$(LINUX_PACKAGES),$(shell pkg-config --libs $(pkg)))CFLAGS += $(PACKAGE_CFLAGS)CXXFLAGS += $(PACKAGE_CFLAGS)LIBRARY_LDFLAGS += $(PACKAGE_LDFLAGS)endif elseLIBRARY_LDFLAGS += $(EXTERNAL_LIBS)ifeq ($(TARGETTYPE),APP) TempName = $(addsuffix .exe,$(basename $(TARGETNAME))) TARGETNAME := $(TempName) endififeq ($(TARGETTYPE),SHARED) TempName = $(addsuffix .dll,$(basename $(TARGETNAME))) TARGETNAME := $(TempName) endifendifLIBRARY_LDFLAGS += $(ADDITIONAL_LINKER_INPUTS)#靜態庫都是以.a為后綴 ifeq ($(TARGETTYPE),STATIC) TempName = $(addsuffix .a,$(basename $(TARGETNAME))) TARGETNAME := $(TempName) endififeq ($(STARTUPFILES),)all_source_files := $(SOURCEFILES) elseall_source_files := $(STARTUPFILES) $(filter-out $(STARTUPFILES),$(SOURCEFILES)) endifdefine HandlePath $(foreach x,$(foreach x,$(foreach x,$(subst //,/,$(1)),$(subst ../,*/,$(x))),$(subst ./,,$(x))),$(subst */,../,$(x))) endefAllSource := $(call HandlePath, $(all_source_files)) AllExcludeSource := $(call HandlePath, $(EXCLUDE_FILES))Source := $(filter-out $(AllExcludeSource),$(AllSource))CompileObjs := $(foreach x,$(SRC_EXTS),$(patsubst %$(x),%.o,$(filter %$(x),$(Source)))) all_objs := $(foreach x,$(CompileObjs),$(BINARYDIR)/$(x))ASM_EXT := .s .S .asm CompileCObjs := $(foreach x,$(filter-out $(ASM_EXT),$(SRC_EXTS)),$(patsubst %$(x),%.d,$(filter %$(x),$(Source)))) all_Cobjs := $(foreach x,$(CompileCObjs),$(BINARYDIR)/$(x))DEPS := $(all_Cobjs:.o=.d)revert0 = $(2) $(1) define revert $(foreach x,$(DEPS),$(eval TempStep = $(call revert0, $(TempStep),$(x)))) $(TempStep) endefAllStep := $(call revert,$(DEPS)) AllStep += $(CompileObjs)WordNum := $(words $(AllStep))ProgressInfo := $(foreach x,$(AllStep),$(eval Counter += A)$(addsuffix .$(words $(Counter)), $(basename $(x))))define FindProgress $(foreach x,$(ProgressInfo),$(if $(filter $(basename $(x)),$(1)),$(subst .,,$(suffix $(x))),)) endefdefine ShowProgress $(strip $(call FindProgress,$(basename $(1))))/$(WordNum) endefIS_GCC_ASM := ifneq ($(filter $(ASM),$(CXX)),) IS_GCC_ASM = 1 else ifneq ($(filter $(ASM),$(CC)),) IS_GCC_ASM = 1 endif endififeq ($(IS_GCC_ASM),1) CompileA := $(ASM) $(CFLAGS) $(ASFLAGS) -c else CompileA := $(ASM) $(ASFLAGS) endifCompileC := $(CC) $(PCH_FLAGS) $(CFLAGS) -c CompileCXX := $(CXX) $(PCH_X_FLAGS) $(CXXFLAGS) -cifneq ($(SHOW_CMD_DETAIL),) define CompileSrc@$(MKDIR) -p $(BINARYDIR)/$(subst ../,__/, $(dir $(1)))@$(ECHO) -n [$(call ShowProgress,$(2))]$(3) $(2) -o $(subst ../,__/, $(1)) endef else define CompileSrc@$(MKDIR) -p $(BINARYDIR)/$(subst ../,__/, $(dir $(1)))@$(ECHO) [$(call ShowProgress,$(2))] Compile $(2)@$(3) $(2) -o $(subst ../,__/, $(1)) endef endifdefine CompileCDep@$(MKDIR) -p $(subst ../,__/, $(dir $(1)))@$(ECHO) [$(call ShowProgress,$(BINARYDIR)/$(2))] Generate $(1)@$(CC) -MM $(CFLAGS) $(2) > $(BINARYDIR)/temp@$(ECHO) -n $(subst ./,, $(dir $(1))) > $(1)@$(CC) -MM $(CFLAGS) $(2) >> $(1) endefdefine CompileCXXDep@$(MKDIR) -p $(subst ../,__/, $(dir $(1)))@$(ECHO) [$(call ShowProgress,$(BINARYDIR)/$(2))] Generate $(1)@$(CXX) -MM $(CXXFLAGS) $(2) > $(BINARYDIR)/temp@$(ECHO) -n $(subst ./,, $(dir $(1))) > $(1)@$(CXX) -MM $(CXXFLAGS) $(2) >> $(1) endefPRIMARY_OUTPUTS :=ifeq ($(GENERATE_BIN_FILE),1) PRIMARY_OUTPUTS += $(BINARYDIR)/$(basename $(TARGETNAME)).bin endififeq ($(GENERATE_IHEX_FILE),1) PRIMARY_OUTPUTS += $(BINARYDIR)/$(basename $(TARGETNAME)).ihex endififeq ($(PRIMARY_OUTPUTS),) PRIMARY_OUTPUTS := $(BINARYDIR)/$(TARGETNAME) endif.PHONY: all clean.SUFFIXES:all: $(PRIMARY_OUTPUTS)@$(RM) $(BINARYDIR)/temp@$(ECHO) Built OK.$(BINARYDIR)/$(basename $(TARGETNAME)).bin: $(BINARYDIR)/$(TARGETNAME)@$(OBJCOPY) -O binary $< $(subst ../,__/, $@)$(BINARYDIR)/$(basename $(TARGETNAME)).ihex: $(BINARYDIR)/$(TARGETNAME)@$(OBJCOPY) -O ihex $< $(subst ../,__/, $@) ifeq ($(TARGETTYPE),APP) $(BINARYDIR)/$(TARGETNAME): $(all_objs) $(EXTERNAL_LIBS)@$(ECHO) Link App $(subst ../,__/, $@)@$(LD) -o $(subst ../,__/, $@) $(LDFLAGS) $(START_GROUP) $(subst ../,__/, $(all_objs)) $(LIBRARY_LDFLAGS) $(END_GROUP) endififeq ($(TARGETTYPE),SHARED) $(BINARYDIR)/$(TARGETNAME): $(all_objs) $(EXTERNAL_LIBS)@$(ECHO) Link Share lib $(subst ../,__/, $@)@$(LD) -shared -o $(subst ../,__/, $@) $(LDFLAGS) $(START_GROUP) $(subst ../,__/, $(all_objs)) $(LIBRARY_LDFLAGS) $(END_GROUP) endififeq ($(TARGETTYPE),STATIC) $(BINARYDIR)/$(TARGETNAME): $(all_objs)@$(ECHO) Link Static lib $(subst ../,__/, $@)@$(AR) -r $(subst ../,__/, $@) $(subst ../,__/, $^) endifclean:@$(RM) $(BINARYDIR)$(BINARYDIR):@$(MKDIR) $(BINARYDIR)#Makefile的生成規則 #生成依賴文件 $(BINARYDIR)/%.d : %.c$(call CompileCDep,$@,$<)$(BINARYDIR)/%.d : %.cpp$(call CompileCXXDep,$@,$<)$(BINARYDIR)/%.d : %.cxx$(call CompileCXXDep,$@,$<)$(BINARYDIR)/%.d : %.cc$(call CompileCXXDep,$@,$<)$(BINARYDIR)/%.d : %.c++$(call CompileCXXDep,$@,$<)#C文件的生成規則 $(BINARYDIR)/%.o : %.c $(PCH_FILE)$(call CompileSrc,$@,$<,$(CompileC))#C++的.cpp文件的生成規則 $(BINARYDIR)/%.o : %.cpp $(PCH_X_FILE)$(call CompileSrc,$@,$<,$(CompileCXX))#C++的.cc文件的生成規則 $(BINARYDIR)/%.o : %.cc $(PCH_X_FILE)$(call CompileSrc,$@,$<,$(CompileCXX))#C++的.cxx文件的生成規則 $(BINARYDIR)/%.o : %.cxx $(PCH_X_FILE)$(call CompileSrc,$@,$<,$(CompileCXX))#C++的.c++文件的生成規則 $(BINARYDIR)/%.o : %.c++ $(PCH_X_FILE)$(call CompileSrc,$@,$<,$(CompileCXX))#Asm的.S文件生成規則 $(BINARYDIR)/%.o : %.S$(call CompileSrc,$@,$<,$(CompileA))#Asm的.s文件生成規則 $(BINARYDIR)/%.o : %.s$(call CompileSrc,$@,$<,$(CompileA))#Asm的.asm文件生成規則 $(BINARYDIR)/%.o : %.asm$(call CompileSrc,$@,$<,$(CompileA))ifneq ($(PCH_H),) #C預編譯頭文件的生成規則 $(BINARYDIR)/$(PCH) : $(PCH_H)@$(MKDIR) -p $(subst ../,__/, $(dir $@))@$(ECHO) Precompiled C header $<@$(CC) $(CFLAGS) $> $^ -o $(subst ../,__/, $@)@$(CP) $(PCH_H) $(BINARYDIR)/$(PCH_H) endififneq ($(PCH_X_H),) #C++預編譯頭文件的生成規則 $(BINARYDIR)/$(PCH_X) : $(PCH_X_H)@$(MKDIR) -p $(subst ../,__/, $(dir $@))@$(ECHO) Precompiled C++ header $<@$(CXX) $(CXXFLAGS) $> $^ -o $(subst ../,__/, $@)@$(CP) $(PCH_X_H) $(BINARYDIR)/$(PCH_X_H) endififndef NODEP ifneq ($(DEPS),) sinclude $(DEPS) endif endif#生成規則結束

最終的運行結果如下圖所示:


祝玩得開心!

轉載于:https://www.cnblogs.com/witton/p/6868958.html

總結

以上是生活随笔為你收集整理的C/C++通用Makefile的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。