1. 程式人生 > >makefile詳解 函式 foreach if call origin shell 控制make函式 二十二

makefile詳解 函式 foreach if call origin shell 控制make函式 二十二

四、foreach 函式
 

foreach函式和別的函式非常的不一樣。因為這個函式是用來做迴圈用的,Makefile中的foreach函式幾乎是仿照於Unix標準Shell(/bin/sh)中的for語句,或是C-Shell(/bin/csh)中的foreach語句而構建的。它的語法是:

 

    $(foreach <var>;,<list>;,<text>;)

 

這個函式的意思是,把引數<list>;中的單詞逐一取出放到引數<var>;所指定的變數中,然後再執行<text>;所包含的表示式。每一次<text>;會返回一個字串,迴圈過程中,<text>;的所返回的每個字串會以空格分隔,最後當整個迴圈結束時,<text>;所返回的每個字串所組成的整個字串(以空格分隔)將會是foreach函式的返回值。

 

所以,<var>;最好是一個變數名,<list>;可以是一個表示式,而<text>;中一般會使用<var>;這個引數來依次列舉<list>;中的單詞。舉個例子:

 

    names := a b c d

    files := $(foreach n,$(names),$(n).o)

 

上面的例子中,$(name)中的單詞會被挨個取出,並存到變數“n”中,“$(n).o”每次根據“$(n)”計算出一個值,這些值以空格分隔,最後作為foreach函式的返回,所以,$(files)的值是“a.o b.o c.o d.o”。

 

注意,foreach中的<var>;引數是一個臨時的區域性變數,foreach函式執行完後,引數<var>;的變數將不在作用,其作用域只在foreach函式當中。

 

 

五、if 函式
 

if函式很像GNU的make所支援的條件語句——ifeq(參見前面所述的章節),if函式的語法是:

 

    $(if <condition>;,<then-part>;) 

 

或是

 

    $(if <condition>;,<then-part>;,<else-part>;)

 

可見,if函式可以包含“else”部分,或是不含。即if函式的引數可以是兩個,也可以是三個。<condition>;引數是if的表示式,如果其返回的為非空字串,那麼這個表示式就相當於返回真,於是,<then-part>;會被計算,否則<else-part>;會被計算。

 

而if函式的返回值是,如果<condition>;為真(非空字串),那個<then-part>;會是整個函式的返回值,如果<condition>;為假(空字串),那麼<else-part>;會是整個函式的返回值,此時如果<else-part>;沒有被定義,那麼,整個函式返回空字串。

 

所以,<then-part>;和<else-part>;只會有一個被計算。

 

 

六、call函式
 

call函式是唯一一個可以用來建立新的引數化的函式。你可以寫一個非常複雜的表示式,這個表示式中,你可以定義許多引數,然後你可以用call函式來向這個表示式傳遞引數。其語法是:

 

    $(call <expression>;,<parm1>;,<parm2>;,<parm3>;...)

 

當make執行這個函式時,<expression>;引數中的變數,如$(1),$(2),$(3)等,會被引數<parm1>;,<parm2>;,<parm3>;依次取代。而<expression>;的返回值就是call函式的返回值。例如:

    reverse =  $(1) $(2)

    foo = $(call reverse,a,b)



那麼,foo的值就是“a b”。當然,引數的次序是可以自定義的,不一定是順序的,如:

 

    reverse =  $(2) $(1)

    foo = $(call reverse,a,b)



此時的foo的值就是“b a”。

 

 

七、origin函式
origin函式不像其它的函式,他並不操作變數的值,他只是告訴你你的這個變數是哪裡來的?其語法是:

 

    $(origin <variable>;)

 

注意,<variable>;是變數的名字,不應該是引用。所以你最好不要在<variable>;中使用“$”字元。Origin函式會以其返回值來告訴你這個變數的“出生情況”,下面,是origin函式的返回值:

 

“undefined”

      如果<variable>;從來沒有定義過,origin函式返回這個值“undefined”。

 

“default”

      如果<variable>;是一個預設的定義,比如“CC”這個變數,這種變數我們將在後面講述。

 

“environment”

      如果<variable>;是一個環境變數,並且當Makefile被執行時,“-e”引數沒有被開啟。

 

“file”

      如果<variable>;這個變數被定義在Makefile中。

 

“command line”

      如果<variable>;這個變數是被命令列定義的。

 

“override”

      如果<variable>;是被override指示符重新定義的。

 

“automatic”

      如果<variable>;是一個命令執行中的自動化變數。關於自動化變數將在後面講述。

 

這些資訊對於我們編寫Makefile是非常有用的,例如,假設我們有一個Makefile其包了一個定義檔案Make.def,在Make.def中定義了一個變數“bletch”,而我們的環境中也有一個環境變數“bletch”,此時,我們想判斷一下,如果變數來源於環境,那麼我們就把之重定義了,如果來源於Make.def或是命令列等非環境的,那麼我們就不重新定義它。於是,在我們的Makefile中,我們可以這樣寫:

 

    ifdef bletch

    ifeq "$(origin bletch)" "environment"

    bletch = barf, gag, etc.

    endif

    endif

 

當然,你也許會說,使用override關鍵字不就可以重新定義環境中的變量了嗎?為什麼需要使用這樣的步驟?是的,我們用override是可以達到這樣的效果,可是override過於粗暴,它同時會把從命令列定義的變數也覆蓋了,而我們只想重新定義環境傳來的,而不想重新定義命令列傳來的。

 

 

八、shell函式
 

shell函式也不像其它的函式。顧名思義,它的引數應該就是作業系統Shell的命令。它和反引號“`”是相同的功能。這就是說,shell函式把執行作業系統命令後的輸出作為函式返回。於是,我們可以用作業系統命令以及字串處理命令awk,sed等等命令來生成一個變數,如:

 

    contents := $(shell cat foo)

 

    files := $(shell echo *.c)

 

注意,這個函式會新生成一個Shell程式來執行命令,所以你要注意其執行效能,如果你的Makefile中有一些比較複雜的規則,並大量使用了這個函式,那麼對於你的系統性能是有害的。特別是Makefile的隱晦的規則可能會讓你的shell函式執行的次數比你想像的多得多。

 

 

九、控制make的函式
 

make提供了一些函式來控制make的執行。通常,你需要檢測一些執行Makefile時的執行時資訊,並且根據這些資訊來決定,你是讓make繼續執行,還是停止。

 

$(error <text ...>;)

 

    產生一個致命的錯誤,<text ...>;是錯誤資訊。注意,error函式不會在一被使用就會產生錯誤資訊,所以如果你把其定義在某個變數中,並在後續的指令碼中使用這個變數,那麼也是可以的。例如:

 

    示例一:

    ifdef ERROR_001

    $(error error is $(ERROR_001))

    endif

 

    示例二:

    ERR = $(error found an error!)

    .PHONY: err

    err: ; $(ERR)

 

    示例一會在變數ERROR_001定義了後執行時產生error呼叫,而示例二則在目錄err被執行時才發生error呼叫。

 

$(warning <text ...>;)

 

     這個函式很像error函式,只是它並不會讓make退出,只是輸出一段警告資訊,而make繼續執行。

相關推薦

makefile 函式 foreach if call origin shell 控制make函式

四、foreach 函式   foreach函式和別的函式非常的不一樣。因為這個函式是用來做迴圈用的,Makefile中的foreach函式幾乎是仿照於Unix標準Shell(/bin/sh)中的for語句,或是C-Shell(/bin/csh)中的foreach語句而構建的。它的語法是:       $(f

makefile 使用make更新函式庫檔案(結束)

使用make更新函式庫檔案 ——————————— 函式庫檔案也就是對Object檔案(程式編譯的中間檔案)的打包檔案。在Unix下,一般是由命令"ar"來完成打包工作。 一、函式庫檔案的成員 一個函式庫檔案由多個檔案組成。你可以以如下格式指定函式庫檔案及其組成:     archive(member) 這個

makefile 函式 字串 檔名

在Makefile中可以使用函式來處理變數,從而讓我們的命令或是規則更為的靈活和具有智慧。make所支援的函式也不算很多,不過已經足夠我們的操作了。函式呼叫後,函式的返回值可以當做變數來使用。 一、函式的呼叫語法 函式呼叫,很像變數的使用,也是以“$”來標識的,其語法如下:     $(<functio

makefile

makefile原文鏈接:https://blog.csdn.net/qq_38646470/article/details/79917494專欄鏈接:https://blog.csdn.net/column/details/20028.html    或許很多Wino

Linux下多資料夾編寫Makefile

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

MySQL自定義函式用法-複合結構自定義變數/流程控制

自定義函式 (user-defined function UDF)就是用一個象ABS() 或 CONCAT()這樣的固有(內建)函式一樣作用的新函式去擴充套件MySQL。 所以UDF是對MySQL功能的一個擴充套件 建立和刪除自定義函式語法: 建立UDF:   CREATE 

【裝飾器】Python的裝飾器--為已經存在的函式或物件新增額外的功能

寫的非常好的文章,原文在:http://www.cnblogs.com/cicaday/p/python-decorator.html Python中的裝飾器是你進入Python大門的一道坎,不管你跨不跨過去它都在那裡。 為什麼需要裝飾器 我們假設你的程式實現了say_hello()和s

網路程式設計必會的poll和epoll函式

  前言   之前已經介紹過select函式,請參考這篇部落格:https://www.cnblogs.com/liudw-0215/p/9661583.html,原理都是類似的,有時間先閱讀下那篇部落格,以便於理解這篇部落格。   一、poll函式   1、函式說明   原型:int poll(st

6 個例項如何把 if-else 程式碼重構成高質量程式碼

6 個例項詳解如何把 if-else 程式碼重構成高質量程式碼   轉載自  Java技術驛站  微信公眾號  原文連結: https://mp.weixin.qq.com/s/bMbtlyGmrrL9OxNz7LeZ-w

Array物件屬性9-forEach

Array物件屬性 Array物件屬性九( forEach() - ES6) forEach() 方法用於呼叫陣列的每個元素,並將元素傳遞給回撥函式。 注意: forEach() 對於空陣列是不會執行回撥函式的。 語法 array.forEach(func

KConfig、Makefile以及ARM平臺Linux核心的編譯

下面講解一個綜合例項,假設我們要在核心原始碼drivers目錄下為ARM體系結 構新增如下用於test driver 的樹型目錄: |--test |-- cpu | -- cpu.c |-- test.c |-- test_client.c |-- test_ioctl.c |-- test_proc.c

MAKEFILE 多目標 靜態模式 十三

六、多目標 Makefile的規則中的目標可以不止一個,其支援多目標,有可能我們的多個目標同時依賴於一個檔案,並且其生成的命令大體類似。於是我們就能把其合併起來。當然,多個目標的生成規則的執行命令是同一個,這可能會可我們帶來麻煩,不過好在我們的可以使用一個自動化變數“[email protected

makefile make 的執行 十三

make 的執行 —————— 一般來說,最簡單的就是直接在命令列下輸入make命令,make命令會找當前目錄的makefile來執行,一切都是自動的。但也有時你也許只想讓make重編譯某些檔案,而不是整個工程,而又有的時候你有幾套編譯規則,你想在不同的時候使用不同的編譯規則,等等。本章節就是講述如何使用ma

makefile 隱含規則

隱含規則 ———— 在我們使用Makefile時,有一些我們會經常使用,而且使用頻率非常高的東西,比如,我們編譯C/C++的源程式為中間目標檔案(Unix下是[.o]檔案,Windows下是[.obj]檔案)。本章講述的就是一些在Makefile中的“隱含的”,早先約定了的,不需要我們再寫出來的規則。 “隱含

makefile 條件判斷

使用條件判斷 —————— 使用條件判斷,可以讓make根據執行時的不同情況選擇不同的執行分支。條件表示式可以是比較變數的值,或是比較變數和常量的值。 一、示例 下面的例子,判斷$(CC)變數是否“gcc”,如果是的話,則使用GNU函式編譯目標。     libs_for_gcc = -lgnu     no

makefile 多行變數 環境變數 目標變數 模式變數

六、多行變數   還有一種設定變數值的方法是使用define關鍵字。使用define關鍵字設定變數的值可以有換行,這有利於定義一系列的命令(前面我們講過“命令包”的技術就是利用這個關鍵字)。 define指示符後面跟的是變數的名字,而重起一行定義變數的值,定義是以endef關鍵字結束。其工作方式和“=”操作符

makefile 定義模式規則

五、定義模式規則 你可以使用模式規則來定義一個隱含規則。一個模式規則就好像一個一般的規則,只是在規則中,目標的定義需要有"%"字元。"%"的意思是表示一個或多個任意字元。在依賴目標中同樣可以使用"%",只是依賴目標中的"%"的取值,取決於其目標。 有一點需要注意的是,"%"的展開發生在變數和函式的展開之後,變

linux下的Makefile(5)

使用條件判斷 —————— 使用條件判斷,可以讓make根據執行時的不同情況選擇不同的執行分支。條件表示式可以是比較變數的值,或是比較變數和常量的值。 一、示例 下面的例子,判斷$(CC)變數是否“gcc”,如果是的話,則使用GNU函式編譯目標。 libs_for_gcc = -lgnu normal_lib

Makefile(自己覺得重新看一次學了好多東西,紅色字)

Makefile詳解 跟我一起寫 Makefile 陳皓 概述 —— 什麼是makefile?或許很多Winodws的程式設計師都不知道這個東西,因為那些Windows的IDE都為你做了這個工作,但我覺得要作一個好的和professional的程式設計師,mak

Makefile—clean

每個Makefile中都應該寫一個清空目標檔案(.o和執行檔案)的規則,這不僅便於重編譯,也很利於保持檔案的清潔。這是一個“修養”。一般的風格都是:clean:rm edit $(objects)更為穩健的做法是:.PHONY : cleanclean :-rm edit