1. 程式人生 > >Makefile中的符號說明

Makefile中的符號說明




1   GNU make
在大型的開發專案中,通常有幾十到上百個的原始檔,如果每次均手工鍵入 gcc命令進行編譯的話,則會非常不方便。因此,人們通常利用 make工具來自動完成編譯工作。這些工作包括:如果僅修改了某幾個原始檔,則只重新編譯這幾個原始檔;如果某個標頭檔案被修改了,則重新編譯所有包含該標頭檔案的原始檔。利用這種自動編譯可大大簡化開發工作,避免不必要的重新編譯。實際上,make工具通過一個稱為 makefile 的檔案來完成並自動維護編譯工作。makefile需要按照某種語法進行編寫,其中說明了如何編譯各個原始檔並連線生成可執行檔案,並定義了原始檔之間的依賴關係。當修改了其中某個原始檔時,如果其他原始檔依賴於該檔案,則也要重新編譯所有依賴該檔案的原始檔。


makefile
檔案是許多編譯器,包括 Windows NT下的編譯器維護編譯資訊的常用方法,只是在整合開發環境中,使用者通過友好的介面修改 makefile檔案而已。預設情況下,GNU make工具在當前工作目錄中按如下順序搜尋 makefile
* GNUmakefile
* makefile
* Makefile
UNIX系統中,習慣使用 Makefile 作為 makfile 檔案。如果要使用其他檔案作為 makefile,則可利用類似下面的 make命令選項指定 makefile 檔案:
$ make -f Makefile.debug

2   makefile基本結構makefile

中一般包含如下內容:
*
需要由 make工具建立的專案,通常是目標檔案和可執行檔案。通常使用目標(target一詞來表示要建立的專案。
*
要建立的專案依賴於哪些檔案。
*
建立每個專案時需要執行的命令。例如,假設你現在有一個 C++原始檔 test.C,該原始檔包含有自定義的標頭檔案 test.h,則目標檔案 test.o
明確依賴於兩個原始檔:test.C test.h。另外,你可能只希望利用 g++命令來生成 test.o 目標檔案。
這時,就可以利用如下的 makefile來定義 test.o 的建立規則:
# This makefile just is a example.
# The following lines indicate how test.o depends
# test.C and test.h, and how to create test.o
test.o: test.C test.h
     g++ -c -g test.C
從上面的例子注意到,第一個字元為 #的行為註釋行。第一個非註釋行指定 test.o 為目標,並且依賴於
test.C
test.h 檔案。隨後的行指定了如何從目標所依賴的檔案建立目標。
test.C test.h 檔案在編譯之後又被修改,則 make 工具可自動重新編譯 test.o,如果在前後兩次編譯之間,test.C test.h 均沒有被修改,而且 test.o 還存在的話,就沒有必要重新編譯。這種依賴關係在多原始檔的程式編譯中尤其重要。通過這種依賴關係的定義,make工具可避免許多不必要的編譯工作。當然,利用 Shell指令碼也可以達到自動編譯的效果,但是,Shell 指令碼將全部編譯任何原始檔,包括哪些不必要重新編譯的原始檔,而 make工具則可根據目標上一次編譯的時間和目標所依賴的原始檔的更新時間而自動判斷應當編譯哪個原始檔。一個 makefile檔案中可定義多個目標,利用 make target 命令可指定要編譯的目標,如果不指定目標,則使用第一個目標。通常,makefile中定義有 clean 目標,可用來清除編譯過程中的中間檔案,例如:
clean:
     rm -f *.o
執行 make clean時,將執行 rm -f *.o 命令,最終刪除所有編譯過程中產生的所有中間檔案。

3   makefile變數
GNU
make工具除提供有建立目標的基本功能之外,還有許多便於表達依賴性關係以及建立目標的命令的特色。其中之一就是變數或巨集的定義能力。如果你要以相同的編譯選項同時編譯十幾個 C原始檔,而為每個目標的編譯指定冗長的編譯選項的話,將是非常乏味的。但利用簡單的變數定義,可避免這種乏味的工作:
# Define macros for name of compiler
CC = gcc
# Define a macr o for the CC flags
CCFLAGS = -D_DEBUG -g -m486
# A rule for building a object file
test.o: test.c test.h
     $(CC) -c $(CCFLAGS) test.c
在上面的例子中,CC CCFLAGS 就是 make 的變數。GNU make通常稱之為變數,而其他 UNIX make
工具稱之為巨集,實際是同一個東西。在 makefile 中引用變數的值時,只需變數名之前新增 $符號,如
上面的 $(CC) $(CCFLAGS)

4   GNU make的主要預定義變數
GNU make
有許多預定義的變數,這些變數具有特殊的含義,可在規則中使用。表 1-5給出了一些主要的預定義變數,除這些變數外,GNU make還將所有的環境變數作為自己的預定義變數。 1-5   GNU make的主要預定義變數預定義變數含義
$*              
不包含副檔名的目標檔名稱。
$+              
所有的依賴檔案,以空格分開,並以出現的先後為序,可能包含重複的依賴檔案。
$<              
第一個依賴檔案的名稱。
$?              
所有的依賴檔案,以空格分開,這些依賴檔案的修改日期比目標的建立日期晚。
[email protected]              
目標的完整名稱。
$^              
所有的依賴檔案,以空格分開,不包含重複的依賴檔案。
$%              
如果目標是歸檔成員,則該變量表示目標的歸檔成員名稱。例如,如果目標名稱 mytarget.so(image.o),則 [email protected] mytarget.so,而 $% image.o
AR              
歸檔維護程式的名稱,預設值為 ar
ARFLAGS         
歸檔維護程式的選項。
AS              
彙編程式的名稱,預設值為 as
ASFLAGS         
彙編程式的選項。
CC               C
編譯器的名稱,預設值為 cc
CCFLAGS          C
編譯器的選項。
CPP              C
預編譯器的名稱,預設值為 $(CC) -E
CPPFLAGS         C
預編譯的選項。
CXX              C++
編譯器的名稱,預設值為 g++
CXXFLAGS         C++
編譯器的選項。
FC               FORTRAN
編譯器的名稱,預設值為 f77
FFLAGS           FORTRAN
編譯器的選項。

5  隱含規則
GNU make
包含有一些內建的或隱含的規則,這些規則定義瞭如何從不同的依賴檔案建立特定型別的目標。
GNU make
支援兩種型別的隱含規則:
*
字尾規則(Suffix Rule)。字尾規則是定義隱含規則的老風格方法。字尾規則定義了將一個具有某個字尾的檔案(例如,.c檔案)轉換為具有另外一種字尾的檔案(例如,.o 檔案)的方法。每個字尾規則以兩個成對出現的字尾名定義,例如,將 .c檔案轉換為 .o 檔案的字尾規則可定義為:
.c.o:
$(CC) $(CCFLAGS) $(CPPFLAGS) -c -o [email protected] $<
*
模式規則(pattern rules)。這種規則更加通用,因為可以利用模式規則定義更加複雜的依賴性規則。模式規則看起來非常類似於正則規則,但在目標名稱的前面多了一個 %號,同時可用來定義目標和依賴檔案之間的關係,例如下面的模式規則定義瞭如何將任意一個 X.c檔案轉換為 X.o 檔案:
%.c:%.o
$(CC) $(CCFLAGS) $(CPPFLAGS) -c -o [email protected] $<

6   makefile範例

。。。

7  執行 make我們知道,直接在 make命令的後面鍵入目標名可建立指定的目標,如果直接執行 make,則建立第一個目標。我們還知道可以用 make -f mymakefile這樣的命令指定 make 使用特定的 makefile,而不是預設的 GNUmakefilemakefile Makefile。但 GNU make 命令還有一些其他選項,表 1-6 給出了這些選項。 1-6   GNU make命令的常用命令列選項命令列選項含義
-C DIR              
在讀取 makefile之前改變到指定的目錄 DIR
-f FILE             
以指定的 FILE檔案作為 makefile
-h                  
顯示所有的 make選項。
-i                  
忽略所有的命令執行錯誤。
-I DIR              
當包含其他 makefile檔案時,可利用該選項指定搜尋目錄。
-n                  
只打印要執行的命令,但不執行這些命令。
-p                  
顯示 make變數資料庫和隱含規則。
-s                  
在執行命令時不顯示命令。
-w                  
在處理 makefile之前和之後,顯示工作目錄。
-W FILE             
假定檔案 FILE已經被修改。

8如何在Makefile中定義巨集進行條件編譯-- “-D”

在原始碼裡面如果這樣是定義的:
#ifdef MACRONAME
//
可選程式碼
   
#endif          
   
那在makefile裡面

gcc   -DMACRONAME=MACRODEF  
或者  
gcc   -DMACRONAME       
這樣就定義了預處理巨集,編譯的時候可選程式碼就會被編譯進去了。

舉例說明:

-Dmacro=string,等價於在標頭檔案中定義:#define   macro   string
-DTRUE=true
,等價於在標頭檔案中定義:#define   TRUE   true  
-Dmacro
,等價於在標頭檔案中定義:#define   macro   1,實際上也達到了定義:#define   macro的目的。

-DLINUX
,等價於:#define   LINUX   1(與#define   LINUX作用類似)。  
--define-macro   macro=string
-Dmacro=string作用相同。

9.其他符號

= 是最基本的賦值
  := 是覆蓋之前的值
  ?= 是如果沒有被賦值過就賦予等號後面的值
  += 是新增等號後面的值
  1、“=”
  make會將整個makefile展開後,再決定變數的值。也就是說,變數的值將會是整個makefile中最後被指定的值。看例子:
  x = foo
y = $(x) bar
x = xyz
  在上例中,y的值將會是 xyz bar ,而不是 foo bar 。
  2、“:=”
  “:=”表示變數的值決定於它在makefile中的位置,而不是整個makefile展開後的最終值。
  x := foo
y := $(x) bar
x := xyz
  在上例中,y的值將會是 foo bar ,而不是 xyz bar 了。



相關推薦

makefile的特殊符號及關鍵字

目標 需要 編寫 ats www. 如果 符號 placement ace 1.常見自動變量和含義 * :表示目標文件的名稱,不包含目標文件的擴展名。 + :表示所有的依賴文件,這些依賴文件之間以空格分開,按照出現的先後為順序,其中可能包含重復的依賴文件。 < :表

uboot的主Makefile變數MKCONFIG建立符號連結相關問題

在uboot的主Makefile中,定義了一個變數:MKCONFIG    := $(SRCTREE)/mkconfig。 該MKCONFIG 變數即為源程式目錄下的mkconfig指令碼檔案,該檔案在uboot的前期配置操作時會用到。 x210_sd_conf

工程Makefile常用符號

Makefile中常見內容 TOPDIR := $(shell /bin/pwd) CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ else if [ -x /bin/bash ]; the

Makefile符號說明

 1   GNU make在大型的開發專案中,通常有幾十到上百個的原始檔,如果每次均手工鍵入 gcc命令進行編譯的話,則會非常不方便。因此,人們通常利用 make工具來自動完成編譯工作。這些工作包括:如果僅修改了某幾個原始檔,則只重新編譯這幾個原始檔;如果某個標頭檔案被

Makefile常用的一些符號

1 環境變數 1.1 編譯器 CC // C語言編譯器,預設值為gcc CXX // C++語言編譯器,預設值為g++ 說明:這是預設的變數,無需使用者自定義(但是使用者可以修改其值,例如CC=arm-linux-gcc,用於交叉編譯)。 1.2 編譯器引數 C

makefile的一點知識

color 一點 pan col get ack 是什麽 makefile track makefile文件裏以下這一部分展開是什麽樣的呢?。。。mytarget=foo $(mytarget): $(mytarget).c gcc -o $(mytarge

Makefile怎樣調用python和perl文件為自己提供須要的數據

print erl col shel ria 實例代碼 space shell eight Makefile中怎樣調用python和perl文件為自己提供須要的數據,利用print函數對外輸出數據 實例代碼例如以下 perl.pl #!/usr/bin/per

php--在類常量的關鍵字

繼承 con def 屬性 實例 類名 () 接口 屬性。 Final、static、const、instanceod Final :final關鍵字可以加在類或者類中方法之前,但是不能使用final標識成員屬性。     作用: 使用final標識的類,不能被繼承。

為什麽C++和定義要分開寫

使用 還得 開始 階段 怎麽辦 clu 即使 tip 文件中 現在開始寫項目了,你會發現我們一般都要寫一個cpp,對應的還得有一個h文件,那麽為什麽在C++中我們要這麽做? .h就是聲明,.cpp就是實現,而所謂分離式實現就是指“聲明”和“定義”分別保存在不同的文件中,聲明

Makefileexport分析

platform 打出 ont style focus false pla ext make 在分析內核啟動過程的./arch/arm/Makefile文件裏碰到了這樣字段 162 export TEXT_OFFSET GZFLAGS MMUEXT   然後在子目錄a

通用 Makefile(及makefile的notdir,wildcard和patsubst)

and har alt table free modify sources follow rul notdir,wildcard和patsubst是makefile中幾個有用的函數,以前沒留意過makefile中函數的用法,今天稍微看看~ 1、makefile裏的函數

Makefile的函數

自動 pad 返回值 file all def wid words black Makefile 中的函數 Makefile 中自帶了一些函數, 利用這些函數可以簡化 Makefile 的編寫. 函數調用語法如下: $(<function> <argum

Electron與jQuery$符號沖突的三種解決方法

jquer obj define export tro conf jquery blog ack   在Electron工程中引用jQuery時,經常會出現以下錯誤: Uncaught ReferenceError: $ is not defined   解決的具體方

關於makefile變量的多次賦值以及override指令

順序 使用 += 令行 所有 命令 也不會 makefile err 1 基本原則如下 1.1 原則1 變量的普通賦值是有先後順序的,後面的賦值會覆蓋掉前面的賦值。 1.2 原則2 使用的時候,用的是其前面最後的賦值,就算其後面有使用了override指令的賦值也不會影響這

makefile=、:=和+=的區別

有感 分析 eight c語言 區別 all ont 總結 mil 經常有人分不清= 、:=和+=的區別 這裏我總結下做下詳細的分析: 首先你得清楚makefile的運行環境,因為我是linux系統,那麽我得運行環境是shell 在Linux的shell裏,shell

Java入門-類HelloWorld是公共的,應在名為HelloWorld.java的文件

world! void java源代碼 clas pan 保存文件 -h 明顯 命令行 public class HelloWorld { public static void main(String[] args) { System.ou

C++常用頭文件的函數及類

ani size com 組織 blog cout log string 函數 iostream 僅包含<iostream>可以使用string類,但是string類的運算符"<<"是在頭文件<string>中重載的。因此要使用cout對

Spring 實戰-第四章-4.4 使用xml切面及引入新方法

cati sys epp proc oca cover tor ring tex 當不能直接接觸源碼時,同樣的不能給源碼增加註解,這時可以使用xml的方式聲明切面並引入新方法 CompactDisc接口 package main.java.soundsystem;

Makefile常見的自動變量和含義

makefile info 自動 vmm var p s xms userinfo href 劫V3W71v9QGW貝膳http://jz.docin.com/cjwjy04096 1姥樸5KAQ訪顯39http://shufang.docin.com/fjqbs11

【正則表達式】linux符號 及 正則表達式

lin int echo 字符 linux中 pri style pre 匹配 【符號】 # 換行 \n echo -e "yy\nwy" yy wy 【正則表達式】 cat test.txt yy1%yy2,yy3,yy4%yy5 # [,%