1. 程式人生 > >make的使用和Makefile的編寫

make的使用和Makefile的編寫

標籤: Linux C/C++開發

簡介

  • make:維護程式模組關係和生成可執行程式的工具
  • makefile:定義了整個專案的編譯規則,定義了模組間的依賴關係,指定檔案的編譯順序和編譯使用的命令
  • makemakefile檔案中獲取模組間的依賴關係,判斷哪些檔案過時了,根據這些資訊make確定哪些檔案需要重新編譯,然後使用makefile中的編譯命令進行編譯
  • 過時:一個檔案生成後,用來生成該檔案的原始檔或者標頭檔案被修改了,導致生成該檔案所需要的原始檔或標頭檔案的修改時間比生成該檔案的時間晚

make使用

基本構成

目標檔案列表 分隔符 依賴檔案列表 [; 命令]
    [命令]
    [命令]
  • 如果某一行是命令,必須以Tab鍵開始
  • #為註釋行
#示例1
main:main.o module1.o module2.o ; gcc main.o module1.o module2.o -o main
main.o:main.c head1.h head2.h common_head.h
    gcc -c main.c

#示例2
main:main.o module1.o module2.o 
    gcc main.o module1.o
module2.o -o main main.o: head1.h head2.h common_head.h module1.o:head1.h module2.o:head2.h

流程

  1. 在當前目錄下找名為Makefile或makefile的檔案
  2. 在當前目錄下尋找第一行中的目標檔案main,如果沒有找到就去尋找生成main檔案所依賴的檔案,如果沒有找到就跳過第二行的編譯命令定位到第三行,第三行的目標檔案也沒有,但所依賴的原始檔和標頭檔案在當前目錄下都被找到了,於是執行第四行的命令
  3. 定位到第5行,發現目標檔案module1.o沒有,但所依賴的檔案都被找到了,就執行第六行的編譯命令。依次向下執行,直到最後一行
  4. 定位到第一行,然後執行第二行的命令,生成目標檔案

  5. 在當前目錄下找名為Makefile或makefile的檔案

  6. 在當前目錄下尋找第一行中的目標檔案main,如果找到就去尋找生成main檔案所依賴的檔案,如果找到。然後比較main和依賴檔案的修改時間,如果main的修改時間晚。就定位到第三行,執行相同的操作,直至最後一行,否則就執行下面的命令
  7. 定位到第一行,比較看是否要執行第二行的命令

說明

  • 命令列之間可以插入任意多個空行,空行也要按Tab鍵開頭
  • 執行:make, make -f othername, make --file=othername
  • 通常把makefile檔案中第一行的目標檔案作為最終目標檔案
  • $表示使用變數或者呼叫函式,如果要是該字元需要書寫兩個連續的$$

檔案的構成

說明

  • 一個完整的makefile檔案由:顯式規則,隱含規則,使用變數,檔案指示,註釋,5部分構成
  • 顯式規則:顯式指定依賴檔案,命令
  • 隱含規則:需要自動推到處的規則
foo:foo.c | somelib
  gcc -o foo foo.c somelib
  • |前面的檔案是普通依賴檔案,|後面的檔案過時,foo不會被重新生成,也就是第二行的命令不會被執行
  • 可以在Tab鍵後面先寫上一個+,-,@然後再協商命令
    • - : 執行本行命令時如果遇到錯誤,繼續執行而不退出make
    • + : 本行命令始終被執行
    • @ : 執行本行命令時不在螢幕上列印命令內容
  • 一個檔案可以有多個目標
a.o b.o c.o: e.h
#相當於
a.o: a.c e.h
    gcc -c a.c -o a.o
b.o: b.c e.h
c.o: c.c e.h

偽目標

  • 偽目標不要求生成實際檔案而是執行一些輔助命令
  • 當一個目標被宣告為偽目標後,make在執行此規則時不會試圖去查詢該目標的依賴檔案
clean:
  -rm -f *.o
  • 以上用來刪除所有已.o結尾的檔案
  • 使用make clean
  • 由於clean沒有依賴檔案,所以始終認為它是最新的,而不去執行下面的命令,除非使用make clean或把它申請為偽目標.PHONY : clean

特殊目標

  • .PHONY 所有的依賴被作為偽目標
  • .IGNORE 後面的依賴檔案,生成這些檔案的命令在執行時如果出現錯誤,將被忽略繼續執行
  • .SUFFIXES 該目標的依賴檔案被認為是一個字尾列表
  • .SILENT 執行生成依賴檔案的命令時不會列印所執行的命令
  • .PRECLOUS 該目標的依賴檔案會受到特殊對待,如果make被終止,或者終止,這些依賴並不會被刪除,如果是中間檔案,不需要時也不會刪除
  • .INTERMEDIATE 目標依賴檔案在make執行時被當做中間檔案對待

搜尋目錄

  • 通過VPATH指定依賴檔案的搜尋目錄,如:VPATH = /usr/src:/headers
  • 定義VPATH時,使用空格或者冒號將多個搜尋目錄分開
  • 通過使用make的關鍵字vpath
    • vpath 為符合模式的檔案指定目錄
    • vpath 清除符合模式的檔案的搜尋目錄
    • vpath 清除設定的檔案搜尋目錄
  • vpath中的需要包含%,意思是匹配零個或若干個字元。例如%.h表示所有以.h結尾的檔案。指定了要搜尋的檔案集
  • 這僅僅是對於makefile來說搜尋目標和依賴檔案的路徑,但是對於命令列來說是無效的,也就是說在執行g++或者gcc時不會自動從VPATH或者vpath中自動搜尋要包含的標頭檔案等資訊檔案
vpath %.c path1
vpath %.c path2
vpath %.h path3
vpath %.c src1
vpath % src2
vpath %.c src3
表示以.c結尾的檔案現在src1中找,然後是src2,最後是src3

使用變數

  • 定義變數的形式:變數名 賦值符 變數值
  • 引用變數:$(變數名), 如果要用字元$要使用$$來表示
foo = $(bar)
bar = $(ugh)
ugh = Huh
all:
    echo $(foo)
  • 賦值符::=,賦值的變數是立即展開變數
CFLAGS := $(a)-o
a := later

CFLAGS的值是-o而不是later-o
  • 條件賦值符`?
  • FOO ?= bar 如果變數FOO在之前沒有定義,就給它賦值bar,否則不改變它的值
  • 可以使用=, +=

  • 預定義變數

巨集名 初始值 說明
CC cc 預設使用的編譯器
CFLAGS -o 編譯器使用的選項
MAKE make make命令
MAKEFLAGS make命令的選項
SHELL 預設使用的Shell型別
PWD 執行make命令時的當前目錄
AR ar 庫管理命令
ARFLADS -ruv 庫管理命令選項
LIBSUFFIXE .a 庫的字尾
A a 庫的副檔名

* 自動變數
1. [email protected] 一個規則中的目標檔名。如果目標是一個文件檔案(.a檔案為文件檔案/靜態庫檔案)
2. $%當規則的目標檔案是一個靜態庫檔案時,$%代表靜態庫的一個成員名
3. $<規則中的第一個依賴檔名,如果規則中使用了隱含規則,則是由隱含規則引入的第一個依賴檔名
4. $> 只適用於庫檔案,它的值是庫名
5. $?
6. $^規則的所有依賴檔案列表,使用空格分隔,如果目標是靜態庫檔案,所代表的只是所有庫成員,會去掉重複的依賴檔案
7. $* 目標檔案去掉字尾後的名稱
* 自動變數只能出現在命令中,要是想出現在檔案列表中,要在前加上一個$

file1.o file2.o: header.h
    cp [email protected] /backup
當目標檔案過時時,將原來的檔案備份到/backup目錄下,然後重新生成新的目標檔案

使用條件語句

  • ifeq表示條件語句的開始,並指定一個比較條件(相等), else之後是當條件不滿足時要執行的部分,endif表示一個條件語句結束
  • 還有關鍵字ifdef, ifndef, ifneq
libs_for_gcc = -lgnu
normal_libs = 
ifeq ($(CC),gcc)
libs = $(libs_for_gcc)
else
libs = $(normal_libs)
endif

使用庫

  • 大型軟體開發專案中,通常把編譯好的模組按照功能的不同放在不同的庫中
  • 庫中的檔案一般稱為庫的成員,表示為:庫名(成員名)
  • mylib.a(file.o) 表示靜態庫mylib.a中一個名為file.o的檔案,靜態庫也稱為文件檔案
  • 建立和維護一個庫時,將庫名作為目標檔案,把希望放到庫中的檔名作為依賴檔案。格式:庫名: 庫名(成員1) 庫名(成員2)...或者庫名: 庫名(成員1 成員2 ...)
  • 命令:ar -ruv 庫名 目標檔名

make引數

  • -C dir 線切換到dir目錄下,然後把dir當做當前目錄
  • -d 打印出所有的除錯資訊
  • -e 不允許在makefile中對系統環境變數進行重新賦值
  • -f filename --file=FILE --makefile=FILE使用指定檔案作為makefile檔案
  • -i 忽略執行過程中產生的錯誤
  • -h 打印出幫助資訊
  • -k 遇到錯誤時不終止執行,知道出現致命的錯誤才終止
  • -n 只打印出要執行的命令
  • -o filename指定檔案filename不需要重建,同時也不重建依賴才檔案的任何目標檔案
  • -q 不執行任何命令,只返回一個查詢狀態,0:沒有目標需要重建 1:存在需要重建的目標 2:錯誤發生
  • -r 忽略隱含規則
  • -R 取消make內嵌的預定義變數
  • -s執行但不西安市所執行的命令
  • -t 把所有目標檔案的最後修改時間設定為當前系統時間
  • -v打印出make的版本資訊

命令列

  • 可以通過-I制定檔案目錄
  • 如果使用$<,會直接引用make的檔案路徑
a.out: main.cpp comm.h
    g++ main.cpp
如果main.cpp不在當前目錄,會出現錯誤,改正如下:
a.out: main.cpp comm.h
    g++ -Ipath main.cpp
或者直接使用`$<`
a.out: main.cpp comm.h
    g++ $<

相關推薦

makefile學習記錄1】認識makemakefile

1、什麼是make?為什麼需要make? make本質是一個應用程式。 用來解析源程式之間的依賴關係        很多原始碼程式的檔案是非常多的,而且那些檔案之間大多是有依賴關係的,make就是可以解析這些依賴的

make的使用Makefile編寫

標籤: Linux C/C++開發 簡介 make使用 基本構成 流程 說明 檔案的構成 說明 偽目標 特殊目標 搜尋目錄 使用變數 使用庫 命令列 簡介 mak

make命令makefile

空格 這一 file mman 情況 相關 描述 end targe make命令和Makefiles: 1. make是一個命令,解釋makefile中指令的命令工具,不同的IDE有自己的make命令。 1. make命令不知道怎麽去構建程序,必須有一個文件告訴make命

簡介make命令makefile文件

tab linux 後綴 依賴關系 函數調用 創建方式 href oca printf 一、為什麽要用到 make 命令和 makefile 文件   在 Linux 下編寫一個程序,每次編譯都需要在命令行一行一行的敲命令。如果是一個很小的程序還好說,命令不怎的復雜,編譯速

簡介make命令makefile檔案

一、為什麼要用到 make 命令和 makefile 檔案   在 Linux 下編寫一個程式,每次編譯都需要在命令列一行一行的敲命令。如果是一個很小的程式還好說,命令不怎的複雜,編譯速度也挺快,但是對於大型程式來說,這樣無疑很麻煩,且不說可能會敲錯命令,有時候僅僅改動了一個小地方,卻需要將整個程式全部重新

如何將多個C檔案連結在一起----Makefile編寫make指令

需使用GCC編譯器,關於MinGW的安裝指南:https://people.eng.unimelb.edu.au/ammoffat/teaching/20005/Install-MinGW.pdf   單個.c檔案且沒有使用自定義標頭檔案的編譯,在命令列:   &nbs

linux動態庫及靜態庫的製作 makefile 的簡單編寫

一.庫什麼是庫,簡單的可以說是可執行程式碼的二進位制形式,能夠被作業系統載入記憶體執行。作業系統的不同,二者的庫也是不相容的,如windows與linux.庫又分為靜態庫和動態庫,動態庫又稱為共享庫。linux下靜態庫(.a)檔案,動態庫(.so)檔案。主要存放函式庫的路徑有

深入學習Make命令Makefile(上)

make是Linux下的一款程式自動維護工具,配合makefile的使用,就能夠根據程式中模組的修改情況,自動判斷應該對那些模組重新編譯,從而保證軟體是由最新的模組構成。本文分為上下兩部分,我們將緊緊圍繞make在軟體開發中的應用展開詳細的介紹。 一、都是原始檔太多惹得禍

【Linux】make的工作原理makefile檔案

1、make會在當前目錄下找名字叫“Makefile”或“makefile”的檔案。2、如果找到,它會找檔案中的第一個目標檔案(target),在上面的例子中,他會找到“edit”這個檔案,並把這個檔案作為最終的目標檔案。3、如果edit檔案不存在,或是edit所依賴的後面的 .o 檔案的檔案修改時間要比ed

深入學習Make命令Makefile(上)(1)

        make是Linux下的一款程式自動維護工具,配合makefile的使用,就能夠根據程式中模組的修改情況,自動判斷應該對那些模組重新編譯,從而保證軟體是由最新的模組構成。本文分為上下兩部分,我們將緊緊圍繞make在軟體開發中的應用展開詳細的介紹。

Linux 應用---makemakefile編寫

     Make 在我們做linux 開發中是必不可少的一部分,它在我們編寫大型專案工程檔案中起到非常大的作用。      Make工程管理器也就是個“自動編譯管理器”,這裡的“自動”是指它能夠根據檔案時間戳自動發現更新過的檔案而減少編譯的工作量,同時,它通過讀入Make

深入學習Make命令Makefile(上)(4)

 七、makefile中的巨集 在makefile中可以使用諸如XLIB、UIL等類似於Shell變數的識別符號,這些識別符號在makefile中稱為“巨集”,它可以代表一些檔名或選項。巨集的作用類似於C語言中的define,利用它們來代表某些多處使用而又可能發生變化的

GNU的make命令、makefile編寫

makefile簡介 makefile可實現工程的自動化編譯,只需一個make命令即可一鍵完成。makefile定義了一些規則,指定哪些檔案需要先編譯、後編譯、重新編譯等。 一般的C或者C++程式,都需要先編譯成中間檔案,windows下為.obj檔案,UNIX下為.o檔案,這個過程稱為編譯(com

利用Expressejs編寫簡單頁面

light logs 開發 ges 下載 highlight 視圖 script dem 1、創建臨時文件夾ejsdemo $ mkdir ejsdemo  2、進入ejsdemo 初始化項目 $ npm init 3、安裝express   $ npm

補基礎之shell makefile

靜默 兩種 1.4 如果能 內置 字符 為我 賦值運算 循環 2.2.1、shell介紹 (1)shell可以理解為軟件系統提供給用戶操作的命令行界面,可以說他是人機交互的一種方式 (2)我們可以使用shell和操作系統、uboot等軟件系統進行交互。具體來說就是我們通過

用CocosCreatorPomelo編寫多人在線實時聊天室(一)----基礎知識環境安裝

shu 以及 pan 信息 ast pre alt web 技術 客戶端:Cocos Creator 1.6.2服務器端:Pomelo 2.2.5源碼地址:https://github.com/foupwang/CocosCreatorChatForPomelo.git 本

Geant4采用makecmake編譯運行geant4自帶例子的方法

剛才 例子 1-1 build g++ 核數 emp cmake 編譯 該教程介紹如何將geant4中自帶的例子通過camke編譯成可執行文件,並運行程序。 1 在linux主目錄下創建一個geant4_workdir目錄,並將geant4自帶的例子B1復制到該目錄

性能測試通用分析思路報告編寫技巧

性能測試 測試結果分析 1. 通用分析思路觀察現象——>層層遞進——>縮小範圍——>推理分析——>不斷驗證——>確定結論 觀察現象:現象只要是指頁面的表現、服務器的資源表現、各類中間件的健康度、log日誌、各類軟件的參數、各類數據庫的健康度等。需要關註的公共指標:響應時間

Linux——makefile編寫

另一個 arch 運用 大量 技術 公司 的人 16px sdn 以前對makefile的編寫,限於剛開始接觸,我都比較局限一些死板的格式,有時候就會顯得有些繁瑣。在進一步了解一些系統編譯和鏈接的知識後,對makefile編寫流程有了一些新的認識,所以來此梳理梳理,方便更靈

利用mapreduce編寫一個str2float函數,把字符串'123.456'轉換成浮點數123.456:

AR 浮點數 n) 失敗 FN cto fun [1] str2 利用map和reduce編寫一個str2float函數,把字符串‘123.456‘轉換成浮點數123.456: # -*- coding: utf-8 -*- from functools import r