1. 程式人生 > >初學Makefile——基本規則和習慣

初學Makefile——基本規則和習慣

面試被問到關於Makefile的問題,除了讀u-boot和核心的Makefile等機會偶爾接觸,根本就不熟悉,說讀出個大概意思吧?很多細節不知道又不容易理解,沒辦法,還是從頭動手練一下的好,這個行當,任何時候,不動手都是不行的。

可是話說回來,沒什麼專案什麼的怎麼找機會練Makefile,乾脆就把最簡單的程式拆開來,C語言基礎知識就不說了,大概意思就是寫個小程式,弄幾個簡單函式比如area()和sum()、print(),分別存在單獨的C檔案,再讓他們都“不辭勞苦”的引用幾個基礎標頭檔案或者引數設定和巨集。

head.h就只直接引用

#include<stdio.h>

parameter.h就是一個

#define PI 3.14

sum是

return a+b;

area是返回圓面積(引用parameter.h)

return PI*D*D;

不怕麻煩的可以自行設計和延展功能,不再贅述。

[email protected]:/usr/local/shellProgram/Project1# ls

 area.c    head.h  main main.c    Makefile  parameter.h sum.c 

#Makefile版本一

#定義依賴關係,最終成品main需要依賴如下三個物件

main: main.o sum.o area.o

#上邊那個結果的實現過程

       cc -o main main.o sum.o area.o

#同上,main.o物件需要依賴main.c和他引用的head.h,後邊跟上實現命令

main.o:main.c head.h

       cc -c main.c

sum.o:sum.c head.h

       cc -c sum.c

area.o:area.c head.h parameter.h

       cc -c area.c

clean:

       rm main main.o sum.o area.o

#注意clean需要單獨使用makeclean執行,會刪除所有.o檔案盒最終的結果main檔案

#所有命令都要用tab縮排,註釋用#,依賴關係用冒號。依賴多個需要空格分開。

上邊的東西比較簡單直觀,適合初學者,但是問題也很多,當你打算自己加個print功能進去,打算再加個計算體積函式,在Makefile版本一中要改三處,這在更大的工程中是無法想象的,所以需要進行改進,出現了版本二

#Makefile版本二

#定義objects引數(這個引數名自擬,不過為了方便理解,最好是相關單詞和簡稱)

objects = main.o sum.o area.o

 

#引用objects引數,形式為$(objects),把他理解為C語言的巨集,文字替換

#將所有用到main.o sum.o area.o的地方直接替換為$(objects)即可

main:$(objects)

       cc -o main $(objects)

main.o:main.c head.h

       cc -c main.c

sum.o:sum.c head.h

       cc -c sum.c

area.o:area.c head.h parameter.h

       cc -c area.c

clean:

       rm main $(objects)

和程式語言類似,所有功能都以人為本,很自然的,這裡引入了引數概念,一次定義,多次使用,修改時修改定義即可,是不是很方便呢?

好了,初級Makefile已經完成了,不過如果讀過其他的Makefile,會覺得略顯冗餘,別人的怎麼那麼簡潔呢,這就要提到指令碼的潛規則了——引入Makefile版本三

#Makefile版本三

 

objects = main.o sum.o area.o

 

main:$(objects)

       cc -o main $(objects)

#除了要你指定最終產出“main”的指令外,其他的CC全都刪了

main.o:main.c head.h

sum.o:sum.c head.h

area.o:area.c head.h parameter.h

#偽指令標識.Phony

.Phony:clean

clean:

       -rm main $(objects)


潛規則就是那些東西make會自己去尋找自己去編譯,不用自己指定命令。

另外就是偽指令了,像clean這種命令你給不依賴其他物件,也不產出任何目標檔案,純粹就是為了執行rm命令而設計。這時候你最好指定clean.Phony

最後,兩個很重要的需要保持的習慣:

減號“-”,回想u-boot等編譯過程,是不是看到一大堆錯誤出現而指令碼依然“風雨無阻”,這就是減號的作用了,他使得即使某處出現錯誤指令碼也能繼續執行,對於大型指令碼是非常重要的特性,而且加上也沒有害處,所以要養成習慣。

如果有一點經驗,會發現如果有多個標籤,並且不像本例是順次依賴的,是互相獨立的,類似於switch和case的結構,那麼指令碼預設執行第一個“分支”,為了防止各種意外發生,另外一個好習慣就是永遠把clean寫最後。

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

當然,除了一個目標依賴一群物件以外,也可以一群目標依賴一個物件,比如:

main.o sum.o area.o:head.h

但是回想一下,你又要一對多,又要多對一,眼花繚亂,到時候怎麼分辨,可讀性太差,就跟你寫個C語句不帶括號弄了一大堆加減號和星號似的,除非是參加程式設計大賽,不然害人害己,沒有太多現實價值。

相關推薦

初學Makefile——基本規則習慣

面試被問到關於Makefile的問題,除了讀u-boot和核心的Makefile等機會偶爾接觸,根本就不熟悉,說讀出個大概意思吧?很多細節不知道又不容易理解,沒辦法,還是從頭動手練一下的好,這個行當,任何時候,不動手都是不行的。 可是話說回來,沒什麼專案什麼的怎麼找機會練

Shell指令碼開發的基本規範習慣

1、指令碼第一行指定指令碼直譯器 #!/bin/bash 或 #!/bin/sh 2、指令碼開頭增加作者、指令碼作用描述等資訊 1 #!/bin/bash 2 #Author: iskylite 3 #Blog: http://www.cnblogs.com/iskylite/ 4 #Time: 2017-1

JavaScript初學基本概念語法

end 區分 基本概念 arguments rop delete 數量 amp nbsp ECMAScript 的語法大量借鑒了C及其他類C語言(如Java 和Perl)的語法。 1. 區分大小寫 2.標識符 2.1 第一個字符必須是一個字母、下劃線(_)或一個美元符

【一】makefile基本規則

1、基本格式: target(目標):prerequisites(依賴) command ... ... 注意:command的縮排必須使用tab,使用空格時會error。例子: image_bs: image_bs.o ../common/profile.o

HTML基本語法語義寫法規則與例項

DOCTYPE DOCTYPE(Document Type) 該宣告位於文件中最前面的位置,處於html標籤之前,此標籤告知瀏覽器文件使用哪種HTML或者 XHTML規範。 DTD(Document Type Definition) 宣告以<!DOCTYPE>開始,不區分大小寫,前面沒有任何內容

從頭開始寫專案Makefile(一):基本規則

【版權宣告:轉載請保留出處:blog.csdn.net/gentleliu。Mail:shallnew at 163 dot com】 一般一個稍大的linux專案會有很多個原始檔組成,最終的可執行程式也是由這許多個原始檔編譯連結而成的。編譯是把一個.c或.cpp檔案編譯成

Makefile (3) 基本語法使用

make是用來管理一個工程專案的工具 . Makefile就是這個專案檔案 . 1.Makefile 是由若干條規則組成的,每個規則的語法如下所示 : #規則 targets: prerequisites command #舉例 main.c func1.c

函式過載(overload)函式重寫(override)的基本規則

本文由Markdown語法編輯器編輯完成。 1. 前言:   在C++中有兩個非常容易混淆的概念,分別是函式過載(overload)和函式重寫(overwirte)。雖然只相差一個字,但是它們兩者之間的差別還是非常巨大的。而通過深入瞭解這兩個概念的區別,

Makefile基本規則

一、首先了解make是如何工作的,在預設的方式下,也就是我們只輸入make命令。會依次執行:     1、make會在當前目錄下找名字叫“Makefile”或“makefile”的檔案。     2、如果找到,它會找檔案中的第一個目標檔案(target)。     3、如

C語言標頭檔案包含編寫的幾個基本規則

總想著把所有的標頭檔案都塞到一個頭檔案裡邊,然後,所有.c檔案只包含這一個混雜的標頭檔案就行了,也不用注意太多,, 但是這樣好像不行,摘抄一篇文章備份一下,覺得寫的不錯, 尊重原創,原文連結:http://blog.csdn.net/ison81/article/det

C語言的本質(37)——makefile之隱含規則模式規則

Makefile有很多靈活的寫法,可以寫得更簡潔,同時減少出錯的可能。本節我們來看看這樣一個例子還有哪些改進的餘地。 一個目標依賴的所有條件不一定非得寫在一條規則中,也可以拆開寫,例如:main.o: main.h stack.h maze.h main.o: main.

基本型別轉換規則sizeof的用法

一.大範圍資料向小範圍轉換時的規則: 1.在轉換時和自身的型別有關和目標型別無關,,有符號的擴充符號位,無符號的擴充0. #include<stdio.h> int main() {     char c = 128;     unsigned char uc

貝葉斯算法的基本原理算法實現

utf shape less 流程 我們 def .sh 詞向量 貝葉斯算法 一. 貝葉斯公式推導   樸素貝葉斯分類是一種十分簡單的分類算法,叫它樸素是因為其思想基礎的簡單性:就文本分類而言,它認為詞袋中的兩兩詞之間的關系是相互獨立的,即一個對象 的特征向量

【Spark深入學習-11】Spark基本概念運行模式

nmf 磁盤 大數據平臺 並不是 鼠標 .cn 管理系統 大型數據集 spa ----本節內容------- 1.大數據基礎 1.1大數據平臺基本框架 1.2學習大數據的基礎 1.3學習Spark的Hadoop基礎 2.Hadoop生態基本介紹 2.1

sshd服務基本配置使用(201610改)

主目錄 兩個文件 pos home ref 保存 如果 鏈接 運行環境 一、基於密鑰認證的服務端基本安全設置:1、修改/etc/ssh/sshd_config,具體如下:Protocol 2 #只支持SSH2協議Port <端口號> #修改默認端口號Ma

Xml一(基本語法約束)、

字符 一行 語言 oca cas 書寫 xsd ati 寫法 XML:eXtensible Markup Language 可擴展標記語言 version="1.0"     * 可擴展:所有的標簽都是自定義的。     * 功能:數據存儲     * 配置文件  

C++11 圖說VS2013下的引用疊加規則模板參數類型推導規則

反匯編 cto 構造 這不 gif 怎麽辦 由於 pla 覆蓋 背景: 最近在學習C++STL,出於偶然,在C++Reference上看到了vector下的emplace_back函數,不想由此引發了一系列的“探索”,於是就有了現在這篇博文。 前言:

第15講++規則默認值對象

號碼 idt 綁定 至少 pla 默認 use 電話 對象 在xscj庫中定義1個規則,限制聯系電話的格式為“(區號)電話號碼”,其中區號為3位,電話號碼至少為6位 。 use xscj go create rule r_電話格式 as @

React框架搭建但頁面應用package.json基本依賴包

5.5 2.0 server 4.5 ack logs ostc style pac {  //依賴包 "devDependencies": {  //babel "babel-core": "6.24.1", "babel-loader": "7.0

Hibernate實體類編寫規則主鍵策略

有時 由於 rem 數據 數據類型 空間 存在 配置 hyper 一、實體類的編寫規則   1、屬性要是私有的。        2、要有公開的setter和getter方法供外界訪問和修改。        3、每一個實體類要有一個屬性作為唯一值(一般都是使用對於數據表的