編寫一個通用的Makefile文件

来源:http://www.cnblogs.com/Lwd-linux/archive/2016/12/24/6217336.html
-Advertisement-
Play Games

1.1在這之前,我們需要瞭解程式的編譯過程 a.預處理:檢查語法錯誤,展開巨集,包含頭文件等 b.編譯:*.c-->*.S c.彙編:*.S-->*.o d.鏈接:.o +庫文件=*.exe 1.2體驗在VC下程式的編譯 a.先編譯,在鏈接 b.修改了哪個文件,就單獨編譯此文件,在鏈接 c.修改了哪個 ...


1.1在這之前,我們需要瞭解程式的編譯過程

a.預處理:檢查語法錯誤,展開巨集,包含頭文件等

b.編譯:*.c-->*.S

c.彙編:*.S-->*.o

d.鏈接:.o +庫文件=*.exe

1.2體驗在VC下程式的編譯

a.先編譯,在鏈接

b.修改了哪個文件,就單獨編譯此文件,在鏈接

c.修改了哪個頭文件,就單獨編譯使用該頭文件的源文件,在鏈接

1.3在linux下實現上述要求

2.編寫一個測試的Makefile

2.1直接編譯鏈接

 1 gcc -o test a.c b.c 

缺點:改變其中一個文件,還需要重新編譯所有文件,最後鏈接,效率低

2.2編寫一個通用的Makefile

核心:規則

 

目標:依賴1 依賴2...

  命令

 

命令的執行條件:

a.依賴文件比目標文件新

b.沒有目標文件

2.2.1一個簡單的Makefile文件

test:a.c b.c a.h
    gcc -o test a.c b.c

缺點:當其中一個文件發生改變時,另一個文件又將從新編譯鏈接

2.2.2針對上述,改為如下

test:a.o b.o
    gcc -o test a.o b.o

a.o : a.c 
    gcc -c -o a.o a.c    

b.o : b.c
    gcc -c -o b.o b.c    

缺點:a.如果test依賴於多個文件,將寫許多代碼。

b.修改a.h程式沒有反應。

2.2.3

針對上述a,可將其改為通配符;針對b,可增加“a.o:a.c a.h”這段代碼。

$@:表示目標;$^:表示全部依賴;$<:第一個依賴。

test:a.o b.o
    gcc -o test a.o b.o

a.o:a.c a.h

%.o : %.c 
    gcc -c -o $@ $<

缺點:如果一個文件的頭文件非常多,不可能一個一個列出來,應該生成一個依賴文件。

2.2.4生成依賴文件

wildcard:檢查文件是否存在

-Wp,-MD:生成依賴文件

objs := a.o b.o

test:$(objs)
    gcc -o test $^

# .a.o.d .b.o.d
dep_files := $(foreach f,$(objs),.$(f).d)//對於objs里的每個文件,生成對應的依賴文件。eg:a.o-->.a.o.d
dep_files := $(wildcard $(dep_files))

ifneq ($(dep_files),)
  include $(dep_files)
endif

%.o : %.c 
    gcc -Wp,-MD,[email protected] -c -o $@ $<

clean:
    rm *.o test

3.參照內核的Makefile和上述的test_Makefile,編寫一個通用的Makefile

3.1子目錄下的Makefile
   它最簡單,形式如下:
obj-y += file.o
obj-y += subdir/
   
   "obj-y += file.o"表示把當前目錄下的file.c編進程式里,
   "obj-y += subdir/"表示要進入subdir這個子目錄下去尋找文件來編進程式里,是哪些文件由subdir目錄下的Makefile決定。

註意: "subdir/"中的斜杠"/"不可省略

3.2頂層目錄的Makefile:
   它除了定義obj-y來指定根目錄下要編進程式去的文件、子目錄外,主要是定義工具鏈、編譯參數、鏈接參數──就是文件中用export導出的各變數。

CROSS_COMPILE = arm-linux-      //交叉編譯工具鏈
AS        = $(CROSS_COMPILE)as
LD        = $(CROSS_COMPILE)ld
CC        = $(CROSS_COMPILE)gcc
CPP        = $(CC) -E
AR        = $(CROSS_COMPILE)ar
NM        = $(CROSS_COMPILE)nm

STRIP        = $(CROSS_COMPILE)strip
OBJCOPY        = $(CROSS_COMPILE)objcopy
OBJDUMP        = $(CROSS_COMPILE)objdump

export AS LD CC CPP AR NM     //導出變數
export STRIP OBJCOPY OBJDUMP

CFLAGS := -Wall -O2 -g        //編譯選項
CFLAGS += -I $(shell pwd)/include

LDFLAGS := -lm -lfreetype     //鏈接選項

export CFLAGS LDFLAGS

TOPDIR := $(shell pwd)
export TOPDIR

TARGET := show_file


obj-y += main.o
obj-y += display/
obj-y += draw/
obj-y += encoding/
obj-y += fonts/


all : 
    make -C ./ -f $(TOPDIR)/Makefile.build       //打開文件,按照頂層目錄下的Makefile.build來編譯
    $(CC) $(LDFLAGS) -o $(TARGET) built-in.o     //link


clean:
    rm -f $(shell find -name "*.o")
    rm -f $(TARGET)

distclean:
    rm -f $(shell find -name "*.o")
    rm -f $(shell find -name "*.d")
    rm -f $(TARGET)
    

3.3頂層目錄的Makefile.build:
   這是最複雜的部分,它的功能就是把某個目錄及它的所有子目錄中、需要編進程式去的文件都編譯出來,打包為built-in.o。

PHONY := __build
__build:


obj-y :=
subdir-y :=

include Makefile
__subdir-y    := $(patsubst %/,%,$(filter %/, $(obj-y)))
subdir-y    += $(__subdir-y)
subdir_objs := $(foreach f,$(subdir-y),$(f)/built-in.o)

cur_objs := $(filter-out %/, $(obj-y))
dep_files := $(foreach f,$(cur_objs),.$(f).d)
dep_files := $(wildcard $(dep_files))

ifneq ($(dep_files),)
  include $(dep_files)
endif


PHONY += $(subdir-y)


__build : $(subdir-y) built-in.o

$(subdir-y):
    make -C $@ -f $(TOPDIR)/Makefile.build

built-in.o : $(cur_objs) $(subdir_objs)
    $(LD) -r -o $@ $^

dep_file = [email protected]

%.o : %.c
    $(CC) $(CFLAGS) -Wp,-MD,$(dep_file) -c -o $@ $<
    
.PHONY : $(PHONY)

通用Makefile


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 備註:oracle版本Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 說明:創建臨時表空間註意關鍵字和創建表空間有所差別,語句類似 關於創建語句解說請查看:http://blog.chinaunix.net/uid-20802110 ...
  • 1.地址 2.Units單位 1 配置大小單位,開頭定義了一些基本的度量單位,只支持bytes,不支持bit 2 對大小寫不敏感 3.includes包含 ...
  • 存儲過程語法、概念、介紹;如何處理並記錄複雜存儲過程中發生的錯誤 ...
  • 本文出處:http://www.cnblogs.com/wy123/p/6217772.html 字元串自身相加, 雖然賦值給了varchar(max)類型的變了,在某些特殊情況下仍然會被“截斷”,這到底是varchar(max)長度的問題還是操作的問題? 1,兩個不超過8000長度的字元串自身相加 ...
  • 隔離級別定義事務操作資源和更新數據的隔離程度,在SQL Server中,隔離級別隻會影響讀操作申請的共用鎖,而不會影響寫操作申請的互斥鎖。隔離級別控制事務在執行讀操作時: 在讀數據時是否使用共用鎖,申請何種類型的隔離級別; 事務持有讀鎖的時間 讀操作引用其他事務更新的數據行時,控制讀操作的行為: 被 ...
  • Linux環境下寫代碼雖然沒有IDE,但通過給vim配置幾個插件也足夠好用。一般常用的插件主要包括幾類,查找文件,查找符號的定義或者聲明(函數,變數等)以及自動補全功能。一般流程都是下載需要的工具,然後在vimrc文件中配置載入工具選項,一直這麼用也沒覺得啥。但最近發現通過vundle工具可以很方便 ...
  • TCP/IP之Nagle演算法與40ms延遲提到了Nagle 演算法。這樣雖然提高了網路吞吐量,但是實時性卻降低了,在一些交互性很強的應用程式來說是不允許的,使用TCP_NODELAY選項可以禁止Nagle 演算法。禁止Nagle後應用程式向內核遞交的每個數據包都會立即發送出去。但是禁止Nagle,網路傳 ...
  • Nagle演算法是針對網路上存在的微小分組可能會在廣域網上造成擁塞而設計的。該演算法要求一個TCP連接上最多只能有一個未被確認的未完成的小分組,在該分組確認到達之前不能發送其他的小分組。同時,TCP收集這些少量的分組,併在確認到來時以一個分組發出去。它的設計規則如下: (1)如果包長度達到最大報文長度( ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...