next up previous contents
Next: 函式庫管理 Up: 開發工具 - makefile 其他功能 Previous: 多重目標項目(target)   Contents

Makefile 其他法則

  • 檔尾(suffix)和符號(pattern)法則:
    # 將 .old_suffix 的檔案變成 .new_suffix 的檔案
    
    # 符號法則 1
    .<old_suffix>.<new_suffix>:
    
    # 符號法則 2
    %.<old_suffix>: %.<new_suffix>:
    
  • 例題:將 .cpp 檔案變成 .o 檔案:
    1. 符號法則 1:
      .SUFFIXES:      .cpp
      .cpp.o:
         $(CC) -xc++ $(CFLAGS) -I$(INCLUDE) -c $<
      # gcc 的 -xc++ 旗標告訴編譯器,它是一個 C++ 原始碼檔案。
      # 變數 $< 代表目前的相依性項目,會被展開成為原本的檔案名稱(含舊的檔尾)。
      
    2. 符號法則 2:
      %.o: %.cpp
         $(CC) -xc++ $(CFLAGS) -I$(INCLUDE) -c $<
      

  • 內建的法則:借助檔尾(suffix), make 即知使用什麼法則。
    1. 可以利用 -p 選項,要求 make 印出內建法則,截取部分如下:
      [dywang@dywOffice ~]$ make -p | vi -
      OUTPUT_OPTION = -o $@
      CXX = g++ ###(gcc)
      COMPILE.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
      COMPILE.C = $(COMPILE.cc)
      COMPILE.cpp = $(COMPILE.cc)
      
      %.o: %.c
      # commands to execute (built-in):
            $(COMPILE.cc) $(OUTPUT_OPTION) $<
      
    2. 例題:將 .c 檔尾的檔案變成 .o 檔尾的檔案。
      1. 編輯 foo.c,(傳統的 Hello World 程式)。
        #include <stdlib.h>
        #include <stdio.h>
        int main()
        {
            printf("Hello World\n");
            exit(EXIT_SUCCESS);
        }
        
      2. 藉由 make 編譯程式,但沒有指定 makefile。
        $ make foo
        cc     foo.c   -o foo
        $
        
      3. 若不使用內建法則,可以於 make 時,直接加入參數
        $ rm foo
        $ make CC=gcc CFLAGS="-Wall -g" foo
        gcc -Wall -g    foo.c   -o foo
        $
        
    3. 可以借用內建法則,簡化 Makefile3 中之編譯法則,儲存為 Makefile4:
      main.o: main.c a.h
      #   $(CC) -I$(INCLUDE) $(CFLAGS) -c main.c
      2.o: 2.c a.h b.h
      #   $(CC) -I$(INCLUDE) $(CFLAGS) -c 2.c
      3.o: 3.c b.h c.h
      #   $(CC) -I$(INCLUDE) $(CFLAGS) -c 3.c
      # 註解部分為原 Makefile3 之編譯法則
      
練習題
  1. 請使用兩種方式寫出,將 .cpp 的檔案變成 .o 的檔案法則。
    Sol. .cpp.o:%.o: %.cpp
  2. makefile 中有一 .cpp.o 之編譯法則 $(CC) -xc++ -c $<,其中 -xc++ 代表意義為何?
    Sol. gcc 的 -xc++ 旗標告訴編譯器,它是一個 C++ 原始碼檔案。
  3. makefile 中有一 .cpp.o 之編譯法則 $(CC) -xc++ -c $<,其中 $< 代表意義為何?
    Sol. 變數 $< 代表目前的相依性項目,會被展開成為原本的檔案名稱(含舊的檔尾)。
  4. 如何要求 make 印出其內建法則?
    Sol. make -p
  5. 何謂 make 的內建法則?
    Sol. 若 makefile 中沒指定法則,則 make 會以內建法則執行,因此可簡化 makefile。
  6. make 的內建法則,編譯器使用 cc,若要改用 gcc 編譯 foo,但 makefile 中沒指定,需如何做?
    Sol. 直接於 make 時加入參數: make CC=gcc foo
  7. 若 makefile 中有目標項目 main.o: main.c a.h,但未指定其編譯法則,則 make 會怎麼執行?
    Sol. 使用內建法則,產生目標項目 main.o



2017-06-14