DemoMakefile

  聲明:如果涉及侵權,請聯繫本人刪除侵權內容。
  聲明:本文由本人以以往工作經驗爲依據,總結而得,如有錯誤,歡迎指正,便於後人參考,少走彎路。

Demo Makefile文件請移步github:Demo Makefile

在開發過程中經常需要交叉編譯,這就會面臨如下問題:

  • 直接用"gcc"、"g++"、"arm-gcc"、"arm-g++"編譯,每次都要敲命令行,太繁瑣;
  • 針對不同的編譯工具:"gcc"、"g++"、"arm-gcc"、"arm-g++",不同的文件類型:".c"和".cpp",寫四個Makefile處理,需要在使用時區分,還是繁瑣;
  • 用一個Makefile來處理,需要優化,優化如下。

目錄

1. 共用處理

2. 分支處理

2.1. x86_gcc分支

2.2. x86_g++分支

2.3. arm_gcc分支

2.4. arm_g++分支

3. 優化

3.1. 參數錯誤

3.2. 參數空

3.3. 僞目標.clean

4. 編譯

5. 備註


1. 共用處理

  共用的變量,標誌放在開始位置

    TARGET := App   #1

    LOCAL_LDFLAGS := -lpthread  #2
    LOCAL_LDFLAGS += -W

    MAP_FILE_NAME := $(TARGET)  #3
    LOCAL_LDFLAGS += -Wl,-Map=./$(MAP_FILE_NAME).map
  • #1:定義終極目標爲:APP
  • #2:添加鏈接選項到:LOCAL_LDFLAGS
  • #3:實現".map"文件生成

2. 分支處理

  分支處理可以用兩種方式實現,我採用第二種

  • 方式一:
ifeq ()
    # 分支一
endif
ifeq ()
    # 分支二
endif
ifeq ()
    # 分支三
endif
ifeq ()
    # 分支四
endif
  • 方式二:
ifeq ()
    # 分支一
else ifeq ()
    # 分支二
else ifeq ()
    # 分支三
else ifeq ()
    # 分支四
endif

2.1. x86_gcc分支

這個分支的應用場景:

  • 編譯工具:gcc
  • 編譯文件類型:.c
    # x86_gcc ###################################################
    ifeq ($(tool),x86_gcc)  #1
    SRCS := $(shell ls *.c) #2
    OBJS := $(patsubst %.c,%.o,$(SRCS)) #3

    CC := gcc   #4

    $(TARGET) : $(OBJS) #5
        $(CC) -o $@ $^ $(LOCAL_LDFLAGS)

    %.o:%.c
        $(CC) -c -o $@ $< $(LOCAL_LDFLAGS)
  • #1:make tool=中給tool賦值x86_gcc
  • #2:獲取源文件
  • #3:轉換目標文件
  • #4:確定編譯工具
  • #5:編譯

2.2. x86_g++分支

這個分支的應用場景:

  • 編譯工具:g++
  • 編譯文件類型:.cpp
     # x86_g++ ###################################################
    else ifeq ($(tool),x86_g++) #1

    SRCS := $(shell ls *.cpp)   #2
    OBJS := $(patsubst %.cpp,%.o,$(SRCS))   #3

    CC := g++   #4

    $(TARGET) : $(OBJS) #5
        $(CC) -o $@ $^ $(LOCAL_LDFLAGS)

    %.o:%.cpp
        $(CC) -c -o $@ $< $(LOCAL_LDFLAGS)
  • #1:make tool=中給tool賦值x86_g++
  • #2:獲取源文件
  • #3:轉換目標文件
  • #4:確定編譯工具
  • #5:編譯

2.3. arm_gcc分支

這個分支的應用場景:

  • 編譯工具:arm-gcc
  • 編譯文件類型:.c
    # arm_gcc ###################################################
    else ifeq ($(tool),arm_gcc) #1

    SRCS := $(shell ls *.c) #2
    OBJS := $(patsubst %.c,%.o,$(SRCS)) #3

    CC := /usr/local/gcc-3.4.6-glibc-2.3.3/bin/aarch32-linux-gnu-gcc    #4

    $(TARGET) : $(OBJS) #5
        $(CC) -o $@ $^ $(LOCAL_LDFLAGS)

    %.o:%.c
        $(CC) -c -o $@ $< $(LOCAL_LDFLAGS)
  • #1:make tool=中給tool賦值arm_gcc
  • #2:獲取源文件
  • #3:轉換目標文件
  • #4:確定編譯工具
  • #5:編譯

2.4. arm_g++分支

這個分支的應用場景:

  • 編譯工具:arm-g++
  • 編譯文件類型:.cpp
    # arm_g++ ###################################################
    else ifeq ($(tool),arm_g++) #1

    SRCS := $(shell ls *.cpp)   #2
    OBJS := $(patsubst %.cpp,%.o,$(SRCS))   #3

    CC := /usr/local/gcc-3.4.6-glibc-2.3.3/bin/aarch32-linux-gnu-g++    #4

    $(TARGET) : $(OBJS) #5
        $(CC) -o $@ $^ $(LOCAL_LDFLAGS)

    %.o:%.cpp
        $(CC) -c -o $@ $< $(LOCAL_LDFLAGS)
    endif
  • #1:make tool=中給tool賦值arm_g++
  • #2:獲取源文件
  • #3:轉換目標文件
  • #4:確定編譯工具
  • #5:編譯

3. 優化

3.1. 參數錯誤

由於這個Makefile要實現四個分支,需要通過"tool"的值來判斷,傳錯參數的情況發生的概率比較高,所以加入以下內容來判斷參數是否錯誤:

    ifneq ($(tool),)    #1
    .PHONY : PARAERROR  #2
    PARAERROR :
        @echo "Error : Parameters error."   #3
        @exit   #4
    endif
  • #1:經過之前的分支判斷,如果"tool"不爲空,說明參數傳錯;
  • #2:定義僞目標,便於添加命令;
  • #3:顯示錯誤提示;
  • #4:退出;
  • 該代碼段必須放到"分支"之後,"參數空"判斷前;

3.2. 參數空

後續會添加".clean"處理,如果不加參數空判斷,會使得使用"make"時執行".clean"的命令,體驗不好,處理如下:

ifeq ($(1),)    #1
.PHONY : PARAEMPTY  #2
PARAEMPTY :
	@echo "Error : Please enter parameters."    #3
	@exit   #4
endif
  • #1:判斷參數是否爲空;
  • #2:定義僞目標;
  • #3:顯示提示信息;
  • #4:退出
  • 該代碼段必須放到僞目標".clean"之前;

3.3. 僞目標.clean

添加僞目標,方便刪除編譯結果,便於重新編譯,實現如下:

PHONY : clean
clean :
    -rm -f $(TARGET) $(MAP_FILE_NAME).map *.o

4. 編譯

如果直接應用當前的makefile,每次編譯需要使用如下中的一個指令,需要在命令行輸入參數,還是有點不方便:

    make tool=x86_gcc   # 用於編譯分支一
    make tool=x86_g++   # 用於編譯分支二
    make tool=arm_gcc   # 用於編譯分支三
    make tool=arm_g++   # 用於編譯分支四

  爲了再方便一點,做如下處理:

    1. 在用戶家目錄的".bashrc"文件尾添加如下內容:
alias makexc='make tool=x86_gcc'
alias makex+='make tool=x86_g++'
alias makeac='make tool=arm_gcc'
alias makea+='make tool=arm_g++'
alias makecl='make clean'
    1. 命令行執行source ~/.bashrc,重新加載該文件;
    1. 接下來可以在終端直接輸入"makexc"、"makex+"、"makeac"、"makea+"、"makecl"命令來分別執行"make tool=x86_gcc" 、"make tool=x86_g++"、"make tool=arm_gcc"、"make tool=arm_g++"、"make clean"命令。

5. 備註

  • 需要用到其他編譯選型(-D、-std=c++11...)可自行添;
  • makefile中的"ifeq ()"中間需要一個空格;
  • makefile中命令開始必須是一個"tab";
  • 這裏的交叉編譯工具鏈是胡謅的,實際按照自己使用的修改;
  • 命令前加"@"表示不回顯命令;
  • 命令前加"-"表示出錯繼續向下處理。

 

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