1. 程式人生 > >makefile自動生成依賴

makefile自動生成依賴

Makefile中,可能需要書寫一些規則來描述一個.o目標檔案和標頭檔案的依賴關係.

例如,如果在main.c中使用"#include defs.h",那麼我們可能需要如下那樣的一個規則來描述當頭檔案"defs.h"被修改以後執行make,目標"main.o"應該被重建.

main.o: defs.h 

這樣,在一個比較大型的工程中.就需要在Makefile中書寫很多條類似於這樣的規則.並且,當在原始檔中加入或刪除標頭檔案後,也需要小心地去修改Makefile.
這是一件很費力、也很費時並且容易出錯誤的工作.為了避免這個令人討厭的問題,現代的c編譯器提供了通過查詢原始檔中的"#include"來自動產生這種依賴的功能."GCC"支援一個"-M"的選項來實現此功能."GCC"將自動找尋原始檔中包含的標頭檔案,並生成一個依賴關係.
例如,如果"main.c"只包含了標頭檔案"defs.h",那麼在Linxu下執行下面的命令:
gcc -M main.c 
其輸出是:
main.o : main.c defs.h

既然編譯器已經提供了自動產生依賴關係的功能,那麼我們就不需要去動手寫這些規則的依賴關係了.
但是需要明確的是:在"main.c"中包含了其他的標準庫的標頭檔案,其輸出的依賴關係中也包含了標準庫的標頭檔案.
當不需要依賴關係中不考慮標準庫標頭檔案時,需要使用"-MM"引數.
需要注意的是,在使用"GCC"自動產生依賴關係時,所產生的規則中明確的指明瞭目標是"main.o"檔案.
通過.c檔案直接產生可執行檔案時,作為過程檔案的"main.o"的中間過程檔案在使用完之後將不會被刪除.
在舊版本的make中,使用編譯器此項功能通常的做法是:在Makefile中書寫一個偽目標"depend"的規則來定義自動產生依賴關係檔案的命令.
輸入"make depend"將生成一個稱為"depend"的檔案,其中包含了所有原始檔的依賴規則描述.Makefile使用"include"指示符包含這個檔案.
在新版本的make中,推薦的方式是為每一個原始檔產生一個描述其依賴關係的makefile檔案.對於一個原始檔"NAME.c",
對應的這個makefile檔案為"NAME.d"."NAME.d"中描述了檔案"NAME.o"所要依賴的所有標頭檔案.採用這種方式,
只有原始檔在修改之後才會重新使用命令生成新的依賴關係描述檔案"NAME.o".我們可以使用如下的模式規則來自動生成每一個.c檔案對應的.d檔案: 

%.d: %.c
     $(CC) -M $(CPPFLAGS) $< > [email protected]; /
     sed 's,/($*/)/.o[ :]*,/1.o [email protected] : ,g' < [email protected] > [email protected]; /
     rm -f [email protected]

此規則的含義是:所有的.d檔案依賴於同名的.c檔案.
第一行;使用c編譯器自自動生成依賴檔案($<)的標頭檔案依賴關係,並輸出成為一個臨時檔案.
如果$(CC)為GNU的C編譯工具,產生的依賴關係的規則中,依賴標頭檔案包括了所有的使用的系統標頭檔案和使用者定義的標頭檔案.
如果需要生成的依賴描述檔案不包含系統標頭檔案,可使用"-MM"代替"-M".
第二行;使用sed處理第二行已產生的那個臨時檔案並生成此規則的目標檔案.這裡sed完成了如下的轉換過程.
例如對已一個.c原始檔.將編譯器產生的依賴關係:
main.o : main.c defs.h
轉成:
main.o main.d : main.c defs.h

這樣就將.d加入到了規則的目標中,其和對應的.o檔案檔案一樣依賴於對應的.c原始檔和原始檔所包含的標頭檔案.
當.c原始檔或者標頭檔案被改變之後規則將會被執行,相應的.d檔案同樣會被更新.
使用上例的規則就可以建立一個描述目標檔案依賴關係的.d檔案.我們可以在Makefile中使用include指示符將描述將這個檔案包含進來.
在執行make時,Makefile所包含的所有.d檔案就會被自動建立或者更新.Makefile中對當前目錄下.d檔案處理可以參考如下: 
sources = foo.c bar.c
sinclude $(sources:.c=.d)

例子中,變數"sources"定義了當前目錄下的需要編譯的原始檔.
變數引用變換"$(sources:.c=.d)"的功能是根據需要.c檔案自動產生對應的.d檔案,並在當前Makefile檔案中包含這些.d檔案.
.d檔案和其它的makefile檔案一樣,make在執行時讀取並試圖重建他們.其實這些.d檔案也是一些可被make解析的makefile檔案.
需要注意的是include指示符的書寫順序,因為在這些.d檔案中已經存在規則.當一個Makefile使用指示符include這些.d檔案時,
應該注意它應該出現在終極目標之後,以免.d檔案中的規則被是Makefile的終極規則.關於這個前面我們已經有了比較詳細的討論.


一個簡單的makefile示例如下:
CC = gcc
SOURCES = $(wildcard *.c)
OBJS = $(patsubst %.c,%.o, $(SOURCES))
DEPS = $(patsubst %.c,%.d, $(SOURCES))
TARGET = main

$(TARGET):$(OBJS)
	$(CC) -o [email protected] $^

%.d: %.c
	$(CC) -MM $(CPPFLAGS) $< > [email protected]; \
	sed 's,/($*/)/.o[ :]*,/1.o [email protected] : ,g' < [email protected] > [email protected]; \
	rm -f [email protected]

sinclude $(DEPS)

clean:
	rm -f $(OBJS) $(DEPS) $(TARGET)


相關推薦

Makefile自動生成依賴檔案,並自動編譯

因為經常要用到makefile編譯,每次都為標頭檔案的依賴關係頭痛,所以這次費了兩天時間開發了一個通用的makefile,它可以自動生成依賴檔案,並編譯,當然你要按檔案裡面的說明來填充一些中間檔名. 程式碼如下: #自動依賴項(*.d),並編譯生成檔案 #編譯選項 LDF

makefile 自動生成依賴檔案

gcc  -c -o a.o a.c -Wp, -MD a.d a.d就是生成的依賴檔案 在a.d中 有 a.o:a.c a.h  (以及其他依賴的標頭檔案等) 在makefile中,包含依賴檔案,使用依賴檔案,使用如下: include a.d %.o : %.c$(CC

makefile自動生成依賴

Makefile中,可能需要書寫一些規則來描述一個.o目標檔案和標頭檔案的依賴關係.例如,如果在main.c中使用"#include defs.h",那麼我們可能需要如下那樣的一個規則來描述當頭檔案"defs.h"被修改以後執行make,目標"main.o"應該被重建.

makefile自動生成依賴關係

手工編寫依賴關係不僅工作量大而且極易出現遺漏,更新也很難及時,修改源或標頭檔案後makefile可能忘記修改。為了解決這個問題,可以用gcc的-M選項自動生成目標檔案和原始檔的依賴關係。-M選項會把包含的系統標頭檔案以及其所包含的其他系統標頭檔案也找出來了,如果我們不需要

makefile(05)_自動生成依賴關系

makefile 自動生成依賴 include 11.自動生成依賴關系_上 11.0. 實驗原料 本節實驗所需的源文件和頭文件:原文件:func.c #include "stdio.h" #include "func.h" void foo() { printf("void foo() :

makefile 自動生成標頭檔案依賴關係

在使用makefile 自動生成標頭檔案依賴是,大家多半使用了下面這個方法。 這個sed語句被稱之為 "上帝的符號",可讀性不言而喻。(PS:CSDN這個排版怎麼也搞不好,只能用圖片了。) gcc的 -MMD 選項可以自動生成帶有依賴規則的.d檔案,為建立標頭檔案依賴帶來

一份通用makefile,自動遍歷子目錄原始檔,自動生成依賴

這份makefile可以將當前makefile所在資料夾以及所有子資料夾中的cpp檔案打包成靜態庫/動態庫/可執行檔案. 自動生成所有依賴關係,修改任何檔案都可以觸發重新編譯相應依賴的檔案。 在U

makefile專題:自動生成依賴關係(續)

.PHONY : all clean rebuild MKDIR := mkdir RM := rm -rf CC := gcc DIR_DEPS := deps DIR_EXES := exes

自動生成依賴關系(十)

png CM 之前 out HA def 打印 card 期望 我們在之前的 makefile 學習中,其目標文件(.o)只依賴於源文件(.c)。那麽如果在源文件中還包含有頭文件,此時編譯器如何編譯源文件和頭文件呢?我們來看看編譯行為帶來的缺陷:1、預處理器

makefile自動生成依賴性

在Makefile中,我們的依賴關係可能會需要包含一系列的標頭檔案,比如,如果我們的main.c中有一句“#include "defs.h"”,那麼我們的依賴關係應該是: main.o : main.c defs.h 但是,如果是一個比較大型的工程,你必需清楚哪些C檔

Makefile自動生成工具-----autotools的使用(詳細)

  相信每個學習Linux的人都知道Makefile,這是一個很有用的東西,但是編寫它是比較複雜,今天介紹一個它的自動生成工具,autotools的使用。很多GNULinux的的軟體都是用它生成Makefile的,包括我們非常熟悉的Linux核心原始碼。   1、準備:

makefile自動產生依賴關係

我們在編譯原始碼的時候,有時候會發現當我們修改某個.h檔案,make之後並沒有發生任何變化,大家是不是很困惑,命名修改了.h檔案為什麼不編譯呢,其實我們的.h不是依賴檔案,什麼意思?納尼?不是依賴檔案。。。我想告訴大家的是,是的,確實是的。 那問題來了,怎麼把我們的make

Makefile自動生成

1、首先,新建一個測試專案的目錄——hello:mkdir hello 然後,cd hello;編輯一個hello.c的程式碼檔案: #include <stdio.h> int main() {      printf("hello automake!\n"); } 儲存退出; 2、執行auto

make--變量與函數的綜合示例 自動生成依賴關系

14. 自動生成 處理 con 替換 總結 連續 產生 rebuild 一.變量與函數的示例 示例的要求1.自動生成target文件夾存放可執行文件2.自動生成objs文件夾存放編譯生成的目標文件3.支持調試版本的編譯選項4.考慮代碼的擴展性完成該示例所需的1.$(wild

GCC+Make 自動生成 Makefile 依賴

目錄 BASIS wildcard .PHONY 靜態模式 常用自動變數 自動生成依賴(GCC) -M 引數 編寫 Makef

makefile自動依賴生成

自動依賴生成 基於make的構建環境要正確工作, 一個很重要(也很煩人)的任務是, 在makefile中正確列 舉依賴. 這個文件將介紹了一個非常有用的讓make自身來建立和維護這些依賴的方法. 文章來源 所有的make程式都需要知道, 某個特定的target依賴的檔案有哪些, 以便確認它(target) 會

AutoConf自動生成Makefile(基於helloworld簡單例子)

programs tom change col -a 二進制 自己 int 生成 新建一個簡單的helloworld工程文件夾,目錄結構如下 hello.h代碼: #include<stdio.h> void fprint() { printf("h

自動生成Makefile的全過程詳解

change make auto osc .cn 轉換成 otto 創建 準備 一、簡介 Linux下的程序開發人員,一定都遇到過Makefile,用make命令來編譯自己寫的程序確實是很方便。一般情況下,大家都是手工寫一個簡單Makefile,如果要想寫出一個符合自由軟件

【轉載】如何自動生成和安裝requirements.txt依賴

生成 構建 文件 自動 file title clas 人的 安裝 如何自動生成和安裝requirements.txt依賴 在查看別人的Python項目時,經常會看到一個requirements.txt文件,裏面記錄了當前程序的所有依賴包及其精確版本號。這個文件有點類似

一個簡單的執行程序的GNU automake自動生成Makefile的方法及案例

rect -o 創建 otool 其中 ner markdown ted head 一個簡單的執行程序的GNU automake自動生成Makefile的方法及案例 在GNU的世界裏,存在Automake這樣的工具進行自動生成Makefile文件,automake是由Per