makefile寫法實例




轉載自:http://blog.csdn.net/gubenpeiyuan/article/details/8128805

makefile例子

假設我們有一個程序由5個文件組成,源代碼如下:

/*main.c*/

#include"mytool1.h"

#include"mytool2.h"

int main()

{

    mytool1_print("hello mytool1!");

    mytool2_print("hello mytool2!");

    return 0;

}

 

/*mytool1.c*/

#include"mytool1.h"

#include<stdio.h>

void mytool1_print(char *print_str)

{

    printf("This is mytool1 print : %s ", print_str);

}

 

/*mytool1.h*/

#ifndef _MYTOOL_1_H

#define _MYTOOL_1_H

void mytool1_print(char *print_str);

#endif

 

/*mytool2.c*/

#include"mytool2.h"

#include<stdio.h>

void mytool2_print(char *print_str)

{

    printf("This is mytool2 print : %s ", print_str);

}

 

/*mytool2.h*/

#ifndef _MYTOOL_2_H

#define _MYTOOL_2_H

void mytool2_print(char *print_str);

#endif

首先了解一下makeMakefileGNU make是一個工程管理器,它可以管理較多的文件。我所使用的RedHat 9.0make版本為GNU Make version 3.79.1。使用make的最大好處就是實現了自動化編譯。如果有一個上百個文件的代碼構成的項目,其中一個或者幾個文件進行了修改,make就能夠自動識別更新了的文件代碼,不需要輸入冗長的命令行就可以完成最后的編譯工作。make執行時,自動尋找Makefilemakefile)文件,然后執行編譯工作。所以我們需要編寫Makefile文件,這樣可以提高實際項目的工作效率。

    在一個Makefile中通常包含下面內容:

1、需要由make工具創建的目標體(target),通常是目標文件或可執行文件。

2、要創建的目標體所依賴的文件(dependency_file)。

3、創建每個目標體時需要運行的命令(command)。

格式如下:

targetdependency_files

<TAB>command

 

target:規則的目標。通常是程序中間或者最后需要生成的文件名,可以是.o文件、也可以是最后的可執行程序的文件名。另外,目標也可以是一個make執行的動作的名稱,如目標“clean”,這樣的目標稱為偽目標

dependency_files:規則的依賴。生成規則目標所需要的文件名列表。通常一個目標依賴於一個或者多個文件。

 

command:規則的命令行。是make程序所有執行的動作(任意的shell命令或者可在shell下執行的程序)一個規則可以有多個命令行,每一條命令占一行。注意:每一個命令行必須以[Tab]字符開始,[Tab]字符告訴make此行是一個命令行。make按照命令完成相應的動作。這也是書寫Makefile中容易產生,而且比較隱蔽的錯誤。命令就是在任何一個目標的依賴文件發生變化后重建目標的動作描述。一個目標可以沒有依賴而只有動作(指定的命令)。比如Makefile中的目標“clean”,此目標沒有依賴,只有命令。它所指定的命令用來刪除make過程產生的中間文件(清理工作)。

 

Makefile規則就是描述在什么情況下、如何重建規則的目標文件,通常規則中包括了目標的依賴關系(目標的依賴文件)和重建目標的命令。make執行重建目標的命令,來創建或者重建規則的目標(此目標文件也可以是觸發這個規則的上一個規則中的依賴文件)。規則包含了目標和依賴的關系以及更新目標所要求的命令。

Makefile中可以包含除規則以外的部分。一個最簡單的Makefile可能只包含規則描述。規則在有些Makefile中可能看起來非常復雜,但是無論規則的書寫是多么的復雜,它都符合規則的基本格式。

下面就可以寫出第一個Makefile了。

main:main.o mytool1.o mytool2.o

    gcc -o main main.o mytool1.o mytool2.o

main.o:main.c mytool1.h mytool2.h

    gcc -c main.c

mytool1.o:mytool1.c mytool1.h

    gcc -c mytool1.c

mytool2.o:mytool2.c mytool2.h

    gcc -c mytool2.c

clean:

    rm -f *.o main

 

shell提示符下輸入make,執行顯示:

gcc -c main.c

gcc -c mytool1.c

gcc -c mytool2.c

gcc -o main main.o mytool1.o mytool2.o

 

執行結果如下:

[armlinux@lqm makefile-easy]$ ./main

This is mytool1 print : hello mytool1!

This is mytool2 print : hello mytool2!

 

這只是最為初級的Makefile,現在來對這個Makefile進行改進。

改進一:使用變量

一般在書寫Makefile時,各部分變量引用的格式如下:

1. make變量(Mak1. make變量(Makefile中定義的或者是make的環境變量)的引用使用“$(VAR)”格式,無論“VAR”是單字符變量名還是多字符變量名。

2. 出現在規則命令行中shell變量(一般為執行命令過程中的臨時變量,它不屬於Makefile變量,而是一個shell變量)引用使用shell“$tmp”格式。

3. 對出現在命令行中的make變量同樣使用“$(CMDVAR)” 格式來引用。

OBJ=main.o mytool1.o mytool2.o

make:$(OBJ)

    gcc -o main $(OBJ)

main.o:main.c mytool1.h mytool2.h

    gcc -c main.c

mytool1.o:mytool1.c mytool1.h

    gcc -c mytool1.c

mytool2.o:mytool2.c mytool2.h

    gcc -c mytool2.c

clean:

    rm -f main $(OBJ)

 

改進二:使用自動推導

make自動推導,只要make看到一個.o文件,它就會自動的把對應的.c文件加到依賴文件中,並且gcc c  .c也會被推導出來,所以Makefile就簡化了。

CC = gcc

OBJ = main.o mytool1.o mytool2.o

make: $(OBJ)

    $(CC) -o main $(OBJ)

main.o: mytool1.h mytool2.h

mytool1.o: mytool1.h

mytool2.o: mytool2.h

.PHONY: clean

clean:

    rm -f main $(OBJ)

 

改進三:自動變量($^  $<  $@)的應用

Makefile 有三個非常有用的變量,分別是$@$^$<。代表的意義分別是:

$@--目標文件,

$^--所有的依賴文件,

$<--第一個依賴文件。

CC = gcc

OBJ = main.o mytool1.o mytool2.o

 

main: $(OBJ)

    $(CC) -o $@ $^

 

main.o: main.c mytool1.h mytool2.h

    $(CC) -c $<

mytool1.o: mytool1.c mytool1.h

    $(CC) -c $<

mytool2.o: mytool2.c mytool2.h

    $(CC) -c $<

 

.PHONY: clean

clean:

    rm -f main $(OBJ)

     這些是最為初級的知識,現在至少可以減少編譯時的工作量。細節方面的東西還需要在以后的工作和學習中不斷的總結,不斷的深化理解。可以 參考GNU Make手冊,這里講解的比較全面。

= = = = =最后的交叉編譯= = = = =

CC = /usr/local/arm/2.95.3/bin/arm-linux-gcc

OBJ = main.o mytool1.o mytool2.o

tar:$(OBJ)

    $(CC) $^ -o $@

main.o:mytool1.h mytool2.h

mytool1.o:mytool1.h

mytool2.o:mytool2.h

clean:

    rm -f $(OBJ)tar

 

 

下面是tc中makefile的例子  
  假設項目中有三個文件main.c、support.c、support.h,則Makefile可以這么寫:    
  代碼:    
   
  all   :   mygame      
  mygame   :   main.o   support.o      
                  tcc   -o   mygame   main.o   support.o      
  support.o   :   support.c   support.h      
                  tcc   -c   support.c      
  main.o   :   main.c      
                  tcc   -c   main.c       
       
    
  注意tcc前的分隔符要用tab。

 

 

 

這里是全自動Makefile的例子,在Linux下運行良好,我沒試過tc下能不能正常使用。   
    
  代碼:         
  EXENAME   =   mygame      
  CC   =   tcc      
  CFLAGS   =   -O2      
  INCLUDE   =      
  LIBS   =      
  HEADER   =      
  OBJS   =   main.o   support.o               
  all:   $(EXENAME)               
  .c.o:      
                  $(CC)   -c   $(CFLAGS)   $(INCLUDE)   $<         
  $(EXENAME):   $(OBJS)    
                  $(CC)   -o   $(EXENAME)   $(OBJS)   $(LIBS)     
    
    
  就算項目中有再多的文件,也只需在“OBJS   =   ”一行再寫入filename.o就可以了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM